Author: sbenza Date: Thu Oct 9 17:08:52 2014 New Revision: 219450 URL: http://llvm.org/viewvc/llvm-project?rev=219450&view=rev Log: 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 Modified: cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp cfe/trunk/unittests/ASTMatchers/Dynamic/RegistryTest.cpp Modified: cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp?rev=219450&r1=219449&r2=219450&view=diff ============================================================================== --- cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp (original) +++ cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp Thu Oct 9 17:08:52 2014 @@ -443,17 +443,22 @@ Registry::getMatcherCompletions(ArrayRef 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(); } } } Modified: cfe/trunk/unittests/ASTMatchers/Dynamic/RegistryTest.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/ASTMatchers/Dynamic/RegistryTest.cpp?rev=219450&r1=219449&r2=219450&view=diff ============================================================================== --- cfe/trunk/unittests/ASTMatchers/Dynamic/RegistryTest.cpp (original) +++ cfe/trunk/unittests/ASTMatchers/Dynamic/RegistryTest.cpp Thu Oct 9 17:08:52 2014 @@ -438,10 +438,18 @@ TEST_F(RegistryTest, Errors) { 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 @@ TEST_F(RegistryTest, Completion) { 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
