forked from OSchip/llvm-project
[ASTMatchers] Add clang-query support for equals matcher
Summary: This allows the clang-query tool to use matchers like "integerLiteral(equals(32))". For this to work, an overloaded function is added for each possible parameter type. Reviewed By: aaron.ballman Differential Revision: https://reviews.llvm.org/D33094 llvm-svn: 305022
This commit is contained in:
parent
2bbed50a45
commit
a9244b57ff
|
@ -1859,17 +1859,36 @@ Example matches a || b (matcher = binaryOperator(hasOperatorName("||")))
|
|||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><td>Matcher<CXXBoolLiteral></td><td class="name" onclick="toggle('equals2')"><a name="equals2Anchor">equals</a></td><td>ValueT Value</td></tr>
|
||||
<tr><td colspan="4" class="doc" id="equals2"><pre>Matches literals that are equal to the given value.
|
||||
<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXBoolLiteralExpr.html">CXXBoolLiteralExpr</a>></td><td class="name" onclick="toggle('equals2')"><a name="equals2Anchor">equals</a></td><td>ValueT Value</td></tr>
|
||||
<tr><td colspan="4" class="doc" id="equals2"><pre>Matches literals that are equal to the given value of type ValueT.
|
||||
|
||||
Example matches true (matcher = cxxBoolLiteral(equals(true)))
|
||||
true
|
||||
Given
|
||||
f('false, 3.14, 42);
|
||||
characterLiteral(equals(0))
|
||||
matches 'cxxBoolLiteral(equals(false)) and cxxBoolLiteral(equals(0))
|
||||
match false
|
||||
floatLiteral(equals(3.14)) and floatLiteral(equals(314e-2))
|
||||
match 3.14
|
||||
integerLiteral(equals(42))
|
||||
matches 42
|
||||
|
||||
Usable as: Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CharacterLiteral.html">CharacterLiteral</a>>, Matcher<CXXBoolLiteral>,
|
||||
Usable as: Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CharacterLiteral.html">CharacterLiteral</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXBoolLiteralExpr.html">CXXBoolLiteralExpr</a>>,
|
||||
Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1FloatingLiteral.html">FloatingLiteral</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1IntegerLiteral.html">IntegerLiteral</a>>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXBoolLiteralExpr.html">CXXBoolLiteralExpr</a>></td><td class="name" onclick="toggle('equals5')"><a name="equals5Anchor">equals</a></td><td>bool Value</td></tr>
|
||||
<tr><td colspan="4" class="doc" id="equals5"><pre></pre></td></tr>
|
||||
|
||||
|
||||
<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXBoolLiteralExpr.html">CXXBoolLiteralExpr</a>></td><td class="name" onclick="toggle('equals11')"><a name="equals11Anchor">equals</a></td><td>double Value</td></tr>
|
||||
<tr><td colspan="4" class="doc" id="equals11"><pre></pre></td></tr>
|
||||
|
||||
|
||||
<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXBoolLiteralExpr.html">CXXBoolLiteralExpr</a>></td><td class="name" onclick="toggle('equals8')"><a name="equals8Anchor">equals</a></td><td>unsigned Value</td></tr>
|
||||
<tr><td colspan="4" class="doc" id="equals8"><pre></pre></td></tr>
|
||||
|
||||
|
||||
<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXCatchStmt.html">CXXCatchStmt</a>></td><td class="name" onclick="toggle('isCatchAll0')"><a name="isCatchAll0Anchor">isCatchAll</a></td><td></td></tr>
|
||||
<tr><td colspan="4" class="doc" id="isCatchAll0"><pre>Matches a C++ catch statement that has a catch-all handler.
|
||||
|
||||
|
@ -2296,16 +2315,35 @@ Example: matches the implicit cast around 0
|
|||
|
||||
|
||||
<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CharacterLiteral.html">CharacterLiteral</a>></td><td class="name" onclick="toggle('equals3')"><a name="equals3Anchor">equals</a></td><td>ValueT Value</td></tr>
|
||||
<tr><td colspan="4" class="doc" id="equals3"><pre>Matches literals that are equal to the given value.
|
||||
<tr><td colspan="4" class="doc" id="equals3"><pre>Matches literals that are equal to the given value of type ValueT.
|
||||
|
||||
Example matches true (matcher = cxxBoolLiteral(equals(true)))
|
||||
true
|
||||
Given
|
||||
f('false, 3.14, 42);
|
||||
characterLiteral(equals(0))
|
||||
matches 'cxxBoolLiteral(equals(false)) and cxxBoolLiteral(equals(0))
|
||||
match false
|
||||
floatLiteral(equals(3.14)) and floatLiteral(equals(314e-2))
|
||||
match 3.14
|
||||
integerLiteral(equals(42))
|
||||
matches 42
|
||||
|
||||
Usable as: Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CharacterLiteral.html">CharacterLiteral</a>>, Matcher<CXXBoolLiteral>,
|
||||
Usable as: Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CharacterLiteral.html">CharacterLiteral</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXBoolLiteralExpr.html">CXXBoolLiteralExpr</a>>,
|
||||
Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1FloatingLiteral.html">FloatingLiteral</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1IntegerLiteral.html">IntegerLiteral</a>>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CharacterLiteral.html">CharacterLiteral</a>></td><td class="name" onclick="toggle('equals4')"><a name="equals4Anchor">equals</a></td><td>bool Value</td></tr>
|
||||
<tr><td colspan="4" class="doc" id="equals4"><pre></pre></td></tr>
|
||||
|
||||
|
||||
<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CharacterLiteral.html">CharacterLiteral</a>></td><td class="name" onclick="toggle('equals10')"><a name="equals10Anchor">equals</a></td><td>double Value</td></tr>
|
||||
<tr><td colspan="4" class="doc" id="equals10"><pre></pre></td></tr>
|
||||
|
||||
|
||||
<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CharacterLiteral.html">CharacterLiteral</a>></td><td class="name" onclick="toggle('equals7')"><a name="equals7Anchor">equals</a></td><td>unsigned Value</td></tr>
|
||||
<tr><td colspan="4" class="doc" id="equals7"><pre></pre></td></tr>
|
||||
|
||||
|
||||
<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ClassTemplateSpecializationDecl.html">ClassTemplateSpecializationDecl</a>></td><td class="name" onclick="toggle('templateArgumentCountIs0')"><a name="templateArgumentCountIs0Anchor">templateArgumentCountIs</a></td><td>unsigned N</td></tr>
|
||||
<tr><td colspan="4" class="doc" id="templateArgumentCountIs0"><pre>Matches if the number of template arguments equals N.
|
||||
|
||||
|
@ -2533,16 +2571,27 @@ fieldDecl(isBitField())
|
|||
|
||||
|
||||
<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1FloatingLiteral.html">FloatingLiteral</a>></td><td class="name" onclick="toggle('equals1')"><a name="equals1Anchor">equals</a></td><td>ValueT Value</td></tr>
|
||||
<tr><td colspan="4" class="doc" id="equals1"><pre>Matches literals that are equal to the given value.
|
||||
<tr><td colspan="4" class="doc" id="equals1"><pre>Matches literals that are equal to the given value of type ValueT.
|
||||
|
||||
Example matches true (matcher = cxxBoolLiteral(equals(true)))
|
||||
true
|
||||
Given
|
||||
f('false, 3.14, 42);
|
||||
characterLiteral(equals(0))
|
||||
matches 'cxxBoolLiteral(equals(false)) and cxxBoolLiteral(equals(0))
|
||||
match false
|
||||
floatLiteral(equals(3.14)) and floatLiteral(equals(314e-2))
|
||||
match 3.14
|
||||
integerLiteral(equals(42))
|
||||
matches 42
|
||||
|
||||
Usable as: Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CharacterLiteral.html">CharacterLiteral</a>>, Matcher<CXXBoolLiteral>,
|
||||
Usable as: Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CharacterLiteral.html">CharacterLiteral</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXBoolLiteralExpr.html">CXXBoolLiteralExpr</a>>,
|
||||
Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1FloatingLiteral.html">FloatingLiteral</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1IntegerLiteral.html">IntegerLiteral</a>>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1FloatingLiteral.html">FloatingLiteral</a>></td><td class="name" onclick="toggle('equals12')"><a name="equals12Anchor">equals</a></td><td>double Value</td></tr>
|
||||
<tr><td colspan="4" class="doc" id="equals12"><pre></pre></td></tr>
|
||||
|
||||
|
||||
<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>></td><td class="name" onclick="toggle('hasDynamicExceptionSpec0')"><a name="hasDynamicExceptionSpec0Anchor">hasDynamicExceptionSpec</a></td><td></td></tr>
|
||||
<tr><td colspan="4" class="doc" id="hasDynamicExceptionSpec0"><pre>Matches functions that have a dynamic exception specification.
|
||||
|
||||
|
@ -2805,16 +2854,35 @@ functionProtoType(parameterCountIs(3))
|
|||
|
||||
|
||||
<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1IntegerLiteral.html">IntegerLiteral</a>></td><td class="name" onclick="toggle('equals0')"><a name="equals0Anchor">equals</a></td><td>ValueT Value</td></tr>
|
||||
<tr><td colspan="4" class="doc" id="equals0"><pre>Matches literals that are equal to the given value.
|
||||
<tr><td colspan="4" class="doc" id="equals0"><pre>Matches literals that are equal to the given value of type ValueT.
|
||||
|
||||
Example matches true (matcher = cxxBoolLiteral(equals(true)))
|
||||
true
|
||||
Given
|
||||
f('false, 3.14, 42);
|
||||
characterLiteral(equals(0))
|
||||
matches 'cxxBoolLiteral(equals(false)) and cxxBoolLiteral(equals(0))
|
||||
match false
|
||||
floatLiteral(equals(3.14)) and floatLiteral(equals(314e-2))
|
||||
match 3.14
|
||||
integerLiteral(equals(42))
|
||||
matches 42
|
||||
|
||||
Usable as: Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CharacterLiteral.html">CharacterLiteral</a>>, Matcher<CXXBoolLiteral>,
|
||||
Usable as: Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CharacterLiteral.html">CharacterLiteral</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXBoolLiteralExpr.html">CXXBoolLiteralExpr</a>>,
|
||||
Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1FloatingLiteral.html">FloatingLiteral</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1IntegerLiteral.html">IntegerLiteral</a>>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1IntegerLiteral.html">IntegerLiteral</a>></td><td class="name" onclick="toggle('equals6')"><a name="equals6Anchor">equals</a></td><td>bool Value</td></tr>
|
||||
<tr><td colspan="4" class="doc" id="equals6"><pre></pre></td></tr>
|
||||
|
||||
|
||||
<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1IntegerLiteral.html">IntegerLiteral</a>></td><td class="name" onclick="toggle('equals13')"><a name="equals13Anchor">equals</a></td><td>double Value</td></tr>
|
||||
<tr><td colspan="4" class="doc" id="equals13"><pre></pre></td></tr>
|
||||
|
||||
|
||||
<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1IntegerLiteral.html">IntegerLiteral</a>></td><td class="name" onclick="toggle('equals9')"><a name="equals9Anchor">equals</a></td><td>unsigned Value</td></tr>
|
||||
<tr><td colspan="4" class="doc" id="equals9"><pre></pre></td></tr>
|
||||
|
||||
|
||||
<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html">MemberExpr</a>></td><td class="name" onclick="toggle('isArrow0')"><a name="isArrow0Anchor">isArrow</a></td><td></td></tr>
|
||||
<tr><td colspan="4" class="doc" id="isArrow0"><pre>Matches member expressions that are called with '->' as opposed
|
||||
to '.'.
|
||||
|
|
|
@ -3806,14 +3806,22 @@ AST_MATCHER_P(CompoundStmt, statementCountIs, unsigned, N) {
|
|||
return Node.size() == N;
|
||||
}
|
||||
|
||||
/// \brief Matches literals that are equal to the given value.
|
||||
/// \brief Matches literals that are equal to the given value of type ValueT.
|
||||
///
|
||||
/// Example matches true (matcher = cxxBoolLiteral(equals(true)))
|
||||
/// Given
|
||||
/// \code
|
||||
/// true
|
||||
/// f('\0', false, 3.14, 42);
|
||||
/// \endcode
|
||||
/// characterLiteral(equals(0))
|
||||
/// matches '\0'
|
||||
/// cxxBoolLiteral(equals(false)) and cxxBoolLiteral(equals(0))
|
||||
/// match false
|
||||
/// floatLiteral(equals(3.14)) and floatLiteral(equals(314e-2))
|
||||
/// match 3.14
|
||||
/// integerLiteral(equals(42))
|
||||
/// matches 42
|
||||
///
|
||||
/// Usable as: Matcher<CharacterLiteral>, Matcher<CXXBoolLiteral>,
|
||||
/// Usable as: Matcher<CharacterLiteral>, Matcher<CXXBoolLiteralExpr>,
|
||||
/// Matcher<FloatingLiteral>, Matcher<IntegerLiteral>
|
||||
template <typename ValueT>
|
||||
internal::PolymorphicMatcherWithParam1<internal::ValueEqualsMatcher, ValueT>
|
||||
|
@ -3823,6 +3831,34 @@ equals(const ValueT &Value) {
|
|||
ValueT>(Value);
|
||||
}
|
||||
|
||||
AST_POLYMORPHIC_MATCHER_P_OVERLOAD(equals,
|
||||
AST_POLYMORPHIC_SUPPORTED_TYPES(CharacterLiteral,
|
||||
CXXBoolLiteralExpr,
|
||||
IntegerLiteral),
|
||||
bool, Value, 0) {
|
||||
return internal::ValueEqualsMatcher<NodeType, ParamT>(Value)
|
||||
.matchesNode(Node);
|
||||
}
|
||||
|
||||
AST_POLYMORPHIC_MATCHER_P_OVERLOAD(equals,
|
||||
AST_POLYMORPHIC_SUPPORTED_TYPES(CharacterLiteral,
|
||||
CXXBoolLiteralExpr,
|
||||
IntegerLiteral),
|
||||
unsigned, Value, 1) {
|
||||
return internal::ValueEqualsMatcher<NodeType, ParamT>(Value)
|
||||
.matchesNode(Node);
|
||||
}
|
||||
|
||||
AST_POLYMORPHIC_MATCHER_P_OVERLOAD(equals,
|
||||
AST_POLYMORPHIC_SUPPORTED_TYPES(CharacterLiteral,
|
||||
CXXBoolLiteralExpr,
|
||||
FloatingLiteral,
|
||||
IntegerLiteral),
|
||||
double, Value, 2) {
|
||||
return internal::ValueEqualsMatcher<NodeType, ParamT>(Value)
|
||||
.matchesNode(Node);
|
||||
}
|
||||
|
||||
/// \brief Matches the operator Name of operator expressions (binary or
|
||||
/// unary).
|
||||
///
|
||||
|
|
|
@ -56,20 +56,24 @@ void RegistryMaps::registerMatcher(
|
|||
registerMatcher(#name, internal::makeMatcherAutoMarshall( \
|
||||
::clang::ast_matchers::name, #name));
|
||||
|
||||
#define REGISTER_MATCHER_OVERLOAD(name) \
|
||||
registerMatcher(#name, \
|
||||
llvm::make_unique<internal::OverloadedMatcherDescriptor>(name##Callbacks))
|
||||
|
||||
#define SPECIFIC_MATCHER_OVERLOAD(name, Id) \
|
||||
static_cast<::clang::ast_matchers::name##_Type##Id>( \
|
||||
::clang::ast_matchers::name)
|
||||
|
||||
#define MATCHER_OVERLOAD_ENTRY(name, Id) \
|
||||
internal::makeMatcherAutoMarshall(SPECIFIC_MATCHER_OVERLOAD(name, Id), \
|
||||
#name)
|
||||
|
||||
#define REGISTER_OVERLOADED_2(name) \
|
||||
do { \
|
||||
std::unique_ptr<MatcherDescriptor> Callbacks[] = { \
|
||||
internal::makeMatcherAutoMarshall(SPECIFIC_MATCHER_OVERLOAD(name, 0), \
|
||||
#name), \
|
||||
internal::makeMatcherAutoMarshall(SPECIFIC_MATCHER_OVERLOAD(name, 1), \
|
||||
#name)}; \
|
||||
registerMatcher( \
|
||||
#name, \
|
||||
llvm::make_unique<internal::OverloadedMatcherDescriptor>(Callbacks)); \
|
||||
std::unique_ptr<MatcherDescriptor> name##Callbacks[] = { \
|
||||
MATCHER_OVERLOAD_ENTRY(name, 0), \
|
||||
MATCHER_OVERLOAD_ENTRY(name, 1)}; \
|
||||
REGISTER_MATCHER_OVERLOAD(name); \
|
||||
} while (0)
|
||||
|
||||
/// \brief Generate a registry map with all the known matchers.
|
||||
|
@ -83,7 +87,6 @@ RegistryMaps::RegistryMaps() {
|
|||
// findAll
|
||||
//
|
||||
// Other:
|
||||
// equals
|
||||
// equalsNode
|
||||
|
||||
REGISTER_OVERLOADED_2(callee);
|
||||
|
@ -96,6 +99,13 @@ RegistryMaps::RegistryMaps() {
|
|||
REGISTER_OVERLOADED_2(references);
|
||||
REGISTER_OVERLOADED_2(thisPointerType);
|
||||
|
||||
std::unique_ptr<MatcherDescriptor> equalsCallbacks[] = {
|
||||
MATCHER_OVERLOAD_ENTRY(equals, 0),
|
||||
MATCHER_OVERLOAD_ENTRY(equals, 1),
|
||||
MATCHER_OVERLOAD_ENTRY(equals, 2),
|
||||
};
|
||||
REGISTER_MATCHER_OVERLOAD(equals);
|
||||
|
||||
REGISTER_MATCHER(accessSpecDecl);
|
||||
REGISTER_MATCHER(addrLabelExpr);
|
||||
REGISTER_MATCHER(alignOfExpr);
|
||||
|
|
|
@ -511,6 +511,46 @@ TEST_F(RegistryTest, ParenExpr) {
|
|||
EXPECT_FALSE(matches("int i = 1;", Value));
|
||||
}
|
||||
|
||||
TEST_F(RegistryTest, EqualsMatcher) {
|
||||
Matcher<Stmt> BooleanStmt = constructMatcher(
|
||||
"cxxBoolLiteral", constructMatcher("equals", VariantValue(true)))
|
||||
.getTypedMatcher<Stmt>();
|
||||
EXPECT_TRUE(matches("bool x = true;", BooleanStmt));
|
||||
EXPECT_FALSE(matches("bool x = false;", BooleanStmt));
|
||||
EXPECT_FALSE(matches("bool x = 0;", BooleanStmt));
|
||||
|
||||
BooleanStmt = constructMatcher(
|
||||
"cxxBoolLiteral", constructMatcher("equals", VariantValue(0)))
|
||||
.getTypedMatcher<Stmt>();
|
||||
EXPECT_TRUE(matches("bool x = false;", BooleanStmt));
|
||||
EXPECT_FALSE(matches("bool x = true;", BooleanStmt));
|
||||
EXPECT_FALSE(matches("bool x = 0;", BooleanStmt));
|
||||
|
||||
Matcher<Stmt> DoubleStmt = constructMatcher(
|
||||
"floatLiteral", constructMatcher("equals", VariantValue(1.2)))
|
||||
.getTypedMatcher<Stmt>();
|
||||
EXPECT_TRUE(matches("double x = 1.2;", DoubleStmt));
|
||||
EXPECT_TRUE(matches("double x = 1.2f;", DoubleStmt));
|
||||
EXPECT_TRUE(matches("double x = 1.2l;", DoubleStmt));
|
||||
EXPECT_TRUE(matches("double x = 12e-1;", DoubleStmt));
|
||||
EXPECT_FALSE(matches("double x = 1.23;", DoubleStmt));
|
||||
|
||||
Matcher<Stmt> IntegerStmt = constructMatcher(
|
||||
"integerLiteral", constructMatcher("equals", VariantValue(42)))
|
||||
.getTypedMatcher<Stmt>();
|
||||
EXPECT_TRUE(matches("int x = 42;", IntegerStmt));
|
||||
EXPECT_FALSE(matches("int x = 1;", IntegerStmt));
|
||||
|
||||
Matcher<Stmt> CharStmt = constructMatcher(
|
||||
"characterLiteral", constructMatcher("equals", VariantValue('x')))
|
||||
.getTypedMatcher<Stmt>();
|
||||
EXPECT_TRUE(matches("int x = 'x';", CharStmt));
|
||||
EXPECT_TRUE(matches("int x = L'x';", CharStmt));
|
||||
EXPECT_TRUE(matches("int x = u'x';", CharStmt));
|
||||
EXPECT_TRUE(matches("int x = U'x';", CharStmt));
|
||||
EXPECT_FALSE(matches("int x = 120;", CharStmt));
|
||||
}
|
||||
|
||||
} // end anonymous namespace
|
||||
} // end namespace dynamic
|
||||
} // end namespace ast_matchers
|
||||
|
|
Loading…
Reference in New Issue