From: Chris Lattner Date: Thu, 30 Aug 2007 17:59:59 +0000 (+0000) Subject: implement pretty printing of offsetof X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=704fe35d13c6c7c17ee8472da2321211fc5197c9;p=clang implement pretty printing of offsetof git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@41615 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/AST/StmtPrinter.cpp b/AST/StmtPrinter.cpp index 875af79020..a771b4ce1a 100644 --- a/AST/StmtPrinter.cpp +++ b/AST/StmtPrinter.cpp @@ -64,6 +64,9 @@ namespace { return OS; } + bool PrintOffsetOfDesignator(Expr *E); + void VisitUnaryOffsetOf(UnaryOperator *Node); + void VisitStmt(Stmt *Node); #define STMT(N, CLASS, PARENT) \ void Visit##CLASS(CLASS *Node); @@ -429,8 +432,33 @@ void StmtPrinter::VisitUnaryOperator(UnaryOperator *Node) { if (Node->isPostfix()) OS << UnaryOperator::getOpcodeStr(Node->getOpcode()); +} + +bool StmtPrinter::PrintOffsetOfDesignator(Expr *E) { + if (isa(E)) { + // Base case, print the type and comma. + OS << E->getType().getAsString() << ", "; + return true; + } else if (ArraySubscriptExpr *ASE = dyn_cast(E)) { + PrintOffsetOfDesignator(ASE->getLHS()); + OS << "["; + PrintExpr(ASE->getRHS()); + OS << "]"; + return false; + } else { + MemberExpr *ME = cast(E); + bool IsFirst = PrintOffsetOfDesignator(ME->getBase()); + OS << (IsFirst ? "" : ".") << ME->getMemberDecl()->getName(); + return false; + } +} +void StmtPrinter::VisitUnaryOffsetOf(UnaryOperator *Node) { + OS << "__builtin_offsetof("; + PrintOffsetOfDesignator(Node->getSubExpr()); + OS << ")"; } + void StmtPrinter::VisitSizeOfAlignOfTypeExpr(SizeOfAlignOfTypeExpr *Node) { OS << (Node->isSizeOf() ? "sizeof(" : "__alignof("); OS << Node->getArgumentType().getAsString() << ")"; diff --git a/Sema/SemaExpr.cpp b/Sema/SemaExpr.cpp index 2d048bd475..615b243334 100644 --- a/Sema/SemaExpr.cpp +++ b/Sema/SemaExpr.cpp @@ -1748,6 +1748,8 @@ Sema::ExprResult Sema::ParseBuiltinOffsetOf(SourceLocation BuiltinLoc, Res->getType().getAsString()); } + // FIXME: C++: Verify that operator[] isn't overloaded. + // C99 6.5.2.1p1 Expr *Idx = static_cast(OC.U.E); if (!Idx->getType()->isIntegerType()) @@ -1772,6 +1774,10 @@ Sema::ExprResult Sema::ParseBuiltinOffsetOf(SourceLocation BuiltinLoc, return Diag(BuiltinLoc, diag::err_typecheck_no_member, OC.U.IdentInfo->getName(), SourceRange(OC.LocStart, OC.LocEnd)); + + // FIXME: C++: Verify that MemberDecl isn't a static field. + // FIXME: Verify that MemberDecl isn't a bitfield. + Res = new MemberExpr(Res, false, MemberDecl, OC.LocEnd); } diff --git a/include/clang/AST/StmtVisitor.h b/include/clang/AST/StmtVisitor.h index c8ebbf2651..575ff17736 100644 --- a/include/clang/AST/StmtVisitor.h +++ b/include/clang/AST/StmtVisitor.h @@ -95,7 +95,7 @@ public: case UnaryOperator::Real: DISPATCH(UnaryReal, UnaryOperator); case UnaryOperator::Imag: DISPATCH(UnaryImag, UnaryOperator); case UnaryOperator::Extension: DISPATCH(UnaryExtension, UnaryOperator); - case UnaryOperator::OffsetOf: DISPATCH(UnaryExtension, UnaryOperator); + case UnaryOperator::OffsetOf: DISPATCH(UnaryOffsetOf, UnaryOperator); } }