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 { 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());