forked from OSchip/llvm-project
Added an AST matcher for declarations that are in the `std` namespace
Reviewers: alexfh Subscribers: cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D61480 llvm-svn: 359876
This commit is contained in:
parent
6d08b8dbae
commit
b641b914a3
|
@ -17,10 +17,6 @@ namespace clang {
|
|||
namespace tidy {
|
||||
namespace bugprone {
|
||||
|
||||
namespace {
|
||||
AST_MATCHER(Decl, isInStdNamespace) { return Node.isInStdNamespace(); }
|
||||
}
|
||||
|
||||
void InaccurateEraseCheck::registerMatchers(MatchFinder *Finder) {
|
||||
// Only register the matchers for C++; the functionality currently does not
|
||||
// provide any benefit to other languages, despite being benign.
|
||||
|
|
|
@ -2827,6 +2827,29 @@ by the compiler (eg. implicit default/copy constructors).
|
|||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>></td><td class="name" onclick="toggle('isInStdNamespace0')"><a name="isInStdNamespace0Anchor">isInStdNamespace</a></td><td></td></tr>
|
||||
<tr><td colspan="4" class="doc" id="isInStdNamespace0"><pre>Matches declarations in the namespace `std`, but not in nested namespaces.
|
||||
|
||||
Given
|
||||
class vector {};
|
||||
namespace foo {
|
||||
class vector {};
|
||||
namespace std {
|
||||
class vector {};
|
||||
}
|
||||
}
|
||||
namespace std {
|
||||
inline namespace __1 {
|
||||
class vector {}; // #1
|
||||
namespace experimental {
|
||||
class vector {};
|
||||
}
|
||||
}
|
||||
}
|
||||
cxxRecordDecl(hasName("vector"), isInStdNamespace()) will match only #1.
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>></td><td class="name" onclick="toggle('isPrivate0')"><a name="isPrivate0Anchor">isPrivate</a></td><td></td></tr>
|
||||
<tr><td colspan="4" class="doc" id="isPrivate0"><pre>Matches private C++ declarations.
|
||||
|
||||
|
|
|
@ -6212,6 +6212,29 @@ AST_MATCHER(NamespaceDecl, isAnonymous) {
|
|||
return Node.isAnonymousNamespace();
|
||||
}
|
||||
|
||||
/// Matches declarations in the namespace `std`, but not in nested namespaces.
|
||||
///
|
||||
/// Given
|
||||
/// \code
|
||||
/// class vector {};
|
||||
/// namespace foo {
|
||||
/// class vector {};
|
||||
/// namespace std {
|
||||
/// class vector {};
|
||||
/// }
|
||||
/// }
|
||||
/// namespace std {
|
||||
/// inline namespace __1 {
|
||||
/// class vector {}; // #1
|
||||
/// namespace experimental {
|
||||
/// class vector {};
|
||||
/// }
|
||||
/// }
|
||||
/// }
|
||||
/// \endcode
|
||||
/// cxxRecordDecl(hasName("vector"), isInStdNamespace()) will match only #1.
|
||||
AST_MATCHER(Decl, isInStdNamespace) { return Node.isInStdNamespace(); }
|
||||
|
||||
/// If the given case statement does not use the GNU case range
|
||||
/// extension, matches the constant given in the statement.
|
||||
///
|
||||
|
|
|
@ -354,7 +354,8 @@ bool Decl::isInAnonymousNamespace() const {
|
|||
}
|
||||
|
||||
bool Decl::isInStdNamespace() const {
|
||||
return getDeclContext()->isStdNamespace();
|
||||
const DeclContext *DC = getDeclContext();
|
||||
return DC && DC->isStdNamespace();
|
||||
}
|
||||
|
||||
TranslationUnitDecl *Decl::getTranslationUnitDecl() {
|
||||
|
|
|
@ -366,6 +366,7 @@ RegistryMaps::RegistryMaps() {
|
|||
REGISTER_MATCHER(isExternC);
|
||||
REGISTER_MATCHER(isFinal);
|
||||
REGISTER_MATCHER(isImplicit);
|
||||
REGISTER_MATCHER(isInStdNamespace);
|
||||
REGISTER_MATCHER(isInTemplateInstantiation);
|
||||
REGISTER_MATCHER(isInline);
|
||||
REGISTER_MATCHER(isInstanceMessage);
|
||||
|
|
|
@ -2031,6 +2031,57 @@ TEST(NS, Anonymous) {
|
|||
EXPECT_TRUE(matches("namespace {}", namespaceDecl(isAnonymous())));
|
||||
}
|
||||
|
||||
TEST(DeclarationMatcher, InStdNamespace) {
|
||||
EXPECT_TRUE(notMatches("class vector {};"
|
||||
"namespace foo {"
|
||||
" class vector {};"
|
||||
"}"
|
||||
"namespace foo {"
|
||||
" namespace std {"
|
||||
" class vector {};"
|
||||
" }"
|
||||
"}",
|
||||
cxxRecordDecl(hasName("vector"), isInStdNamespace())));
|
||||
|
||||
EXPECT_TRUE(matches("namespace std {"
|
||||
" class vector {};"
|
||||
"}",
|
||||
cxxRecordDecl(hasName("vector"), isInStdNamespace())));
|
||||
EXPECT_TRUE(matches("namespace std {"
|
||||
" inline namespace __1 {"
|
||||
" class vector {};"
|
||||
" }"
|
||||
"}",
|
||||
cxxRecordDecl(hasName("vector"), isInStdNamespace())));
|
||||
EXPECT_TRUE(notMatches("namespace std {"
|
||||
" inline namespace __1 {"
|
||||
" inline namespace __fs {"
|
||||
" namespace filesystem {"
|
||||
" inline namespace v1 {"
|
||||
" class path {};"
|
||||
" }"
|
||||
" }"
|
||||
" }"
|
||||
" }"
|
||||
"}",
|
||||
cxxRecordDecl(hasName("path"), isInStdNamespace())));
|
||||
EXPECT_TRUE(
|
||||
matches("namespace std {"
|
||||
" inline namespace __1 {"
|
||||
" inline namespace __fs {"
|
||||
" namespace filesystem {"
|
||||
" inline namespace v1 {"
|
||||
" class path {};"
|
||||
" }"
|
||||
" }"
|
||||
" }"
|
||||
" }"
|
||||
"}",
|
||||
cxxRecordDecl(hasName("path"),
|
||||
hasAncestor(namespaceDecl(hasName("filesystem"),
|
||||
isInStdNamespace())))));
|
||||
}
|
||||
|
||||
TEST(EqualsBoundNodeMatcher, QualType) {
|
||||
EXPECT_TRUE(matches(
|
||||
"int i = 1;", varDecl(hasType(qualType().bind("type")),
|
||||
|
|
Loading…
Reference in New Issue