Fix completion logic to allow for heterogeneous argument types in matcher overloads.

Summary:
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

Reviewers: pcc

Subscribers: klimek, cfe-commits

Differential Revision: http://reviews.llvm.org/D5711

llvm-svn: 219450
diff --git a/clang/lib/ASTMatchers/Dynamic/Registry.cpp b/clang/lib/ASTMatchers/Dynamic/Registry.cpp
index 5672169..b92e8ef 100644
--- a/clang/lib/ASTMatchers/Dynamic/Registry.cpp
+++ b/clang/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();
           }
         }
       }