diff options
-rw-r--r-- | clang/include/clang/AST/ExprCXX.h | 12 | ||||
-rw-r--r-- | clang/include/clang/ASTMatchers/ASTMatchers.h | 10 | ||||
-rw-r--r-- | clang/lib/AST/ExprCXX.cpp | 19 | ||||
-rw-r--r-- | clang/lib/Sema/SemaCast.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Sema/SemaInit.cpp | 22 | ||||
-rw-r--r-- | clang/lib/Sema/TreeTransform.h | 4 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTReaderStmt.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTWriterStmt.cpp | 2 | ||||
-rw-r--r-- | clang/unittests/AST/SourceLocationTest.cpp | 9 |
9 files changed, 55 insertions, 27 deletions
diff --git a/clang/include/clang/AST/ExprCXX.h b/clang/include/clang/AST/ExprCXX.h index 1dfa3b5244d..23c91742c70 100644 --- a/clang/include/clang/AST/ExprCXX.h +++ b/clang/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<Expr *> Args, - SourceRange parenRange, + SourceRange ParenOrBraceRange, bool HadMultipleCandidates, bool ListInitialization, bool ZeroInitialization); diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h index 0551355c58b..bff521a88d4 100644 --- a/clang/include/clang/ASTMatchers/ASTMatchers.h +++ b/clang/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> qualType; diff --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp index 36aa2892f2a..7f1a287d1fa 100644 --- a/clang/lib/AST/ExprCXX.cpp +++ b/clang/lib/AST/ExprCXX.cpp @@ -447,8 +447,8 @@ SourceLocation CXXConstructExpr::getLocEnd() const { if (isa<CXXTemporaryObjectExpr>(this)) return cast<CXXTemporaryObjectExpr>(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<Expr*> 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/clang/lib/Sema/SemaCast.cpp b/clang/lib/Sema/SemaCast.cpp index e3227bcaefe..032cd6efb75 100644 --- a/clang/lib/Sema/SemaCast.cpp +++ b/clang/lib/Sema/SemaCast.cpp @@ -2361,7 +2361,7 @@ ExprResult Sema::BuildCXXFunctionalCastExpr(TypeSourceInfo *CastTypeInfo, return ExprError(); if (CXXConstructExpr *ConstructExpr = dyn_cast<CXXConstructExpr>(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/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index 009e8c8098b..2eeb729dc8e 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/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<CXXConstructorDecl>(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/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 947fc241993..008e1eafe44 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -2760,7 +2760,7 @@ ExprResult TreeTransform<Derived>::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<Derived>::TransformCXXConstructExpr(CXXConstructExpr *E) { E->isListInitialization(), E->requiresZeroInitialization(), E->getConstructionKind(), - E->getParenRange()); + E->getParenOrBraceRange()); } /// \brief Transform a C++ temporary-binding expression. diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp index 62459d89742..35df2521145 100644 --- a/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/clang/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/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp index 6e87129e846..ee328e2351a 100644 --- a/clang/lib/Serialization/ASTWriterStmt.cpp +++ b/clang/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/clang/unittests/AST/SourceLocationTest.cpp b/clang/unittests/AST/SourceLocationTest.cpp index d45c6448c79..29156bc96ba 100644 --- a/clang/unittests/AST/SourceLocationTest.cpp +++ b/clang/unittests/AST/SourceLocationTest.cpp @@ -211,6 +211,15 @@ TEST(CXXFunctionalCastExpr, SourceRange) { functionalCastExpr(), Lang_CXX11)); } +TEST(CXXTemporaryObjectExpr, SourceRange) { + RangeVerifier<CXXTemporaryObjectExpr> 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<CXXUnresolvedConstructExpr> Verifier; Verifier.expectRange(3, 10, 3, 12); |