From a086b9fd15161fb50043b0921be4b2e11018b0cb Mon Sep 17 00:00:00 2001 From: Aaron Ballman Date: Wed, 17 Aug 2016 13:10:42 +0000 Subject: Add an AST matcher for external formal linkage. Patch by Visoiu Mistrih llvm-svn: 278926 --- clang/docs/LibASTMatchersReference.html | 20 ++++++++++++++++++ clang/include/clang/ASTMatchers/ASTMatchers.h | 24 ++++++++++++++++++++++ clang/lib/ASTMatchers/Dynamic/Registry.cpp | 1 + .../ASTMatchers/ASTMatchersNarrowingTest.cpp | 16 +++++++++++++++ 4 files changed, 61 insertions(+) (limited to 'clang') diff --git a/clang/docs/LibASTMatchersReference.html b/clang/docs/LibASTMatchersReference.html index b87cae230bf..f97183895cb 100644 --- a/clang/docs/LibASTMatchersReference.html +++ b/clang/docs/LibASTMatchersReference.html @@ -2740,6 +2740,26 @@ memberExpr(isArrow()) +Matcher<NamedDecl>hasExternalFormalLinkage +
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() {}
+}
+
+ + Matcher<NamedDecl>hasNamestd::string Name
Matches NamedDecl nodes that have the specified name.
 
diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h
index 6f194e2a57a..63ec2a4a949 100644
--- a/clang/include/clang/ASTMatchers/ASTMatchers.h
+++ b/clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -5476,6 +5476,30 @@ AST_MATCHER_P(Stmt, forFunction, internal::Matcher,
   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/clang/lib/ASTMatchers/Dynamic/Registry.cpp b/clang/lib/ASTMatchers/Dynamic/Registry.cpp
index 192b4b6d2ac..6e594d7a7fd 100644
--- a/clang/lib/ASTMatchers/Dynamic/Registry.cpp
+++ b/clang/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/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
index 108fd435cef..1527eacb6ab 100644
--- a/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
+++ b/clang/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
-- 
cgit v1.2.3