]> granicus.if.org Git - clang/commitdiff
Preserve type source information in sizeof/alignof expressions, and pass it
authorJohn McCall <rjmccall@apple.com>
Wed, 4 Nov 2009 07:28:41 +0000 (07:28 +0000)
committerJohn McCall <rjmccall@apple.com>
Wed, 4 Nov 2009 07:28:41 +0000 (07:28 +0000)
through to indexing.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@86018 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/Expr.h
lib/Frontend/PCHReaderStmt.cpp
lib/Frontend/PCHWriterStmt.cpp
lib/Frontend/RewriteObjC.cpp
lib/Index/ResolveLocation.cpp
lib/Sema/Sema.h
lib/Sema/SemaExpr.cpp
lib/Sema/TreeTransform.h

index 27d2ba72f2d3babc26992fcddc967b40363a7f43..2a87f5883588b33ec915214377b0cdb56c7d3068 100644 (file)
@@ -976,7 +976,7 @@ class SizeOfAlignOfExpr : public Expr {
   bool isSizeof : 1;  // true if sizeof, false if alignof.
   bool isType : 1;    // true if operand is a type, false if an expression
   union {
-    void *Ty;
+    DeclaratorInfo *Ty;
     Stmt *Ex;
   } Argument;
   SourceLocation OpLoc, RParenLoc;
@@ -985,15 +985,15 @@ protected:
   virtual void DoDestroy(ASTContext& C);
 
 public:
-  SizeOfAlignOfExpr(bool issizeof, QualType T,
+  SizeOfAlignOfExpr(bool issizeof, DeclaratorInfo *DInfo,
                     QualType resultType, SourceLocation op,
                     SourceLocation rp) :
       Expr(SizeOfAlignOfExprClass, resultType,
            false, // Never type-dependent (C++ [temp.dep.expr]p3).
            // Value-dependent if the argument is type-dependent.
-           T->isDependentType()),
+           DInfo->getType()->isDependentType()),
       isSizeof(issizeof), isType(true), OpLoc(op), RParenLoc(rp) {
-    Argument.Ty = T.getAsOpaquePtr();
+    Argument.Ty = DInfo;
   }
 
   SizeOfAlignOfExpr(bool issizeof, Expr *E,
@@ -1016,8 +1016,11 @@ public:
 
   bool isArgumentType() const { return isType; }
   QualType getArgumentType() const {
+    return getArgumentTypeInfo()->getType();
+  }
+  DeclaratorInfo *getArgumentTypeInfo() const {
     assert(isArgumentType() && "calling getArgumentType() when arg is expr");
-    return QualType::getFromOpaquePtr(Argument.Ty);
+    return Argument.Ty;
   }
   Expr *getArgumentExpr() {
     assert(!isArgumentType() && "calling getArgumentExpr() when arg is type");
@@ -1028,8 +1031,8 @@ public:
   }
 
   void setArgument(Expr *E) { Argument.Ex = E; isType = false; }
-  void setArgument(QualType T) {
-    Argument.Ty = T.getAsOpaquePtr();
+  void setArgument(DeclaratorInfo *DInfo) {
+    Argument.Ty = DInfo;
     isType = true;
   }
 
index 60f6d196009cbbd1799a201c564a7ae2393cc5f7..01af67dd50a16397ac65b6a7d1b5e0c36b38f006 100644 (file)
@@ -424,7 +424,7 @@ unsigned PCHStmtReader::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) {
     E->setArgument(cast<Expr>(StmtStack.back()));
     ++Idx;
   } else {
-    E->setArgument(Reader.GetType(Record[Idx++]));
+    E->setArgument(Reader.GetDeclaratorInfo(Record, Idx));
   }
   E->setOperatorLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
   E->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
index afed7fae58f9bf629815450e01b2b2fcbdac0522..78a56db7edcd3748946df619710ff5d7f0bf0ab7 100644 (file)
@@ -384,7 +384,7 @@ void PCHStmtWriter::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) {
   VisitExpr(E);
   Record.push_back(E->isSizeOf());
   if (E->isArgumentType())
-    Writer.AddTypeRef(E->getArgumentType(), Record);
+    Writer.AddDeclaratorInfo(E->getArgumentTypeInfo(), Record);
   else {
     Record.push_back(0);
     Writer.WriteSubStmt(E->getArgumentExpr());
index a00326267ed6b57d6f65e038487cdb0ea75797cc..24ad69e3e0d386e4897d63573971547487847d62 100644 (file)
@@ -2569,7 +2569,7 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp) {
 
     // Build sizeof(returnType)
     SizeOfAlignOfExpr *sizeofExpr = new (Context) SizeOfAlignOfExpr(true,
-                                      returnType,
+                            Context->getTrivialDeclaratorInfo(returnType),
                                       Context->getSizeType(),
                                       SourceLocation(), SourceLocation());
     // (sizeof(returnType) <= 8 ? objc_msgSend(...) : objc_msgSend_stret(...))
index ec8c1dcb3813484175eae80322f24d9d8ee014e2..73b584b5205d1662d70d095ce0d52939f2157851 100644 (file)
@@ -92,6 +92,7 @@ public:
   StmtLocResolver(ASTContext &ctx, SourceLocation loc, Decl *parent)
     : LocResolverBase(ctx, loc), Parent(parent) {}
 
+  ASTLocation VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *Node);
   ASTLocation VisitCXXOperatorCallExpr(CXXOperatorCallExpr *Node);
   ASTLocation VisitDeclStmt(DeclStmt *Node);
   ASTLocation VisitStmt(Stmt *Node);
@@ -135,6 +136,25 @@ public:
 
 } // anonymous namespace
 
+ASTLocation
+StmtLocResolver::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *Node) {
+  assert(ContainsLocation(Node) &&
+         "Should visit only after verifying that loc is in range");
+
+  if (Node->isArgumentType()) {
+    DeclaratorInfo *DInfo = Node->getArgumentTypeInfo();
+    if (ContainsLocation(DInfo))
+      return ResolveInDeclarator(Parent, Node, DInfo);
+  } else {
+    Expr *SubNode = Node->getArgumentExpr();
+    if (ContainsLocation(SubNode))
+      return Visit(SubNode);
+  }
+
+  return ASTLocation(Parent, Node);
+}
+
+
 ASTLocation
 StmtLocResolver::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *Node) {
   assert(ContainsLocation(Node) &&
index bb59e1c9f404eee974332b9b22f74607e07dfebf..0f84b46ed405694dfc4b1223a2e3ad83f66f2124 100644 (file)
@@ -1670,7 +1670,8 @@ public:
   virtual OwningExprResult ActOnUnaryOp(Scope *S, SourceLocation OpLoc,
                                         tok::TokenKind Op, ExprArg Input);
 
-  OwningExprResult CreateSizeOfAlignOfExpr(QualType T, SourceLocation OpLoc,
+  OwningExprResult CreateSizeOfAlignOfExpr(DeclaratorInfo *T,
+                                           SourceLocation OpLoc,
                                            bool isSizeOf, SourceRange R);
   OwningExprResult CreateSizeOfAlignOfExpr(Expr *E, SourceLocation OpLoc,
                                            bool isSizeOf, SourceRange R);
index 2c54a792c1aec89681e8ae6bd021dedb8a9fefc0..ac7cced2eaeff278c582fecd0b19c697521f274b 100644 (file)
@@ -1290,7 +1290,7 @@ bool Sema::CheckSizeOfAlignOfOperand(QualType exprType,
     return false;
 
   // C99 6.5.3.4p1:
-  if (isa<FunctionType>(exprType)) {
+  if (exprType->isFunctionType()) {
     // alignof(function) is allowed as an extension.
     if (isSizeof)
       Diag(OpLoc, diag::ext_sizeof_function_type) << ExprRange;
@@ -1348,17 +1348,20 @@ bool Sema::CheckAlignOfExpr(Expr *E, SourceLocation OpLoc,
 
 /// \brief Build a sizeof or alignof expression given a type operand.
 Action::OwningExprResult
-Sema::CreateSizeOfAlignOfExpr(QualType T, SourceLocation OpLoc,
+Sema::CreateSizeOfAlignOfExpr(DeclaratorInfo *DInfo,
+                              SourceLocation OpLoc,
                               bool isSizeOf, SourceRange R) {
-  if (T.isNull())
+  if (!DInfo)
     return ExprError();
 
+  QualType T = DInfo->getType();
+
   if (!T->isDependentType() &&
       CheckSizeOfAlignOfOperand(T, OpLoc, R, isSizeOf))
     return ExprError();
 
   // C99 6.5.3.4p4: the type (an unsigned integer type) is size_t.
-  return Owned(new (Context) SizeOfAlignOfExpr(isSizeOf, T,
+  return Owned(new (Context) SizeOfAlignOfExpr(isSizeOf, DInfo,
                                                Context.getSizeType(), OpLoc,
                                                R.getEnd()));
 }
@@ -1400,12 +1403,11 @@ Sema::ActOnSizeOfAlignOfExpr(SourceLocation OpLoc, bool isSizeof, bool isType,
   if (TyOrEx == 0) return ExprError();
 
   if (isType) {
-    // FIXME: Preserve type source info.
-    QualType ArgTy = GetTypeFromParser(TyOrEx);
-    return CreateSizeOfAlignOfExpr(ArgTy, OpLoc, isSizeof, ArgRange);
+    DeclaratorInfo *DInfo;
+    (void) GetTypeFromParser(TyOrEx, &DInfo);
+    return CreateSizeOfAlignOfExpr(DInfo, OpLoc, isSizeof, ArgRange);
   }
 
-  // Get the end location.
   Expr *ArgEx = (Expr *)TyOrEx;
   Action::OwningExprResult Result
     = CreateSizeOfAlignOfExpr(ArgEx, OpLoc, isSizeof, ArgEx->getSourceRange());
index 9a6b851d63a64db752b0d286d00649eed878ff86..5713da9fa5904148c476b9d87203580f5f4cebe2 100644 (file)
@@ -884,9 +884,10 @@ public:
   ///
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
-  OwningExprResult RebuildSizeOfAlignOf(QualType T, SourceLocation OpLoc,
+  OwningExprResult RebuildSizeOfAlignOf(DeclaratorInfo *DInfo,
+                                        SourceLocation OpLoc,
                                         bool isSizeOf, SourceRange R) {
-    return getSema().CreateSizeOfAlignOfExpr(T, OpLoc, isSizeOf, R);
+    return getSema().CreateSizeOfAlignOfExpr(DInfo, OpLoc, isSizeOf, R);
   }
 
   /// \brief Build a new sizeof or alignof expression with an expression
@@ -3532,16 +3533,16 @@ Sema::OwningExprResult
 TreeTransform<Derived>::TransformSizeOfAlignOfExpr(SizeOfAlignOfExpr *E,
                                                    bool isAddressOfOperand) {
   if (E->isArgumentType()) {
-    TemporaryBase Rebase(*this, E->getOperatorLoc(), DeclarationName());
+    DeclaratorInfo *OldT = E->getArgumentTypeInfo();
 
-    QualType T = getDerived().TransformType(E->getArgumentType());
-    if (T.isNull())
+    DeclaratorInfo *NewT = getDerived().TransformType(OldT);
+    if (!NewT)
       return SemaRef.ExprError();
 
-    if (!getDerived().AlwaysRebuild() && T == E->getArgumentType())
+    if (!getDerived().AlwaysRebuild() && OldT == NewT)
       return SemaRef.Owned(E->Retain());
 
-    return getDerived().RebuildSizeOfAlignOf(T, E->getOperatorLoc(),
+    return getDerived().RebuildSizeOfAlignOf(NewT, E->getOperatorLoc(),
                                              E->isSizeOf(),
                                              E->getSourceRange());
   }