]> granicus.if.org Git - clang/commitdiff
implement pretty printing of offsetof
authorChris Lattner <sabre@nondot.org>
Thu, 30 Aug 2007 17:59:59 +0000 (17:59 +0000)
committerChris Lattner <sabre@nondot.org>
Thu, 30 Aug 2007 17:59:59 +0000 (17:59 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@41615 91177308-0d34-0410-b5e6-96231b3b80d8

AST/StmtPrinter.cpp
Sema/SemaExpr.cpp
include/clang/AST/StmtVisitor.h

index 875af790201a071aecf490a3b2129fae763e0848..a771b4ce1a72120c0b7261bbe707e8708684ccc5 100644 (file)
@@ -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<CompoundLiteralExpr>(E)) {
+    // Base case, print the type and comma.
+    OS << E->getType().getAsString() << ", ";
+    return true;
+  } else if (ArraySubscriptExpr *ASE = dyn_cast<ArraySubscriptExpr>(E)) {
+    PrintOffsetOfDesignator(ASE->getLHS());
+    OS << "[";
+    PrintExpr(ASE->getRHS());
+    OS << "]";
+    return false;
+  } else {
+    MemberExpr *ME = cast<MemberExpr>(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() << ")";
index 2d048bd4759dc794def14d492813c0a5c172ece0..615b2433348fec538314b9a93fc6a8e68d15beb9 100644 (file)
@@ -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<Expr*>(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);
   }
   
index c8ebbf265142c7c8c8ca685c8b565ea7fad9ba95..575ff177369f53060e63fc08c06520cd0a882d98 100644 (file)
@@ -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);
       }          
     }