From 1245a54ca6e9c5b14196461dc3f84b24ea6594b1 Mon Sep 17 00:00:00 2001 From: Enea Zaffanella Date: Sat, 7 Sep 2013 05:49:53 +0000 Subject: [PATCH] Fix missing source location in CXXTemporaryObjectExpr nodes. For clarity, renamed (get/set)ParenRange as (get/set)ParenOrBraceRange in CXXConstructExpr nodes. Added testcase. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@190239 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/ExprCXX.h | 12 ++++++------ include/clang/ASTMatchers/ASTMatchers.h | 10 ++++++++++ lib/AST/ExprCXX.cpp | 19 ++++++++++--------- lib/Sema/SemaCast.cpp | 2 +- lib/Sema/SemaInit.cpp | 22 +++++++++++++++------- lib/Sema/TreeTransform.h | 4 ++-- lib/Serialization/ASTReaderStmt.cpp | 2 +- lib/Serialization/ASTWriterStmt.cpp | 2 +- unittests/AST/SourceLocationTest.cpp | 9 +++++++++ 9 files changed, 55 insertions(+), 27 deletions(-) diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h index 1dfa3b5244..23c91742c7 100644 --- a/include/clang/AST/ExprCXX.h +++ b/include/clang/AST/ExprCXX.h @@ -1070,7 +1070,7 @@ private: CXXConstructorDecl *Constructor; SourceLocation Loc; - SourceRange ParenRange; + SourceRange ParenOrBraceRange; unsigned NumArgs : 16; bool Elidable : 1; bool HadMultipleCandidates : 1; @@ -1088,7 +1088,7 @@ protected: bool ListInitialization, bool ZeroInitialization, ConstructionKind ConstructKind, - SourceRange ParenRange); + SourceRange ParenOrBraceRange); /// \brief Construct an empty C++ construction expression. CXXConstructExpr(StmtClass SC, EmptyShell Empty) @@ -1114,7 +1114,7 @@ public: bool ListInitialization, bool ZeroInitialization, ConstructionKind ConstructKind, - SourceRange ParenRange); + SourceRange ParenOrBraceRange); CXXConstructorDecl* getConstructor() const { return Constructor; } void setConstructor(CXXConstructorDecl *C) { Constructor = C; } @@ -1180,8 +1180,8 @@ public: SourceLocation getLocStart() const LLVM_READONLY; SourceLocation getLocEnd() const LLVM_READONLY; - SourceRange getParenRange() const { return ParenRange; } - void setParenRange(SourceRange Range) { ParenRange = Range; } + SourceRange getParenOrBraceRange() const { return ParenOrBraceRange; } + void setParenOrBraceRange(SourceRange Range) { ParenOrBraceRange = Range; } static bool classof(const Stmt *T) { return T->getStmtClass() == CXXConstructExprClass || @@ -1264,7 +1264,7 @@ public: CXXTemporaryObjectExpr(const ASTContext &C, CXXConstructorDecl *Cons, TypeSourceInfo *Type, ArrayRef Args, - SourceRange parenRange, + SourceRange ParenOrBraceRange, bool HadMultipleCandidates, bool ListInitialization, bool ZeroInitialization); diff --git a/include/clang/ASTMatchers/ASTMatchers.h b/include/clang/ASTMatchers/ASTMatchers.h index 0551355c58..bff521a88d 100644 --- a/include/clang/ASTMatchers/ASTMatchers.h +++ b/include/clang/ASTMatchers/ASTMatchers.h @@ -1269,6 +1269,16 @@ const internal::VariadicDynCastAllOfMatcher< Stmt, CXXFunctionalCastExpr> functionalCastExpr; +/// \brief Matches functional cast expressions having N != 1 arguments +/// +/// Example: Matches Foo(bar, bar) +/// \code +/// Foo h = Foo(bar, bar); +/// \endcode +const internal::VariadicDynCastAllOfMatcher< + Stmt, + CXXTemporaryObjectExpr> temporaryObjectExpr; + /// \brief Matches \c QualTypes in the clang AST. const internal::VariadicAllOfMatcher qualType; diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp index 36aa2892f2..7f1a287d1f 100644 --- a/lib/AST/ExprCXX.cpp +++ b/lib/AST/ExprCXX.cpp @@ -447,8 +447,8 @@ SourceLocation CXXConstructExpr::getLocEnd() const { if (isa(this)) return cast(this)->getLocEnd(); - if (ParenRange.isValid()) - return ParenRange.getEnd(); + if (ParenOrBraceRange.isValid()) + return ParenOrBraceRange.getEnd(); SourceLocation End = Loc; for (unsigned I = getNumArgs(); I > 0; --I) { @@ -761,7 +761,7 @@ CXXTemporaryObjectExpr::CXXTemporaryObjectExpr(const ASTContext &C, CXXConstructorDecl *Cons, TypeSourceInfo *Type, ArrayRef Args, - SourceRange parenRange, + SourceRange ParenOrBraceRange, bool HadMultipleCandidates, bool ListInitialization, bool ZeroInitialization) @@ -771,7 +771,7 @@ CXXTemporaryObjectExpr::CXXTemporaryObjectExpr(const ASTContext &C, Cons, false, Args, HadMultipleCandidates, ListInitialization, ZeroInitialization, - CXXConstructExpr::CK_Complete, parenRange), + CXXConstructExpr::CK_Complete, ParenOrBraceRange), Type(Type) { } @@ -780,7 +780,7 @@ SourceLocation CXXTemporaryObjectExpr::getLocStart() const { } SourceLocation CXXTemporaryObjectExpr::getLocEnd() const { - return getParenRange().getEnd(); + return getParenOrBraceRange().getEnd(); } CXXConstructExpr *CXXConstructExpr::Create(const ASTContext &C, QualType T, @@ -791,12 +791,12 @@ CXXConstructExpr *CXXConstructExpr::Create(const ASTContext &C, QualType T, bool ListInitialization, bool ZeroInitialization, ConstructionKind ConstructKind, - SourceRange ParenRange) { + SourceRange ParenOrBraceRange) { return new (C) CXXConstructExpr(C, CXXConstructExprClass, T, Loc, D, Elidable, Args, HadMultipleCandidates, ListInitialization, ZeroInitialization, ConstructKind, - ParenRange); + ParenOrBraceRange); } CXXConstructExpr::CXXConstructExpr(const ASTContext &C, StmtClass SC, @@ -807,12 +807,13 @@ CXXConstructExpr::CXXConstructExpr(const ASTContext &C, StmtClass SC, bool ListInitialization, bool ZeroInitialization, ConstructionKind ConstructKind, - SourceRange ParenRange) + SourceRange ParenOrBraceRange) : Expr(SC, T, VK_RValue, OK_Ordinary, T->isDependentType(), T->isDependentType(), T->isInstantiationDependentType(), T->containsUnexpandedParameterPack()), - Constructor(D), Loc(Loc), ParenRange(ParenRange), NumArgs(args.size()), + Constructor(D), Loc(Loc), ParenOrBraceRange(ParenOrBraceRange), + NumArgs(args.size()), Elidable(elidable), HadMultipleCandidates(HadMultipleCandidates), ListInitialization(ListInitialization), ZeroInitialization(ZeroInitialization), diff --git a/lib/Sema/SemaCast.cpp b/lib/Sema/SemaCast.cpp index e3227bcaef..032cd6efb7 100644 --- a/lib/Sema/SemaCast.cpp +++ b/lib/Sema/SemaCast.cpp @@ -2361,7 +2361,7 @@ ExprResult Sema::BuildCXXFunctionalCastExpr(TypeSourceInfo *CastTypeInfo, return ExprError(); if (CXXConstructExpr *ConstructExpr = dyn_cast(Op.SrcExpr.get())) - ConstructExpr->setParenRange(SourceRange(LPLoc, RPLoc)); + ConstructExpr->setParenOrBraceRange(SourceRange(LPLoc, RPLoc)); return Op.complete(CXXFunctionalCastExpr::Create(Context, Op.ResultType, Op.ValueKind, CastTypeInfo, Op.Kind, diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp index 009e8c8098..2eeb729dc8 100644 --- a/lib/Sema/SemaInit.cpp +++ b/lib/Sema/SemaInit.cpp @@ -5066,7 +5066,9 @@ PerformConstructorInitialization(Sema &S, MultiExprArg Args, const InitializationSequence::Step& Step, bool &ConstructorInitRequiresZeroInit, - bool IsListInitialization) { + bool IsListInitialization, + SourceLocation LBraceLoc, + SourceLocation RBraceLoc) { unsigned NumArgs = Args.size(); CXXConstructorDecl *Constructor = cast(Step.Function.Function); @@ -5118,14 +5120,16 @@ PerformConstructorInitialization(Sema &S, TypeSourceInfo *TSInfo = Entity.getTypeSourceInfo(); if (!TSInfo) TSInfo = S.Context.getTrivialTypeSourceInfo(Entity.getType(), Loc); - SourceRange ParenRange; - if (Kind.getKind() != InitializationKind::IK_DirectList) - ParenRange = Kind.getParenRange(); + SourceRange ParenOrBraceRange = + (Kind.getKind() == InitializationKind::IK_DirectList) + ? SourceRange(LBraceLoc, RBraceLoc) + : Kind.getParenRange(); CurInit = S.Owned( new (S.Context) CXXTemporaryObjectExpr(S.Context, Constructor, TSInfo, ConstructorArgs, - ParenRange, IsListInitialization, + ParenOrBraceRange, + IsListInitialization, HadMultipleCandidates, ConstructorInitRequiresZeroInit)); } else { @@ -5913,7 +5917,9 @@ InitializationSequence::Perform(Sema &S, Entity, Kind, Arg, *Step, ConstructorInitRequiresZeroInit, - /*IsListInitialization*/ true); + /*IsListInitialization*/ true, + InitList->getLBraceLoc(), + InitList->getRBraceLoc()); break; } @@ -5947,7 +5953,9 @@ InitializationSequence::Perform(Sema &S, : Entity, Kind, Args, *Step, ConstructorInitRequiresZeroInit, - /*IsListInitialization*/ false); + /*IsListInitialization*/ false, + /*LBraceLoc*/ SourceLocation(), + /*RBraceLoc*/ SourceLocation()); break; } diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index 947fc24199..008e1eafe4 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -2760,7 +2760,7 @@ ExprResult TreeTransform::TransformInitializer(Expr *Init, Construct->getType()); // Build a ParenListExpr to represent anything else. - SourceRange Parens = Construct->getParenRange(); + SourceRange Parens = Construct->getParenOrBraceRange(); return getDerived().RebuildParenListExpr(Parens.getBegin(), NewArgs, Parens.getEnd()); } @@ -8176,7 +8176,7 @@ TreeTransform::TransformCXXConstructExpr(CXXConstructExpr *E) { E->isListInitialization(), E->requiresZeroInitialization(), E->getConstructionKind(), - E->getParenRange()); + E->getParenOrBraceRange()); } /// \brief Transform a C++ temporary-binding expression. diff --git a/lib/Serialization/ASTReaderStmt.cpp b/lib/Serialization/ASTReaderStmt.cpp index 62459d8974..35df252114 100644 --- a/lib/Serialization/ASTReaderStmt.cpp +++ b/lib/Serialization/ASTReaderStmt.cpp @@ -1192,7 +1192,7 @@ void ASTStmtReader::VisitCXXConstructExpr(CXXConstructExpr *E) { E->setListInitialization(Record[Idx++]); E->setRequiresZeroInitialization(Record[Idx++]); E->setConstructionKind((CXXConstructExpr::ConstructionKind)Record[Idx++]); - E->ParenRange = ReadSourceRange(Record, Idx); + E->ParenOrBraceRange = ReadSourceRange(Record, Idx); } void ASTStmtReader::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E) { diff --git a/lib/Serialization/ASTWriterStmt.cpp b/lib/Serialization/ASTWriterStmt.cpp index 6e87129e84..ee328e2351 100644 --- a/lib/Serialization/ASTWriterStmt.cpp +++ b/lib/Serialization/ASTWriterStmt.cpp @@ -1148,7 +1148,7 @@ void ASTStmtWriter::VisitCXXConstructExpr(CXXConstructExpr *E) { Record.push_back(E->isListInitialization()); Record.push_back(E->requiresZeroInitialization()); Record.push_back(E->getConstructionKind()); // FIXME: stable encoding - Writer.AddSourceRange(E->getParenRange(), Record); + Writer.AddSourceRange(E->getParenOrBraceRange(), Record); Code = serialization::EXPR_CXX_CONSTRUCT; } diff --git a/unittests/AST/SourceLocationTest.cpp b/unittests/AST/SourceLocationTest.cpp index d45c6448c7..29156bc96b 100644 --- a/unittests/AST/SourceLocationTest.cpp +++ b/unittests/AST/SourceLocationTest.cpp @@ -211,6 +211,15 @@ TEST(CXXFunctionalCastExpr, SourceRange) { functionalCastExpr(), Lang_CXX11)); } +TEST(CXXTemporaryObjectExpr, SourceRange) { + RangeVerifier Verifier; + Verifier.expectRange(2, 6, 2, 12); + EXPECT_TRUE(Verifier.match( + "struct A { A(int, int); };\n" + "A a( A{0, 0} );", + temporaryObjectExpr(), Lang_CXX11)); +} + TEST(CXXUnresolvedConstructExpr, SourceRange) { RangeVerifier Verifier; Verifier.expectRange(3, 10, 3, 12); -- 2.40.0