[PATCH] D15506: [ASTMatchers] Allow hasName() to look through inline namespaces

Samuel Benzaquen via cfe-commits cfe-commits at lists.llvm.org
Mon Dec 14 12:43:26 PST 2015


sbenza created this revision.
sbenza added a reviewer: klimek.
sbenza added a subscriber: cfe-commits.
Herald added a subscriber: klimek.

Allow hasName() to look through inline namespaces.
This will fix the interaction between some clang-tidy checks and libc++.

libc++ defines names in an inline namespace named std::<version_#>.
When we try to match a name using hasName("std::xxx") it fails to match and the clang-tidy check does not work.

http://reviews.llvm.org/D15506

Files:
  lib/ASTMatchers/ASTMatchersInternal.cpp
  unittests/ASTMatchers/ASTMatchersTest.cpp

Index: unittests/ASTMatchers/ASTMatchersTest.cpp
===================================================================
--- unittests/ASTMatchers/ASTMatchersTest.cpp
+++ unittests/ASTMatchers/ASTMatchersTest.cpp
@@ -2644,6 +2644,14 @@
                  recordDecl(hasName("A+B::C"))));
 }
 
+TEST(Matcher, HasNameSupportsInlinedNamesapces) {
+  std::string code = "namespace a { inline namespace b { class C; } }";
+  EXPECT_TRUE(matches(code, recordDecl(hasName("a::b::C"))));
+  EXPECT_TRUE(matches(code, recordDecl(hasName("a::C"))));
+  EXPECT_TRUE(matches(code, recordDecl(hasName("::a::b::C"))));
+  EXPECT_TRUE(matches(code, recordDecl(hasName("::a::C"))));
+}
+
 TEST(Matcher, IsDefinition) {
   DeclarationMatcher DefinitionOfClassA =
       recordDecl(hasName("A"), isDefinition());
Index: lib/ASTMatchers/ASTMatchersInternal.cpp
===================================================================
--- lib/ASTMatchers/ASTMatchersInternal.cpp
+++ lib/ASTMatchers/ASTMatchersInternal.cpp
@@ -315,17 +315,31 @@
 }
 
 bool HasNameMatcher::matchesNodeFull(const NamedDecl &Node) const {
-  llvm::SmallString<128> NodeName = StringRef("::");
-  llvm::raw_svector_ostream OS(NodeName);
-  Node.printQualifiedName(OS);
-  const StringRef FullName = OS.str();
   const StringRef Pattern = Name;
 
-  if (Pattern.startswith("::"))
-    return FullName == Pattern;
+  for (bool SkipUnwritten : {false, true}) {
+    llvm::SmallString<128> NodeName = StringRef("::");
+    llvm::raw_svector_ostream OS(NodeName);
+
+    if (SkipUnwritten) {
+      PrintingPolicy Policy = Node.getASTContext().getPrintingPolicy();
+      Policy.SuppressUnwrittenScope = true;
+      Node.printQualifiedName(OS, Policy);
+    } else {
+      Node.printQualifiedName(OS);
+    }
 
-  return FullName.endswith(Pattern) &&
-         FullName.drop_back(Pattern.size()).endswith("::");
+    const StringRef FullName = OS.str();
+
+    if (Pattern.startswith("::")) {
+      if (FullName == Pattern) return true;
+    } else if (FullName.endswith(Pattern) &&
+               FullName.drop_back(Pattern.size()).endswith("::")) {
+      return true;
+    }
+  }
+
+  return false;
 }
 
 bool HasNameMatcher::matchesNode(const NamedDecl &Node) const {


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D15506.42755.patch
Type: text/x-patch
Size: 2220 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20151214/394dc2e8/attachment.bin>


More information about the cfe-commits mailing list