steveire created this revision.
steveire added a reviewer: aaron.ballman.
Herald added a subscriber: cfe-commits.

Repository:
  rC Clang

https://reviews.llvm.org/D54408

Files:
  lib/ASTMatchers/Dynamic/Registry.cpp
  unittests/ASTMatchers/Dynamic/RegistryTest.cpp

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()"));
 }
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<std::pair<ASTNodeKind, std::string>>
+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<MatchingMatcher>
-Registry::getMatchingMatchers(ast_type_traits::ASTNodeKind StaticType) {
+getDerivedResults(ast_type_traits::ASTNodeKind StaticType, StringRef Name);
+
+std::vector<MatchingMatcher>
+getMatchingMatchersImpl(ast_type_traits::ASTNodeKind StaticType,
+                        bool ExactOnly = false) {
+
   std::vector<MatchingMatcher> Result;
 
   static std::vector<StringRef> excludedMatchers{
@@ -684,10 +702,39 @@
   AcceptedTypes.push_back(StaticType);
 
   processAcceptableMatchers(
-      AcceptedTypes, [&Result](StringRef Name, const MatcherDescriptor &Matcher,
-                               std::set<ASTNodeKind> &RetKinds,
-                               std::vector<std::vector<ArgKind>> ArgsKinds,
-                               unsigned MaxSpecificity) {
+      AcceptedTypes, [&](StringRef Name, const MatcherDescriptor &Matcher,
+                         std::set<ASTNodeKind> &RetKinds,
+                         std::vector<std::vector<ArgKind>> 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<MatchingMatcher>
+getDerivedResults(ast_type_traits::ASTNodeKind StaticType, StringRef Name) {
+  auto NestedResult = getMatchingMatchersImpl(StaticType, true);
+
+  std::vector<MatchingMatcher> Result;
+
+  Diagnostics DiagnosticIgnorer;
+
+  for (auto item : NestedResult) {
+
+    auto nestedMatcherName = item.MatcherString;
+
+    nestedMatcherName = Name.str() + "(" + nestedMatcherName + ")";
+
+    Result.emplace_back(nestedMatcherName);
+  }
+
+  return Result;
+}
+
+std::vector<MatchingMatcher>
+Registry::getMatchingMatchers(ast_type_traits::ASTNodeKind StaticType) {
+
+  std::vector<MatchingMatcher> Result = getMatchingMatchersImpl(StaticType);
+
+  return Result;
+}
+
 std::vector<MatcherCompletion>
 Registry::getMatcherCompletions(ArrayRef<ArgKind> AcceptedTypes) {
   std::vector<MatcherCompletion> Completions;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to