From 301bc621b5f774ca2998f9804730ee5d15846c8a Mon Sep 17 00:00:00 2001 From: Aaron Ballman <aaron@aaronballman.com> Date: Wed, 17 Aug 2016 13:10:42 +0000 Subject: [PATCH] Add an AST matcher for external formal linkage. Patch by Visoiu Mistrih git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@278926 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/LibASTMatchersReference.html | 20 ++++++++++++++++ include/clang/ASTMatchers/ASTMatchers.h | 24 +++++++++++++++++++ lib/ASTMatchers/Dynamic/Registry.cpp | 1 + .../ASTMatchers/ASTMatchersNarrowingTest.cpp | 16 +++++++++++++ 4 files changed, 61 insertions(+) diff --git a/docs/LibASTMatchersReference.html b/docs/LibASTMatchersReference.html index b87cae230bf..f97183895cb 100644 --- a/docs/LibASTMatchersReference.html +++ b/docs/LibASTMatchersReference.html @@ -2740,6 +2740,26 @@ memberExpr(isArrow()) </pre></td></tr> +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1NamedDecl.html">NamedDecl</a>></td><td class="name" onclick="toggle('hasExternalFormalLinkage0')"><a name="hasExternalFormalLinkage0Anchor">hasExternalFormalLinkage</a></td><td></td></tr> +<tr><td colspan="4" class="doc" id="hasExternalFormalLinkage0"><pre>Matches a declaration that has external formal linkage. + +Example matches only z (matcher = varDecl(hasExternalFormalLinkage())) +void f() { + int x; + static int y; +} +int z; + +Example matches f() because it has external formal linkage despite being +unique to the translation unit as though it has internal likage +(matcher = functionDecl(hasExternalFormalLinkage())) + +namespace { +void f() {} +} +</pre></td></tr> + + <tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1NamedDecl.html">NamedDecl</a>></td><td class="name" onclick="toggle('hasName0')"><a name="hasName0Anchor">hasName</a></td><td>std::string Name</td></tr> <tr><td colspan="4" class="doc" id="hasName0"><pre>Matches NamedDecl nodes that have the specified name. diff --git a/include/clang/ASTMatchers/ASTMatchers.h b/include/clang/ASTMatchers/ASTMatchers.h index 6f194e2a57a..63ec2a4a949 100644 --- a/include/clang/ASTMatchers/ASTMatchers.h +++ b/include/clang/ASTMatchers/ASTMatchers.h @@ -5476,6 +5476,30 @@ AST_MATCHER_P(Stmt, forFunction, internal::Matcher<FunctionDecl>, return false; } +/// \brief Matches a declaration that has external formal linkage. +/// +/// Example matches only z (matcher = varDecl(hasExternalFormalLinkage())) +/// \code +/// void f() { +/// int x; +/// static int y; +/// } +/// int z; +/// \endcode +/// +/// Example matches f() because it has external formal linkage despite being +/// unique to the translation unit as though it has internal likage +/// (matcher = functionDecl(hasExternalFormalLinkage())) +/// +/// \code +/// namespace { +/// void f() {} +/// } +/// \endcode +AST_MATCHER(NamedDecl, hasExternalFormalLinkage) { + return Node.hasExternalFormalLinkage(); +} + } // end namespace ast_matchers } // end namespace clang diff --git a/lib/ASTMatchers/Dynamic/Registry.cpp b/lib/ASTMatchers/Dynamic/Registry.cpp index 192b4b6d2ac..6e594d7a7fd 100644 --- a/lib/ASTMatchers/Dynamic/Registry.cpp +++ b/lib/ASTMatchers/Dynamic/Registry.cpp @@ -226,6 +226,7 @@ RegistryMaps::RegistryMaps() { REGISTER_MATCHER(hasEitherOperand); REGISTER_MATCHER(hasElementType); REGISTER_MATCHER(hasElse); + REGISTER_MATCHER(hasExternalFormalLinkage); REGISTER_MATCHER(hasFalseExpression); REGISTER_MATCHER(hasGlobalStorage); REGISTER_MATCHER(hasImplicitDestinationType); diff --git a/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp b/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp index 108fd435cef..1527eacb6ab 100644 --- a/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp +++ b/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp @@ -1937,5 +1937,21 @@ TEST(NullPointerConstants, Basic) { EXPECT_TRUE(notMatches("int i = 0;", expr(nullPointerConstant()))); } +TEST(HasExternalFormalLinkage, Basic) { + EXPECT_TRUE(matches("int a = 0;", namedDecl(hasExternalFormalLinkage()))); + EXPECT_TRUE( + notMatches("static int a = 0;", namedDecl(hasExternalFormalLinkage()))); + EXPECT_TRUE(notMatches("static void f(void) { int a = 0; }", + namedDecl(hasExternalFormalLinkage()))); + EXPECT_TRUE(matches("void f(void) { int a = 0; }", + namedDecl(hasExternalFormalLinkage()))); + + // Despite having internal semantic linkage, the anonymous namespace member + // has external linkage because the member has a unique name in all + // translation units. + EXPECT_TRUE(matches("namespace { int a = 0; }", + namedDecl(hasExternalFormalLinkage()))); +} + } // namespace ast_matchers } // namespace clang -- GitLab