PR15095: Use more correct source locations for the InitListExpr we fake up for
authorRichard Smith <richard-llvm@metafoo.co.uk>
Tue, 5 Feb 2013 05:55:57 +0000 (05:55 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Tue, 5 Feb 2013 05:55:57 +0000 (05:55 +0000)
vector initialization. Patch by John Stratton!

llvm-svn: 174339

clang/include/clang/ASTMatchers/ASTMatchers.h
clang/lib/Sema/SemaExpr.cpp
clang/unittests/AST/MatchVerifier.h
clang/unittests/AST/SourceLocationTest.cpp

index 933ef6b..61a0ab2 100644 (file)
@@ -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,
index 5b8b8fd..0d046f1 100644 (file)
@@ -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);
 }
index 4706899..f0a5853 100644 (file)
@@ -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
index 486c82f..b8d8b02 100644 (file)
@@ -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