diff options
-rw-r--r-- | clang/include/clang/ASTMatchers/ASTMatchers.h | 10 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 11 | ||||
-rw-r--r-- | clang/unittests/AST/MatchVerifier.h | 4 | ||||
-rw-r--r-- | clang/unittests/AST/SourceLocationTest.cpp | 33 |
4 files changed, 54 insertions, 4 deletions
diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h index 933ef6b27ea..61a0ab25593 100644 --- a/clang/include/clang/ASTMatchers/ASTMatchers.h +++ b/clang/include/clang/ASTMatchers/ASTMatchers.h @@ -922,6 +922,16 @@ const internal::VariadicDynCastAllOfMatcher< Stmt, UserDefinedLiteral> userDefinedLiteral; +/// \brief Matches compound (i.e. non-scalar) literals +/// +/// Example match: {1}, (1, 2) +/// \code +/// int array[4] = {1}; vector int myvec = (vector int)(1, 2); +/// \endcode +const internal::VariadicDynCastAllOfMatcher< + Stmt, + CompoundLiteralExpr> compoundLiteralExpr; + /// \brief Matches nullptr literal. const internal::VariadicDynCastAllOfMatcher< Stmt, diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 5b8b8fdcbf7..0d046f15aa3 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -4627,10 +4627,15 @@ ExprResult Sema::BuildVectorLiteral(SourceLocation LParenLoc, Expr **exprs; unsigned numExprs; Expr *subExpr; + SourceLocation LiteralLParenLoc, LiteralRParenLoc; if (ParenListExpr *PE = dyn_cast<ParenListExpr>(E)) { + LiteralLParenLoc = PE->getLParenLoc(); + LiteralRParenLoc = PE->getRParenLoc(); exprs = PE->getExprs(); numExprs = PE->getNumExprs(); - } else { + } else { // isa<ParenExpr> by assertion at function entrance + LiteralLParenLoc = cast<ParenExpr>(E)->getLParen(); + LiteralRParenLoc = cast<ParenExpr>(E)->getRParen(); subExpr = cast<ParenExpr>(E)->getSubExpr(); exprs = &subExpr; numExprs = 1; @@ -4687,8 +4692,8 @@ ExprResult Sema::BuildVectorLiteral(SourceLocation LParenLoc, } // FIXME: This means that pretty-printing the final AST will produce curly // braces instead of the original commas. - InitListExpr *initE = new (Context) InitListExpr(Context, LParenLoc, - initExprs, RParenLoc); + InitListExpr *initE = new (Context) InitListExpr(Context, LiteralLParenLoc, + initExprs, LiteralRParenLoc); initE->setType(Ty); return BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc, initE); } diff --git a/clang/unittests/AST/MatchVerifier.h b/clang/unittests/AST/MatchVerifier.h index 470689987c4..f0a58537048 100644 --- a/clang/unittests/AST/MatchVerifier.h +++ b/clang/unittests/AST/MatchVerifier.h @@ -25,7 +25,7 @@ namespace clang { namespace ast_matchers { -enum Language { Lang_C, Lang_C89, Lang_CXX }; +enum Language { Lang_C, Lang_C89, Lang_CXX, Lang_OpenCL }; /// \brief Base class for verifying some property of nodes found by a matcher. template <typename NodeType> @@ -85,6 +85,8 @@ testing::AssertionResult MatchVerifier<NodeType>::match( Args.push_back("-std=c++98"); FileName = "input.cc"; break; + case Lang_OpenCL: + FileName = "input.cl"; } // Default to failure in case callback is never called diff --git a/clang/unittests/AST/SourceLocationTest.cpp b/clang/unittests/AST/SourceLocationTest.cpp index 486c82fceca..b8d8b02d031 100644 --- a/clang/unittests/AST/SourceLocationTest.cpp +++ b/clang/unittests/AST/SourceLocationTest.cpp @@ -122,5 +122,38 @@ TEST(CXXConstructorDecl, NoRetFunTypeLocRange) { EXPECT_TRUE(Verifier.match("class C { C(); };", functionDecl())); } +TEST(CompoundLiteralExpr, CompoundVectorLiteralRange) { + RangeVerifier<CompoundLiteralExpr> Verifier; + Verifier.expectRange(2, 11, 2, 22); + EXPECT_TRUE(Verifier.match( + "typedef int int2 __attribute__((ext_vector_type(2)));\n" + "int2 i2 = (int2){1, 2};", compoundLiteralExpr())); +} + +TEST(CompoundLiteralExpr, ParensCompoundVectorLiteralRange) { + RangeVerifier<CompoundLiteralExpr> Verifier; + Verifier.expectRange(2, 11, 2, 22); + EXPECT_TRUE(Verifier.match( + "typedef int int2 __attribute__((ext_vector_type(2)));\n" + "int2 i2 = (int2)(1, 2);", + compoundLiteralExpr(), Lang_OpenCL)); +} + +TEST(InitListExpr, VectorLiteralListBraceRange) { + RangeVerifier<InitListExpr> Verifier; + Verifier.expectRange(2, 17, 2, 22); + EXPECT_TRUE(Verifier.match( + "typedef int int2 __attribute__((ext_vector_type(2)));\n" + "int2 i2 = (int2){1, 2};", initListExpr())); +} + +TEST(InitListExpr, VectorLiteralInitListParens) { + RangeVerifier<InitListExpr> Verifier; + Verifier.expectRange(2, 17, 2, 22); + EXPECT_TRUE(Verifier.match( + "typedef int int2 __attribute__((ext_vector_type(2)));\n" + "int2 i2 = (int2)(1, 2);", initListExpr(), Lang_OpenCL)); +} + } // end namespace ast_matchers } // end namespace clang |