]> granicus.if.org Git - clang/commitdiff
Improve source-location information for CXXNewExpr, by hanging on to
authorDouglas Gregor <dgregor@apple.com>
Tue, 7 Sep 2010 21:49:58 +0000 (21:49 +0000)
committerDouglas Gregor <dgregor@apple.com>
Tue, 7 Sep 2010 21:49:58 +0000 (21:49 +0000)
the TypeSourceInfo for the allocated type. Fixes PR7501.

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

include/clang/AST/ExprCXX.h
include/clang/AST/RecursiveASTVisitor.h
include/clang/Sema/Sema.h
lib/AST/ExprCXX.cpp
lib/Sema/SemaExprCXX.cpp
lib/Sema/TreeTransform.h
lib/Serialization/ASTReaderStmt.cpp
lib/Serialization/ASTWriterStmt.cpp
test/Index/load-stmts.cpp
tools/libclang/CIndex.cpp

index 0a9435479d935642eb61c2dcc215beabd9b552b2..b3012bf5d8f043679500e89a938c0fa9c504292c 100644 (file)
@@ -900,6 +900,9 @@ class CXXNewExpr : public Expr {
   // Must be null for all other types.
   CXXConstructorDecl *Constructor;
 
+  /// \brief The allocated type-source information, as written in the source.
+  TypeSourceInfo *AllocatedTypeInfo;
+  
   /// \brief If the allocated type was expressed as a parenthesized type-id, 
   /// the source range covering the parenthesized type-id.
   SourceRange TypeIdParens;
@@ -915,6 +918,7 @@ public:
              Expr *arraySize, CXXConstructorDecl *constructor, bool initializer,
              Expr **constructorArgs, unsigned numConsArgs,
              FunctionDecl *operatorDelete, QualType ty,
+             TypeSourceInfo *AllocatedTypeInfo,
              SourceLocation startLoc, SourceLocation endLoc);
   explicit CXXNewExpr(EmptyShell Shell)
     : Expr(CXXNewExprClass, Shell), SubExprs(0) { }
@@ -927,6 +931,10 @@ public:
     return getType()->getAs<PointerType>()->getPointeeType();
   }
 
+  TypeSourceInfo *getAllocatedTypeSourceInfo() const {
+    return AllocatedTypeInfo;
+  }
+  
   FunctionDecl *getOperatorNew() const { return OperatorNew; }
   void setOperatorNew(FunctionDecl *D) { OperatorNew = D; }
   FunctionDecl *getOperatorDelete() const { return OperatorDelete; }
index 232e47b03ae511720609b0943e9dc7a52103dcf2..0a2adba58f0e951c42da8f4d812e4973e7cd9e78 100644 (file)
@@ -1744,7 +1744,8 @@ DEF_TRAVERSE_STMT(CXXScalarValueInitExpr, {
   })
 
 DEF_TRAVERSE_STMT(CXXNewExpr, {
-    TRY_TO(TraverseType(S->getAllocatedType()));
+  // The child-iterator will pick up the other arguments.
+  TRY_TO(TraverseTypeLoc(S->getAllocatedTypeSourceInfo()->getTypeLoc()));
   })
 
 DEF_TRAVERSE_STMT(OffsetOfExpr, {
index 4741028cb0c974193ceec879e54f8b1d4676ed4a..99228dc701955a5d805d13ecb16536df334452af 100644 (file)
@@ -2195,8 +2195,7 @@ public:
                          SourceLocation PlacementRParen,
                          SourceRange TypeIdParens,
                          QualType AllocType,
-                         SourceLocation TypeLoc,
-                         SourceRange TypeRange,
+                         TypeSourceInfo *AllocTypeInfo,
                          Expr *ArraySize,
                          SourceLocation ConstructorLParen,
                          MultiExprArg ConstructorArgs,
index 0a101300d8fa1ac11a8fdb112da6854f71851e36..11b223646b43a5d59535b3c6b01fc51c30579fa4 100644 (file)
@@ -89,12 +89,14 @@ CXXNewExpr::CXXNewExpr(ASTContext &C, bool globalNew, FunctionDecl *operatorNew,
                        CXXConstructorDecl *constructor, bool initializer,
                        Expr **constructorArgs, unsigned numConsArgs,
                        FunctionDecl *operatorDelete, QualType ty,
+                       TypeSourceInfo *AllocatedTypeInfo,
                        SourceLocation startLoc, SourceLocation endLoc)
   : Expr(CXXNewExprClass, ty, ty->isDependentType(), ty->isDependentType()),
     GlobalNew(globalNew),
     Initializer(initializer), SubExprs(0), OperatorNew(operatorNew),
     OperatorDelete(operatorDelete), Constructor(constructor),
-    TypeIdParens(TypeIdParens), StartLoc(startLoc), EndLoc(endLoc) {
+    AllocatedTypeInfo(AllocatedTypeInfo), TypeIdParens(TypeIdParens),
+    StartLoc(startLoc), EndLoc(endLoc) {
       
   AllocateArgsArray(C, arraySize != 0, numPlaceArgs, numConsArgs);
   unsigned i = 0;
index 5720d931b66bd6df3c99def363333ee75d0b9051..8e376c29f3fc5189adbeffecacaa3e27cb509095 100644 (file)
@@ -630,12 +630,14 @@ Sema::ActOnCXXNew(SourceLocation StartLoc, bool UseGlobal,
     }
   }
 
-  //FIXME: Store TypeSourceInfo in CXXNew expression.
   TypeSourceInfo *TInfo = GetTypeForDeclarator(D, /*Scope=*/0);
   QualType AllocType = TInfo->getType();
   if (D.isInvalidType())
     return ExprError();
   
+  if (!TInfo)
+    TInfo = Context.getTrivialTypeSourceInfo(AllocType);
+    
   SourceRange R = TInfo->getTypeLoc().getSourceRange();    
   return BuildCXXNew(StartLoc, UseGlobal,
                      PlacementLParen,
@@ -643,8 +645,7 @@ Sema::ActOnCXXNew(SourceLocation StartLoc, bool UseGlobal,
                      PlacementRParen,
                      TypeIdParens,
                      AllocType,
-                     D.getSourceRange().getBegin(),
-                     R,
+                     TInfo,
                      ArraySize,
                      ConstructorLParen,
                      move(ConstructorArgs),
@@ -658,13 +659,13 @@ Sema::BuildCXXNew(SourceLocation StartLoc, bool UseGlobal,
                   SourceLocation PlacementRParen,
                   SourceRange TypeIdParens,
                   QualType AllocType,
-                  SourceLocation TypeLoc,
-                  SourceRange TypeRange,
+                  TypeSourceInfo *AllocTypeInfo,
                   Expr *ArraySize,
                   SourceLocation ConstructorLParen,
                   MultiExprArg ConstructorArgs,
                   SourceLocation ConstructorRParen) {
-  if (CheckAllocatedType(AllocType, TypeLoc, TypeRange))
+  SourceRange TypeRange = AllocTypeInfo->getTypeLoc().getSourceRange();
+  if (CheckAllocatedType(AllocType, TypeRange.getBegin(), TypeRange))
     return ExprError();
 
   // Per C++0x [expr.new]p5, the type being constructed may be a
@@ -800,10 +801,10 @@ Sema::BuildCXXNew(SourceLocation StartLoc, bool UseGlobal,
     //     - If the new-initializer is omitted, the object is default-
     //       initialized (8.5); if no initialization is performed,
     //       the object has indeterminate value
-      = !Init? InitializationKind::CreateDefault(TypeLoc)
+      = !Init? InitializationKind::CreateDefault(TypeRange.getBegin())
     //     - Otherwise, the new-initializer is interpreted according to the 
     //       initialization rules of 8.5 for direct-initialization.
-             : InitializationKind::CreateDirect(TypeLoc,
+             : InitializationKind::CreateDirect(TypeRange.getBegin(),
                                                 ConstructorLParen, 
                                                 ConstructorRParen);
     
@@ -852,12 +853,12 @@ Sema::BuildCXXNew(SourceLocation StartLoc, bool UseGlobal,
   PlacementArgs.release();
   ConstructorArgs.release();
   
-  // FIXME: The TypeSourceInfo should also be included in CXXNewExpr.
   return Owned(new (Context) CXXNewExpr(Context, UseGlobal, OperatorNew,
                                         PlaceArgs, NumPlaceArgs, TypeIdParens,
                                         ArraySize, Constructor, Init,
                                         ConsArgs, NumConsArgs, OperatorDelete,
-                                        ResultType, StartLoc,
+                                        ResultType, AllocTypeInfo,
+                                        StartLoc,
                                         Init ? ConstructorRParen :
                                                TypeRange.getEnd()));
 }
index e7bfbe6fe95524f6ba6f2b2b3c188df9d6c47f69..0300143743f6965d42f808a737851710278fdbd7 100644 (file)
@@ -1580,26 +1580,24 @@ public:
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
   ExprResult RebuildCXXNewExpr(SourceLocation StartLoc,
-                                     bool UseGlobal,
-                                     SourceLocation PlacementLParen,
-                                     MultiExprArg PlacementArgs,
-                                     SourceLocation PlacementRParen,
-                                     SourceRange TypeIdParens,
-                                     QualType AllocType,
-                                     SourceLocation TypeLoc,
-                                     SourceRange TypeRange,
-                                     Expr *ArraySize,
-                                     SourceLocation ConstructorLParen,
-                                     MultiExprArg ConstructorArgs,
-                                     SourceLocation ConstructorRParen) {
+                               bool UseGlobal,
+                               SourceLocation PlacementLParen,
+                               MultiExprArg PlacementArgs,
+                               SourceLocation PlacementRParen,
+                               SourceRange TypeIdParens,
+                               QualType AllocatedType,
+                               TypeSourceInfo *AllocatedTypeInfo,
+                               Expr *ArraySize,
+                               SourceLocation ConstructorLParen,
+                               MultiExprArg ConstructorArgs,
+                               SourceLocation ConstructorRParen) {
     return getSema().BuildCXXNew(StartLoc, UseGlobal,
                                  PlacementLParen,
                                  move(PlacementArgs),
                                  PlacementRParen,
                                  TypeIdParens,
-                                 AllocType,
-                                 TypeLoc,
-                                 TypeRange,
+                                 AllocatedType,
+                                 AllocatedTypeInfo,
                                  ArraySize,
                                  ConstructorLParen,
                                  move(ConstructorArgs),
@@ -5245,9 +5243,9 @@ template<typename Derived>
 ExprResult
 TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) {
   // Transform the type that we're allocating
-  TemporaryBase Rebase(*this, E->getLocStart(), DeclarationName());
-  QualType AllocType = getDerived().TransformType(E->getAllocatedType());
-  if (AllocType.isNull())
+  TypeSourceInfo *AllocTypeInfo
+    = getDerived().TransformType(E->getAllocatedTypeSourceInfo());
+  if (!AllocTypeInfo)
     return ExprError();
 
   // Transform the size of the array we're allocating (if any).
@@ -5310,7 +5308,7 @@ TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) {
   }
   
   if (!getDerived().AlwaysRebuild() &&
-      AllocType == E->getAllocatedType() &&
+      AllocTypeInfo == E->getAllocatedTypeSourceInfo() &&
       ArraySize.get() == E->getArraySize() &&
       Constructor == E->getConstructor() &&
       OperatorNew == E->getOperatorNew() &&
@@ -5327,6 +5325,7 @@ TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) {
     return SemaRef.Owned(E->Retain());
   }
 
+  QualType AllocType = AllocTypeInfo->getType();
   if (!ArraySize.get()) {
     // If no array size was specified, but the new expression was
     // instantiated with an array type (e.g., "new T" where T is
@@ -5352,6 +5351,7 @@ TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) {
       }
     }
   }
+  
   return getDerived().RebuildCXXNewExpr(E->getLocStart(),
                                         E->isGlobalNew(),
                                         /*FIXME:*/E->getLocStart(),
@@ -5359,8 +5359,7 @@ TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) {
                                         /*FIXME:*/E->getLocStart(),
                                         E->getTypeIdParens(),
                                         AllocType,
-                                        /*FIXME:*/E->getLocStart(),
-                                        /*FIXME:*/SourceRange(),
+                                        AllocTypeInfo,
                                         ArraySize.get(),
                                         /*FIXME:*/E->getLocStart(),
                                         move_arg(ConstructorArgs),
index ee5d40a3698e43d288fb290b10d54146c2a18a3f..d3efc71c83b801cf97dd85a6c7fb4fa01abb609d 100644 (file)
@@ -1074,6 +1074,7 @@ void ASTStmtReader::VisitCXXNewExpr(CXXNewExpr *E) {
                     cast_or_null<FunctionDecl>(Reader.GetDecl(Record[Idx++])));
   E->setConstructor(
                cast_or_null<CXXConstructorDecl>(Reader.GetDecl(Record[Idx++])));
+  E->AllocatedTypeInfo = Reader.GetTypeSourceInfo(DeclsCursor, Record, Idx);
   SourceRange TypeIdParens;
   TypeIdParens.setBegin(SourceLocation::getFromRawEncoding(Record[Idx++]));
   TypeIdParens.setEnd(SourceLocation::getFromRawEncoding(Record[Idx++]));
index 7f2da6c225a3134852c3a28d69d366786d373a9e..b98b7e90a6ac00cd0b691807a523e24a59f8a87c 100644 (file)
@@ -1091,6 +1091,7 @@ void ASTStmtWriter::VisitCXXNewExpr(CXXNewExpr *E) {
   Writer.AddDeclRef(E->getOperatorNew(), Record);
   Writer.AddDeclRef(E->getOperatorDelete(), Record);
   Writer.AddDeclRef(E->getConstructor(), Record);
+  Writer.AddTypeSourceInfo(E->getAllocatedTypeSourceInfo(), Record);
   Writer.AddSourceRange(E->getTypeIdParens(), Record);
   Writer.AddSourceLocation(E->getStartLoc(), Record);
   Writer.AddSourceLocation(E->getEndLoc(), Record);
index 503219f71e155ec9b049750bb974e5adfa6ef8d4..c78f689989513ff6abad63d66cc958cdcf8513c6 100644 (file)
@@ -70,6 +70,16 @@ void test_more_dependent_exprs(T t, Y y) {
   y.g<type>(t);
 }
 
+struct Pair {
+  Pair(int, int);
+};
+
+void *operator new(__SIZE_TYPE__, void*) throw();
+
+void test_more_exprs(void *mem, int i, int j) {
+  new (mem) Pair(i, j);
+}
+
 // RUN: c-index-test -test-load-source all %s | FileCheck %s
 // CHECK: load-stmts.cpp:1:13: TypedefDecl=T:1:13 (Definition) Extent=[1:13 - 1:14]
 // CHECK: load-stmts.cpp:2:8: StructDecl=X:2:8 (Definition) Extent=[2:1 - 2:23]
@@ -160,3 +170,8 @@ void test_more_dependent_exprs(T t, Y y) {
 // CHECK: load-stmts.cpp:70:3: DeclRefExpr=y:67:39 Extent=[70:3 - 70:4]
 // CHECK: load-stmts.cpp:70:7: TypeRef=type:69:13 Extent=[70:7 - 70:11]
 // CHECK: load-stmts.cpp:70:13: DeclRefExpr=t:67:34 Extent=[70:13 - 70:14]
+// CHECK: load-stmts.cpp:79:6: FunctionDecl=test_more_exprs:79:6 (Definition)
+// CHECK: load-stmts.cpp:80:8: DeclRefExpr=mem:79:28 Extent=[80:8 - 80:11]
+// CHECK: load-stmts.cpp:80:13: TypeRef=struct Pair:73:8 Extent=[80:13 - 80:17]
+// CHECK: load-stmts.cpp:80:18: DeclRefExpr=i:79:37 Extent=[80:18 - 80:19]
+// CHECK: load-stmts.cpp:80:21: DeclRefExpr=j:79:44 Extent=[80:21 - 80:22]
index 5117f2c16424087589020843c61bc2db79f9ade2..c056e485429dc6ac2e558b19484f0602705e277f 100644 (file)
@@ -388,7 +388,7 @@ public:
   bool VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) { return false; }
   // FIXME: CXXTemporaryObjectExpr has poor source-location information.
   // FIXME: CXXScalarValueInitExpr has poor source-location information.
-  // FIXME: CXXNewExpr has poor source-location information
+  bool VisitCXXNewExpr(CXXNewExpr *E);
   bool VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E);
   // FIXME: UnaryTypeTraitExpr has poor source-location information.
   bool VisitOverloadExpr(OverloadExpr *E);
@@ -1590,6 +1590,29 @@ bool CursorVisitor::VisitCXXTypeidExpr(CXXTypeidExpr *E) {
   return VisitExpr(E);
 }
 
+bool CursorVisitor::VisitCXXNewExpr(CXXNewExpr *E) {
+  // Visit placement arguments.
+  for (unsigned I = 0, N = E->getNumPlacementArgs(); I != N; ++I)
+    if (Visit(MakeCXCursor(E->getPlacementArg(I), StmtParent, TU)))
+      return true;
+  
+  // Visit the allocated type.
+  if (TypeSourceInfo *TSInfo = E->getAllocatedTypeSourceInfo())
+    if (Visit(TSInfo->getTypeLoc()))
+      return true;
+  
+  // Visit the array size, if any.
+  if (E->isArray() && Visit(MakeCXCursor(E->getArraySize(), StmtParent, TU)))
+    return true;
+  
+  // Visit the initializer or constructor arguments.
+  for (unsigned I = 0, N = E->getNumConstructorArgs(); I != N; ++I)
+    if (Visit(MakeCXCursor(E->getConstructorArg(I), StmtParent, TU)))
+      return true;
+  
+  return false;
+}
+
 bool CursorVisitor::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
   // Visit base expression.
   if (Visit(MakeCXCursor(E->getBase(), StmtParent, TU)))