PR15095: Use more correct source locations for the InitListExpr we fake up for

vector initialization. Patch by John Stratton!

llvm-svn: 174339
This commit is contained in:
Richard Smith 2013-02-05 05:55:57 +00:00
parent e2af9b5d2c
commit 9ca910111c
4 changed files with 54 additions and 4 deletions

View File

@ -922,6 +922,16 @@ const internal::VariadicDynCastAllOfMatcher<
Stmt, Stmt,
UserDefinedLiteral> userDefinedLiteral; 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. /// \brief Matches nullptr literal.
const internal::VariadicDynCastAllOfMatcher< const internal::VariadicDynCastAllOfMatcher<
Stmt, Stmt,

View File

@ -4627,10 +4627,15 @@ ExprResult Sema::BuildVectorLiteral(SourceLocation LParenLoc,
Expr **exprs; Expr **exprs;
unsigned numExprs; unsigned numExprs;
Expr *subExpr; Expr *subExpr;
SourceLocation LiteralLParenLoc, LiteralRParenLoc;
if (ParenListExpr *PE = dyn_cast<ParenListExpr>(E)) { if (ParenListExpr *PE = dyn_cast<ParenListExpr>(E)) {
LiteralLParenLoc = PE->getLParenLoc();
LiteralRParenLoc = PE->getRParenLoc();
exprs = PE->getExprs(); exprs = PE->getExprs();
numExprs = PE->getNumExprs(); 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(); subExpr = cast<ParenExpr>(E)->getSubExpr();
exprs = &subExpr; exprs = &subExpr;
numExprs = 1; numExprs = 1;
@ -4687,8 +4692,8 @@ ExprResult Sema::BuildVectorLiteral(SourceLocation LParenLoc,
} }
// FIXME: This means that pretty-printing the final AST will produce curly // FIXME: This means that pretty-printing the final AST will produce curly
// braces instead of the original commas. // braces instead of the original commas.
InitListExpr *initE = new (Context) InitListExpr(Context, LParenLoc, InitListExpr *initE = new (Context) InitListExpr(Context, LiteralLParenLoc,
initExprs, RParenLoc); initExprs, LiteralRParenLoc);
initE->setType(Ty); initE->setType(Ty);
return BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc, initE); return BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc, initE);
} }

View File

@ -25,7 +25,7 @@
namespace clang { namespace clang {
namespace ast_matchers { 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. /// \brief Base class for verifying some property of nodes found by a matcher.
template <typename NodeType> template <typename NodeType>
@ -85,6 +85,8 @@ testing::AssertionResult MatchVerifier<NodeType>::match(
Args.push_back("-std=c++98"); Args.push_back("-std=c++98");
FileName = "input.cc"; FileName = "input.cc";
break; break;
case Lang_OpenCL:
FileName = "input.cl";
} }
// Default to failure in case callback is never called // Default to failure in case callback is never called

View File

@ -122,5 +122,38 @@ TEST(CXXConstructorDecl, NoRetFunTypeLocRange) {
EXPECT_TRUE(Verifier.match("class C { C(); };", functionDecl())); 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 ast_matchers
} // end namespace clang } // end namespace clang