Hi pcc,

There was an assumption that there were no matchers that were overloaded
on matchers and other types of arguments.
This assumption was broken recently with the addition of new matcher
overloads.

Fixes http://llvm.org/PR21226

http://reviews.llvm.org/D5711

Files:
  lib/ASTMatchers/Dynamic/Registry.cpp
  unittests/ASTMatchers/Dynamic/RegistryTest.cpp
Index: lib/ASTMatchers/Dynamic/Registry.cpp
===================================================================
--- lib/ASTMatchers/Dynamic/Registry.cpp
+++ 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();
           }
         }
       }
Index: unittests/ASTMatchers/Dynamic/RegistryTest.cpp
===================================================================
--- unittests/ASTMatchers/Dynamic/RegistryTest.cpp
+++ 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) {
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to