Closed by commit rL219450 (authored by @sbenza).

REPOSITORY
  rL LLVM

http://reviews.llvm.org/D5711

Files:
  cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp
  cfe/trunk/unittests/ASTMatchers/Dynamic/RegistryTest.cpp
Index: cfe/trunk/unittests/ASTMatchers/Dynamic/RegistryTest.cpp
===================================================================
--- cfe/trunk/unittests/ASTMatchers/Dynamic/RegistryTest.cpp
+++ cfe/trunk/unittests/ASTMatchers/Dynamic/RegistryTest.cpp
@@ -438,10 +438,18 @@
 
 TEST_F(RegistryTest, Completion) {
   CompVector Comps = getCompletions();
+  // Overloaded
   EXPECT_TRUE(hasCompletion(
       Comps, "hasParent(", "Matcher<Decl|Stmt> hasParent(Matcher<Decl|Stmt>)"));
+  // Variadic.
   EXPECT_TRUE(hasCompletion(Comps, "whileStmt(",
                             "Matcher<Stmt> whileStmt(Matcher<WhileStmt>...)"));
+  // Polymorphic.
+  EXPECT_TRUE(hasCompletion(
+      Comps, "hasDescendant(",
+      "Matcher<NestedNameSpecifier|NestedNameSpecifierLoc|QualType|...> "
+      "hasDescendant(Matcher<CXXCtorInitializer|NestedNameSpecifier|"
+      "NestedNameSpecifierLoc|...>)"));
 
   CompVector WhileComps = getCompletions("whileStmt", 0);
 
@@ -470,6 +478,12 @@
       hasCompletion(NamedDeclComps, "isPublic()", "Matcher<Decl> isPublic()"));
   EXPECT_TRUE(hasCompletion(NamedDeclComps, "hasName(\"",
                             "Matcher<NamedDecl> hasName(string)"));
+
+  // Heterogeneous overloads.
+  Comps = getCompletions("classTemplateSpecializationDecl", 0);
+  EXPECT_TRUE(hasCompletion(
+      Comps, "isSameOrDerivedFrom(",
+      "Matcher<CXXRecordDecl> isSameOrDerivedFrom(string|Matcher<NamedDecl>)"));
 }
 
 TEST_F(RegistryTest, HasArgs) {
Index: cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp
===================================================================
--- cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp
+++ cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp
@@ -443,17 +443,22 @@
         for (const std::vector<ArgKind> &Arg : ArgsKinds) {
           if (&Arg != &ArgsKinds[0])
             OS << ", ";
-          // This currently assumes that a matcher may not overload a
-          // non-matcher, and all non-matcher overloads have identical
-          // arguments.
-          if (Arg[0].getArgKind() == ArgKind::AK_Matcher) {
-            std::set<ASTNodeKind> MatcherKinds;
-            std::transform(Arg.begin(), Arg.end(),
-                           std::inserter(MatcherKinds, MatcherKinds.end()),
-                           std::mem_fun_ref(&ArgKind::getMatcherKind));
+
+          bool FirstArgKind = true;
+          std::set<ASTNodeKind> MatcherKinds;
+          // Two steps. First all non-matchers, then matchers only.
+          for (const ArgKind &AK : Arg) {
+            if (AK.getArgKind() == ArgKind::AK_Matcher) {
+              MatcherKinds.insert(AK.getMatcherKind());
+            } else {
+              if (!FirstArgKind) OS << "|";
+              FirstArgKind = false;
+              OS << AK.asString();
+            }
+          }
+          if (!MatcherKinds.empty()) {
+            if (!FirstArgKind) OS << "|";
             OS << "Matcher<" << MatcherKinds << ">";
-          } else {
-            OS << Arg[0].asString();
           }
         }
       }
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to