diff options
author | Douglas Gregor <dgregor@apple.com> | 2010-09-07 21:49:58 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2010-09-07 21:49:58 +0000 |
commit | 1bb2a93ab7b1499dda6f6b58865bd0dce1864228 (patch) | |
tree | 839f3064983d5d820ecc01c0f0bfa5b4809522b6 | |
parent | 02b49bb23273f3488a47f8abadf0ec7a98429d1f (diff) |
Improve source-location information for CXXNewExpr, by hanging on to
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
-rw-r--r-- | include/clang/AST/ExprCXX.h | 8 | ||||
-rw-r--r-- | include/clang/AST/RecursiveASTVisitor.h | 3 | ||||
-rw-r--r-- | include/clang/Sema/Sema.h | 3 | ||||
-rw-r--r-- | lib/AST/ExprCXX.cpp | 4 | ||||
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 21 | ||||
-rw-r--r-- | lib/Sema/TreeTransform.h | 41 | ||||
-rw-r--r-- | lib/Serialization/ASTReaderStmt.cpp | 1 | ||||
-rw-r--r-- | lib/Serialization/ASTWriterStmt.cpp | 1 | ||||
-rw-r--r-- | test/Index/load-stmts.cpp | 15 | ||||
-rw-r--r-- | tools/libclang/CIndex.cpp | 25 |
10 files changed, 86 insertions, 36 deletions
diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h index 0a9435479d..b3012bf5d8 100644 --- a/include/clang/AST/ExprCXX.h +++ b/include/clang/AST/ExprCXX.h @@ -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; } diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h index 232e47b03a..0a2adba58f 100644 --- a/include/clang/AST/RecursiveASTVisitor.h +++ b/include/clang/AST/RecursiveASTVisitor.h @@ -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, { diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index 4741028cb0..99228dc701 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -2195,8 +2195,7 @@ public: SourceLocation PlacementRParen, SourceRange TypeIdParens, QualType AllocType, - SourceLocation TypeLoc, - SourceRange TypeRange, + TypeSourceInfo *AllocTypeInfo, Expr *ArraySize, SourceLocation ConstructorLParen, MultiExprArg ConstructorArgs, diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp index 0a101300d8..11b223646b 100644 --- a/lib/AST/ExprCXX.cpp +++ b/lib/AST/ExprCXX.cpp @@ -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; diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 5720d931b6..8e376c29f3 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -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())); } diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index e7bfbe6fe9..0300143743 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -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), diff --git a/lib/Serialization/ASTReaderStmt.cpp b/lib/Serialization/ASTReaderStmt.cpp index ee5d40a369..d3efc71c83 100644 --- a/lib/Serialization/ASTReaderStmt.cpp +++ b/lib/Serialization/ASTReaderStmt.cpp @@ -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++])); diff --git a/lib/Serialization/ASTWriterStmt.cpp b/lib/Serialization/ASTWriterStmt.cpp index 7f2da6c225..b98b7e90a6 100644 --- a/lib/Serialization/ASTWriterStmt.cpp +++ b/lib/Serialization/ASTWriterStmt.cpp @@ -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); diff --git a/test/Index/load-stmts.cpp b/test/Index/load-stmts.cpp index 503219f71e..c78f689989 100644 --- a/test/Index/load-stmts.cpp +++ b/test/Index/load-stmts.cpp @@ -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] diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp index 5117f2c164..c056e48542 100644 --- a/tools/libclang/CIndex.cpp +++ b/tools/libclang/CIndex.cpp @@ -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))) |