Add a polymorphic AST matcher for testing whether a constructor or a conversion declaration is marked as explicit or not.

llvm-svn: 244666
This commit is contained in:
Aaron Ballman 2015-08-11 21:09:52 +00:00
parent da06bce8b5
commit 6f6d0b6c5a
4 changed files with 62 additions and 0 deletions

View File

@ -1483,6 +1483,19 @@ Example matches #1, but not #2 or #3 (matcher = constructorDecl(isDefaultConstru
</pre></td></tr>
<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructorDecl.html">CXXConstructorDecl</a>&gt;</td><td class="name" onclick="toggle('isExplicit0')"><a name="isExplicit0Anchor">isExplicit</a></td><td></td></tr>
<tr><td colspan="4" class="doc" id="isExplicit0"><pre>Matches a constructor declaration if it is marked explicit.
Given
struct S {
S(int); // #1
explicit S(double); // #2
};
constructorDecl(isExplicit())
will match #2, but not #1.
</pre></td></tr>
<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructorDecl.html">CXXConstructorDecl</a>&gt;</td><td class="name" onclick="toggle('isMoveConstructor1')"><a name="isMoveConstructor1Anchor">isMoveConstructor</a></td><td></td></tr>
<tr><td colspan="4" class="doc" id="isMoveConstructor1"><pre>Matches constructor declarations that are move constructors.
@ -1495,6 +1508,19 @@ Example matches #3, but not #1 or #2 (matcher = constructorDecl(isMoveConstructo
</pre></td></tr>
<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConversionDecl.html">CXXConversionDecl</a>&gt;</td><td class="name" onclick="toggle('isExplicit1')"><a name="isExplicit1Anchor">isExplicit</a></td><td></td></tr>
<tr><td colspan="4" class="doc" id="isExplicit1"><pre>Matches a conversion declaration if it is marked explicit.
Given
struct S {
operator int(); // #1
explicit operator bool(); // #2
};
conversionDecl(isExplicit())
will match #2, but not #1.
</pre></td></tr>
<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXCtorInitializer.html">CXXCtorInitializer</a>&gt;</td><td class="name" onclick="toggle('isBaseInitializer0')"><a name="isBaseInitializer0Anchor">isBaseInitializer</a></td><td></td></tr>
<tr><td colspan="4" class="doc" id="isBaseInitializer0"><pre>Matches a constructor initializer if it is initializing a base, as opposed to a member.

View File

@ -4189,6 +4189,27 @@ AST_MATCHER(CXXConstructorDecl, isDefaultConstructor) {
return Node.isDefaultConstructor();
}
/// \brief Matches constructor and conversion declarations that are marked with
/// the explicit keyword.
///
/// Given
/// \code
/// struct S {
/// S(int); // #1
/// explicit S(double); // #2
/// operator int(); // #3
/// explicit operator bool(); // #4
/// };
/// \endcode
/// constructorDecl(isExplicit()) will match #2, but not #1.
/// conversionDecl(isExplicit()) will match #4, but not #3.
AST_POLYMORPHIC_MATCHER(isExplicit,
AST_POLYMORPHIC_SUPPORTED_TYPES(CXXConstructorDecl,
CXXConversionDecl)) {
return Node.isExplicit();
}
/// \brief If the given case statement does not use the GNU case range
/// extension, matches the constant given in the statement.
///

View File

@ -249,6 +249,7 @@ RegistryMaps::RegistryMaps() {
REGISTER_MATCHER(isDefinition);
REGISTER_MATCHER(isDeleted);
REGISTER_MATCHER(isExceptionVariable);
REGISTER_MATCHER(isExplicit);
REGISTER_MATCHER(isExplicitTemplateSpecialization);
REGISTER_MATCHER(isExpr);
REGISTER_MATCHER(isExternC);

View File

@ -1420,6 +1420,13 @@ TEST(Callee, MatchesDeclarations) {
CallMethodX));
}
TEST(ConversionDeclaration, IsExplicit) {
EXPECT_TRUE(matches("struct S { explicit operator int(); };",
conversionDecl(isExplicit())));
EXPECT_TRUE(notMatches("struct S { operator int(); };",
conversionDecl(isExplicit())));
}
TEST(Callee, MatchesMemberExpressions) {
EXPECT_TRUE(matches("class Y { void x() { this->x(); } };",
callExpr(callee(memberExpr()))));
@ -1992,6 +1999,13 @@ TEST(ConstructorDeclaration, IsImplicit) {
methodDecl(isImplicit(), hasName("operator="))));
}
TEST(ConstructorDeclaration, IsExplicit) {
EXPECT_TRUE(matches("struct S { explicit S(int); };",
constructorDecl(isExplicit())));
EXPECT_TRUE(notMatches("struct S { S(int); };",
constructorDecl(isExplicit())));
}
TEST(ConstructorDeclaration, Kinds) {
EXPECT_TRUE(matches("struct S { S(); };",
constructorDecl(isDefaultConstructor())));