forked from OSchip/llvm-project
Add cxxStdInitializerListExpr AST matcher
Summary: This adds a new ASTMatcher for CXXStdInitializerListExprs that matches C++ initializer list expressions. The primary motivation is to use it to fix [[ https://bugs.llvm.org/show_bug.cgi?id=32896 | PR32896 ]] (review here [[ https://reviews.llvm.org/D32767 | D32767 ]]). Reviewers: alexfh, Prazek, aaron.ballman Reviewed By: alexfh, aaron.ballman Subscribers: malcolm.parsons, cfe-commits, klimek Differential Revision: https://reviews.llvm.org/D32810 llvm-svn: 302287
This commit is contained in:
parent
430a335b7b
commit
64b6c78e94
|
@ -924,6 +924,19 @@ in
|
||||||
</pre></td></tr>
|
</pre></td></tr>
|
||||||
|
|
||||||
|
|
||||||
|
<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('cxxStdInitializerListExpr0')"><a name="cxxStdInitializerListExpr0Anchor">cxxStdInitializerListExpr</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXStdInitializerListExpr.html">CXXStdInitializerListExpr</a>>...</td></tr>
|
||||||
|
<tr><td colspan="4" class="doc" id="cxxStdInitializerListExpr0"><pre>Matches C++ initializer list expressions.
|
||||||
|
|
||||||
|
Given
|
||||||
|
std::vector<int> a({ 1, 2, 3 });
|
||||||
|
std::vector<int> b = { 4, 5 };
|
||||||
|
int c[] = { 6, 7 };
|
||||||
|
std::pair<int, int> d = { 8, 9 };
|
||||||
|
cxxStdInitializerListExpr()
|
||||||
|
matches "{ 1, 2, 3 }" and "{ 4, 5 }"
|
||||||
|
</pre></td></tr>
|
||||||
|
|
||||||
|
|
||||||
<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('cxxTemporaryObjectExpr0')"><a name="cxxTemporaryObjectExpr0Anchor">cxxTemporaryObjectExpr</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXTemporaryObjectExpr.html">CXXTemporaryObjectExpr</a>>...</td></tr>
|
<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('cxxTemporaryObjectExpr0')"><a name="cxxTemporaryObjectExpr0Anchor">cxxTemporaryObjectExpr</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXTemporaryObjectExpr.html">CXXTemporaryObjectExpr</a>>...</td></tr>
|
||||||
<tr><td colspan="4" class="doc" id="cxxTemporaryObjectExpr0"><pre>Matches functional cast expressions having N != 1 arguments
|
<tr><td colspan="4" class="doc" id="cxxTemporaryObjectExpr0"><pre>Matches functional cast expressions having N != 1 arguments
|
||||||
|
|
||||||
|
@ -1160,7 +1173,7 @@ Example matches [&](){return 5;}
|
||||||
<tr><td colspan="4" class="doc" id="materializeTemporaryExpr0"><pre>Matches nodes where temporaries are materialized.
|
<tr><td colspan="4" class="doc" id="materializeTemporaryExpr0"><pre>Matches nodes where temporaries are materialized.
|
||||||
|
|
||||||
Example: Given
|
Example: Given
|
||||||
struct T {void func()};
|
struct T {void func();};
|
||||||
T f();
|
T f();
|
||||||
void g(T);
|
void g(T);
|
||||||
materializeTemporaryExpr() matches 'f()' in these statements
|
materializeTemporaryExpr() matches 'f()' in these statements
|
||||||
|
@ -5233,7 +5246,7 @@ Example matches y in x(y)
|
||||||
<tr><td colspan="4" class="doc" id="hasReceiverType0"><pre>Matches on the receiver of an ObjectiveC Message expression.
|
<tr><td colspan="4" class="doc" id="hasReceiverType0"><pre>Matches on the receiver of an ObjectiveC Message expression.
|
||||||
|
|
||||||
Example
|
Example
|
||||||
matcher = objCMessageExpr(hasRecieverType(asString("UIWebView *")));
|
matcher = objCMessageExpr(hasReceiverType(asString("UIWebView *")));
|
||||||
matches the [webView ...] message invocation.
|
matches the [webView ...] message invocation.
|
||||||
NSString *webViewJavaScript = ...
|
NSString *webViewJavaScript = ...
|
||||||
UIWebView *webView = ...
|
UIWebView *webView = ...
|
||||||
|
|
|
@ -1223,6 +1223,20 @@ AST_MATCHER_P(InitListExpr, hasSyntacticForm,
|
||||||
InnerMatcher.matches(*SyntForm, Finder, Builder));
|
InnerMatcher.matches(*SyntForm, Finder, Builder));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// \brief Matches C++ initializer list expressions.
|
||||||
|
///
|
||||||
|
/// Given
|
||||||
|
/// \code
|
||||||
|
/// std::vector<int> a({ 1, 2, 3 });
|
||||||
|
/// std::vector<int> b = { 4, 5 };
|
||||||
|
/// int c[] = { 6, 7 };
|
||||||
|
/// std::pair<int, int> d = { 8, 9 };
|
||||||
|
/// \endcode
|
||||||
|
/// cxxStdInitializerListExpr()
|
||||||
|
/// matches "{ 1, 2, 3 }" and "{ 4, 5 }"
|
||||||
|
const internal::VariadicDynCastAllOfMatcher<Stmt,
|
||||||
|
CXXStdInitializerListExpr> cxxStdInitializerListExpr;
|
||||||
|
|
||||||
/// \brief Matches implicit initializers of init list expressions.
|
/// \brief Matches implicit initializers of init list expressions.
|
||||||
///
|
///
|
||||||
/// Given
|
/// Given
|
||||||
|
|
|
@ -153,6 +153,7 @@ RegistryMaps::RegistryMaps() {
|
||||||
REGISTER_MATCHER(cxxRecordDecl);
|
REGISTER_MATCHER(cxxRecordDecl);
|
||||||
REGISTER_MATCHER(cxxReinterpretCastExpr);
|
REGISTER_MATCHER(cxxReinterpretCastExpr);
|
||||||
REGISTER_MATCHER(cxxStaticCastExpr);
|
REGISTER_MATCHER(cxxStaticCastExpr);
|
||||||
|
REGISTER_MATCHER(cxxStdInitializerListExpr);
|
||||||
REGISTER_MATCHER(cxxTemporaryObjectExpr);
|
REGISTER_MATCHER(cxxTemporaryObjectExpr);
|
||||||
REGISTER_MATCHER(cxxThisExpr);
|
REGISTER_MATCHER(cxxThisExpr);
|
||||||
REGISTER_MATCHER(cxxThrowExpr);
|
REGISTER_MATCHER(cxxThrowExpr);
|
||||||
|
|
|
@ -1020,6 +1020,29 @@ TEST(InitListExpression, MatchesInitListExpression) {
|
||||||
matches("int i[1] = {42, [0] = 43};", integerLiteral(equals(42))));
|
matches("int i[1] = {42, [0] = 43};", integerLiteral(equals(42))));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(CXXStdInitializerListExpression, MatchesCXXStdInitializerListExpression) {
|
||||||
|
const std::string code = "namespace std {"
|
||||||
|
"template <typename> class initializer_list {"
|
||||||
|
" public: initializer_list() noexcept {}"
|
||||||
|
"};"
|
||||||
|
"}"
|
||||||
|
"struct A {"
|
||||||
|
" A(std::initializer_list<int>) {}"
|
||||||
|
"};";
|
||||||
|
EXPECT_TRUE(matches(code + "A a{0};",
|
||||||
|
cxxConstructExpr(has(cxxStdInitializerListExpr()),
|
||||||
|
hasDeclaration(cxxConstructorDecl(
|
||||||
|
ofClass(hasName("A")))))));
|
||||||
|
EXPECT_TRUE(matches(code + "A a = {0};",
|
||||||
|
cxxConstructExpr(has(cxxStdInitializerListExpr()),
|
||||||
|
hasDeclaration(cxxConstructorDecl(
|
||||||
|
ofClass(hasName("A")))))));
|
||||||
|
|
||||||
|
EXPECT_TRUE(notMatches("int a[] = { 1, 2 };", cxxStdInitializerListExpr()));
|
||||||
|
EXPECT_TRUE(notMatches("struct B { int x, y; }; B b = { 5, 6 };",
|
||||||
|
cxxStdInitializerListExpr()));
|
||||||
|
}
|
||||||
|
|
||||||
TEST(UsingDeclaration, MatchesUsingDeclarations) {
|
TEST(UsingDeclaration, MatchesUsingDeclarations) {
|
||||||
EXPECT_TRUE(matches("namespace X { int x; } using X::x;",
|
EXPECT_TRUE(matches("namespace X { int x; } using X::x;",
|
||||||
usingDecl()));
|
usingDecl()));
|
||||||
|
|
Loading…
Reference in New Issue