Index: lib/ASTMatchers/Dynamic/Registry.cpp =================================================================== --- lib/ASTMatchers/Dynamic/Registry.cpp +++ lib/ASTMatchers/Dynamic/Registry.cpp @@ -640,8 +640,26 @@ } } +using SR = ast_matchers::dynamic::SourceRange; + +llvm::Optional> +getNodeConstructorType(MatcherCtor targetCtor) { + auto const &ctors = RegistryData->nodeConstructors(); + + for (auto ctor : ctors) { + if (ctor.second.second == targetCtor) + return std::make_pair(ctor.first, ctor.second.first); + } + return llvm::None; +} + std::vector -Registry::getMatchingMatchers(ast_type_traits::ASTNodeKind StaticType) { +getDerivedResults(ast_type_traits::ASTNodeKind StaticType, StringRef Name); + +std::vector +getMatchingMatchersImpl(ast_type_traits::ASTNodeKind StaticType, + bool ExactOnly = false) { + std::vector Result; static std::vector excludedMatchers{ @@ -684,10 +702,39 @@ AcceptedTypes.push_back(StaticType); processAcceptableMatchers( - AcceptedTypes, [&Result](StringRef Name, const MatcherDescriptor &Matcher, - std::set &RetKinds, - std::vector> ArgsKinds, - unsigned MaxSpecificity) { + AcceptedTypes, [&](StringRef Name, const MatcherDescriptor &Matcher, + std::set &RetKinds, + std::vector> ArgsKinds, + unsigned MaxSpecificity) { + { + unsigned Specificity; + ASTNodeKind LeastDerivedKind; + if (ExactOnly) { + auto isConv = Matcher.isConvertibleTo(StaticType, &Specificity, + &LeastDerivedKind); + if (isConv && !LeastDerivedKind.isSame(StaticType)) { + return; + } + } + } + + { + auto TypeForMatcherOpt = getNodeConstructorType(&Matcher); + if (TypeForMatcherOpt) { + // TODO: Should not be needed. + // Actually, all base types should be part of it. + // Nah, only all derived types. + if (TypeForMatcherOpt->first.isBaseOf(StaticType)) { + return; + } + if (StaticType.isBaseOf(TypeForMatcherOpt->first)) { + auto derRes = getDerivedResults(TypeForMatcherOpt->first, Name); + Result.insert(Result.end(), derRes.begin(), derRes.end()); + return; + } + } + } + if (!std::binary_search(excludedMatchers.begin(), excludedMatchers.end(), Name)) { Result.emplace_back((Name + "()").str()); @@ -697,6 +744,34 @@ return Result; } +std::vector +getDerivedResults(ast_type_traits::ASTNodeKind StaticType, StringRef Name) { + auto NestedResult = getMatchingMatchersImpl(StaticType, true); + + std::vector Result; + + Diagnostics DiagnosticIgnorer; + + for (auto item : NestedResult) { + + auto nestedMatcherName = item.MatcherString; + + nestedMatcherName = Name.str() + "(" + nestedMatcherName + ")"; + + Result.emplace_back(nestedMatcherName); + } + + return Result; +} + +std::vector +Registry::getMatchingMatchers(ast_type_traits::ASTNodeKind StaticType) { + + std::vector Result = getMatchingMatchersImpl(StaticType); + + return Result; +} + std::vector Registry::getMatcherCompletions(ArrayRef AcceptedTypes) { std::vector Completions; Index: unittests/ASTMatchers/Dynamic/RegistryTest.cpp =================================================================== --- unittests/ASTMatchers/Dynamic/RegistryTest.cpp +++ unittests/ASTMatchers/Dynamic/RegistryTest.cpp @@ -571,14 +571,14 @@ EXPECT_TRUE(Contains(Matchers, "hasType()")); EXPECT_TRUE(Contains(Matchers, "hasTypeLoc()")); EXPECT_TRUE(Contains(Matchers, "parameterCountIs()")); + EXPECT_TRUE(Contains(Matchers, "cxxMethodDecl(isOverride())")); EXPECT_TRUE(!Contains(Matchers, "decl()")); EXPECT_TRUE(!Contains(Matchers, "namedDecl()")); EXPECT_TRUE(!Contains(Matchers, "valueDecl()")); EXPECT_TRUE(!Contains(Matchers, "declaratorDecl()")); EXPECT_TRUE(!Contains(Matchers, "functionDecl()")); - - EXPECT_TRUE(Contains(Matchers, "cxxMethodDecl()")); + EXPECT_TRUE(!Contains(Matchers, "cxxMethodDecl()")); EXPECT_TRUE(!Contains(Matchers, "has()")); }