Thanks. On Wed, Oct 21, 2015 at 12:14 PM, Benjamin Kramer <benny....@gmail.com> wrote:
> Reverted for now in r250889. > > On Wed, Oct 21, 2015 at 12:07 PM, Daniel Jasper <djas...@google.com> > wrote: > > I think we'll need to come up with a different solution. The problem is > that > > DynTypedNode is 5 times larger than the bare pointer and we are storing > many > > more elements in the ParentMap. This means, this change is effectively > > increasing the parent map by 10x and it was already large to begin with. > > > > Please revert and lets come up with a different solution. > > > > On Tue, Oct 20, 2015 at 5:08 PM, Benjamin Kramer via cfe-commits > > <cfe-commits@lists.llvm.org> wrote: > >> > >> Author: d0k > >> Date: Tue Oct 20 10:08:46 2015 > >> New Revision: 250831 > >> > >> URL: http://llvm.org/viewvc/llvm-project?rev=250831&view=rev > >> Log: > >> [AST] Put TypeLocs and NestedNameSpecifierLocs into the ParentMap. > >> > >> Firstly this changes the type of parent map to be keyed on DynTypedNode > to > >> simplify the following changes. This comes with a DenseMapInfo for > >> DynTypedNode, which is a bit incomplete still and will probably only > work > >> for parentmap right now. > >> > >> Then the RecursiveASTVisitor in ASTContext is updated and finally > >> ASTMatchers hasParent and hasAncestor learn about the new functionality. > >> > >> Now ParentMap is only missing TemplateArgumentLocs and > >> CXXCtorInitializers. > >> > >> Differential Revision: http://reviews.llvm.org/D13897 > >> > >> Modified: > >> cfe/trunk/include/clang/AST/ASTContext.h > >> cfe/trunk/include/clang/AST/ASTTypeTraits.h > >> cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h > >> cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h > >> cfe/trunk/lib/AST/ASTContext.cpp > >> cfe/trunk/lib/ASTMatchers/ASTMatchFinder.cpp > >> cfe/trunk/unittests/AST/ASTContextParentMapTest.cpp > >> cfe/trunk/unittests/ASTMatchers/Dynamic/ParserTest.cpp > >> cfe/trunk/unittests/ASTMatchers/Dynamic/RegistryTest.cpp > >> > >> Modified: cfe/trunk/include/clang/AST/ASTContext.h > >> URL: > >> > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=250831&r1=250830&r2=250831&view=diff > >> > >> > ============================================================================== > >> --- cfe/trunk/include/clang/AST/ASTContext.h (original) > >> +++ cfe/trunk/include/clang/AST/ASTContext.h Tue Oct 20 10:08:46 2015 > >> @@ -452,7 +452,7 @@ public: > >> typedef llvm::SmallVector<ast_type_traits::DynTypedNode, 2> > >> ParentVector; > >> > >> /// \brief Maps from a node to its parents. > >> - typedef llvm::DenseMap<const void *, > >> + typedef llvm::DenseMap<ast_type_traits::DynTypedNode, > >> > llvm::PointerUnion<ast_type_traits::DynTypedNode > >> *, > >> ParentVector *>> ParentMap; > >> > >> > >> Modified: cfe/trunk/include/clang/AST/ASTTypeTraits.h > >> URL: > >> > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTTypeTraits.h?rev=250831&r1=250830&r2=250831&view=diff > >> > >> > ============================================================================== > >> --- cfe/trunk/include/clang/AST/ASTTypeTraits.h (original) > >> +++ cfe/trunk/include/clang/AST/ASTTypeTraits.h Tue Oct 20 10:08:46 2015 > >> @@ -253,10 +253,30 @@ public: > >> /// @{ > >> /// \brief Imposes an order on \c DynTypedNode. > >> /// > >> - /// Supports comparison of nodes that support memoization. > >> - /// FIXME: Implement comparsion for other node types (currently > >> - /// only Stmt, Decl, Type and NestedNameSpecifier return memoization > >> data). > >> + /// FIXME: Implement comparsion for other node types. > >> bool operator<(const DynTypedNode &Other) const { > >> + if (!NodeKind.isSame(Other.NodeKind)) > >> + return NodeKind < Other.NodeKind; > >> + > >> + if (ASTNodeKind::getFromNodeKind<TypeLoc>().isSame(NodeKind)) { > >> + auto TLA = getUnchecked<TypeLoc>(); > >> + auto TLB = Other.getUnchecked<TypeLoc>(); > >> + return std::make_pair(TLA.getType().getAsOpaquePtr(), > >> + TLA.getOpaqueData()) < > >> + std::make_pair(TLB.getType().getAsOpaquePtr(), > >> + TLB.getOpaqueData()); > >> + } > >> + > >> + if (ASTNodeKind::getFromNodeKind<NestedNameSpecifierLoc>().isSame( > >> + NodeKind)) { > >> + auto NNSLA = getUnchecked<NestedNameSpecifierLoc>(); > >> + auto NNSLB = Other.getUnchecked<NestedNameSpecifierLoc>(); > >> + return std::make_pair(NNSLA.getNestedNameSpecifier(), > >> + NNSLA.getOpaqueData()) < > >> + std::make_pair(NNSLB.getNestedNameSpecifier(), > >> + NNSLB.getOpaqueData()); > >> + } > >> + > >> assert(getMemoizationData() && Other.getMemoizationData()); > >> return getMemoizationData() < Other.getMemoizationData(); > >> } > >> @@ -270,6 +290,13 @@ public: > >> if (ASTNodeKind::getFromNodeKind<QualType>().isSame(NodeKind)) > >> return getUnchecked<QualType>() == > Other.getUnchecked<QualType>(); > >> > >> + if (ASTNodeKind::getFromNodeKind<TypeLoc>().isSame(NodeKind)) > >> + return getUnchecked<TypeLoc>() == Other.getUnchecked<TypeLoc>(); > >> + > >> + if > >> > (ASTNodeKind::getFromNodeKind<NestedNameSpecifierLoc>().isSame(NodeKind)) > >> + return getUnchecked<NestedNameSpecifierLoc>() == > >> + Other.getUnchecked<NestedNameSpecifierLoc>(); > >> + > >> assert(getMemoizationData() && Other.getMemoizationData()); > >> return getMemoizationData() == Other.getMemoizationData(); > >> } > >> @@ -278,6 +305,47 @@ public: > >> } > >> /// @} > >> > >> + /// \brief Hooks for using DynTypedNode as a key in a DenseMap. > >> + struct DenseMapInfo { > >> + static inline DynTypedNode getEmptyKey() { > >> + DynTypedNode Node; > >> + Node.NodeKind = ASTNodeKind::DenseMapInfo::getEmptyKey(); > >> + return Node; > >> + } > >> + static inline DynTypedNode getTombstoneKey() { > >> + DynTypedNode Node; > >> + Node.NodeKind = ASTNodeKind::DenseMapInfo::getTombstoneKey(); > >> + return Node; > >> + } > >> + static unsigned getHashValue(const DynTypedNode &Val) { > >> + // FIXME: Add hashing support for the remaining types. > >> + if > (ASTNodeKind::getFromNodeKind<TypeLoc>().isSame(Val.NodeKind)) { > >> + auto TL = Val.getUnchecked<TypeLoc>(); > >> + return llvm::hash_combine(TL.getType().getAsOpaquePtr(), > >> + TL.getOpaqueData()); > >> + } > >> + > >> + if > (ASTNodeKind::getFromNodeKind<NestedNameSpecifierLoc>().isSame( > >> + Val.NodeKind)) { > >> + auto NNSL = Val.getUnchecked<NestedNameSpecifierLoc>(); > >> + return llvm::hash_combine(NNSL.getNestedNameSpecifier(), > >> + NNSL.getOpaqueData()); > >> + } > >> + > >> + assert(Val.getMemoizationData()); > >> + return llvm::hash_value(Val.getMemoizationData()); > >> + } > >> + static bool isEqual(const DynTypedNode &LHS, const DynTypedNode > &RHS) > >> { > >> + auto Empty = ASTNodeKind::DenseMapInfo::getEmptyKey(); > >> + auto TombStone = ASTNodeKind::DenseMapInfo::getTombstoneKey(); > >> + return (ASTNodeKind::DenseMapInfo::isEqual(LHS.NodeKind, Empty) > && > >> + ASTNodeKind::DenseMapInfo::isEqual(RHS.NodeKind, Empty)) > || > >> + (ASTNodeKind::DenseMapInfo::isEqual(LHS.NodeKind, > TombStone) > >> && > >> + ASTNodeKind::DenseMapInfo::isEqual(RHS.NodeKind, > >> TombStone)) || > >> + LHS == RHS; > >> + } > >> + }; > >> + > >> private: > >> /// \brief Takes care of converting from and to \c T. > >> template <typename T, typename EnablerT = void> struct BaseConverter; > >> @@ -420,6 +488,10 @@ template <> > >> struct DenseMapInfo<clang::ast_type_traits::ASTNodeKind> > >> : clang::ast_type_traits::ASTNodeKind::DenseMapInfo {}; > >> > >> +template <> > >> +struct DenseMapInfo<clang::ast_type_traits::DynTypedNode> > >> + : clang::ast_type_traits::DynTypedNode::DenseMapInfo {}; > >> + > >> } // end namespace llvm > >> > >> #endif > >> > >> Modified: cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h > >> URL: > >> > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h?rev=250831&r1=250830&r2=250831&view=diff > >> > >> > ============================================================================== > >> --- cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h (original) > >> +++ cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h Tue Oct 20 > 10:08:46 > >> 2015 > >> @@ -2068,8 +2068,10 @@ internal::Matcher<T> findAll(const inter > >> /// > >> /// Usable as: Any Matcher > >> const internal::ArgumentAdaptingMatcherFunc< > >> - internal::HasParentMatcher, internal::TypeList<Decl, Stmt>, > >> - internal::TypeList<Decl, Stmt> > LLVM_ATTRIBUTE_UNUSED hasParent = > >> {}; > >> + internal::HasParentMatcher, > >> + internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc>, > >> + internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc>> > >> + LLVM_ATTRIBUTE_UNUSED hasParent = {}; > >> > >> /// \brief Matches AST nodes that have an ancestor that matches the > >> provided > >> /// matcher. > >> @@ -2083,8 +2085,10 @@ const internal::ArgumentAdaptingMatcherF > >> /// > >> /// Usable as: Any Matcher > >> const internal::ArgumentAdaptingMatcherFunc< > >> - internal::HasAncestorMatcher, internal::TypeList<Decl, Stmt>, > >> - internal::TypeList<Decl, Stmt> > LLVM_ATTRIBUTE_UNUSED hasAncestor > = > >> {}; > >> + internal::HasAncestorMatcher, > >> + internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc>, > >> + internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc>> > >> + LLVM_ATTRIBUTE_UNUSED hasAncestor = {}; > >> > >> /// \brief Matches if the provided matcher does not match. > >> /// > >> > >> Modified: cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h > >> URL: > >> > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h?rev=250831&r1=250830&r2=250831&view=diff > >> > >> > ============================================================================== > >> --- cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h (original) > >> +++ cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h Tue Oct 20 > >> 10:08:46 2015 > >> @@ -848,8 +848,10 @@ public: > >> BoundNodesTreeBuilder *Builder, > >> AncestorMatchMode MatchMode) { > >> static_assert(std::is_base_of<Decl, T>::value || > >> - std::is_base_of<Stmt, T>::value, > >> - "only Decl or Stmt allowed for recursive matching"); > >> + std::is_base_of<NestedNameSpecifierLoc, T>::value > >> || > >> + std::is_base_of<Stmt, T>::value || > >> + std::is_base_of<TypeLoc, T>::value, > >> + "type not allowed for recursive matching"); > >> return > matchesAncestorOf(ast_type_traits::DynTypedNode::create(Node), > >> Matcher, Builder, MatchMode); > >> } > >> > >> Modified: cfe/trunk/lib/AST/ASTContext.cpp > >> URL: > >> > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=250831&r1=250830&r2=250831&view=diff > >> > >> > ============================================================================== > >> --- cfe/trunk/lib/AST/ASTContext.cpp (original) > >> +++ cfe/trunk/lib/AST/ASTContext.cpp Tue Oct 20 10:08:46 2015 > >> @@ -8678,6 +8678,23 @@ bool ASTContext::AtomicUsesUnsupportedLi > >> > >> namespace { > >> > >> +/// Template specializations to abstract away from pointers and > TypeLocs. > >> +/// @{ > >> +template <typename T> > >> +ast_type_traits::DynTypedNode createDynTypedNode(const T &Node) { > >> + return ast_type_traits::DynTypedNode::create(*Node); > >> +} > >> +template <> > >> +ast_type_traits::DynTypedNode createDynTypedNode(const TypeLoc &Node) { > >> + return ast_type_traits::DynTypedNode::create(Node); > >> +} > >> +template <> > >> +ast_type_traits::DynTypedNode > >> +createDynTypedNode(const NestedNameSpecifierLoc &Node) { > >> + return ast_type_traits::DynTypedNode::create(Node); > >> +} > >> +/// @} > >> + > >> /// \brief A \c RecursiveASTVisitor that builds a map from nodes to > >> their > >> /// parents as defined by the \c RecursiveASTVisitor. > >> /// > >> @@ -8685,7 +8702,8 @@ namespace { > >> /// traversal - there are other relationships (for example > declaration > >> context) > >> /// in the AST that are better modeled by special matchers. > >> /// > >> - /// FIXME: Currently only builds up the map using \c Stmt and \c Decl > >> nodes. > >> +/// FIXME: Currently only builds up the map using \c Stmt, \c Decl, > >> +/// \c NestedNameSpecifierLoc and \c TypeLoc nodes. > >> class ParentMapASTVisitor : public > >> RecursiveASTVisitor<ParentMapASTVisitor> { > >> > >> public: > >> @@ -8717,21 +8735,11 @@ namespace { > >> } > >> > >> template <typename T> > >> - bool TraverseNode(T *Node, bool(VisitorBase:: *traverse) (T *)) { > >> + bool TraverseNode(T Node, bool (VisitorBase::*traverse)(T)) { > >> if (!Node) > >> return true; > >> if (ParentStack.size() > 0) { > >> - // FIXME: Currently we add the same parent multiple times, but > >> only > >> - // when no memoization data is available for the type. > >> - // For example when we visit all subexpressions of template > >> - // instantiations; this is suboptimal, but benign: the only way > >> to > >> - // visit those is with hasAncestor / hasParent, and those do > not > >> create > >> - // new matches. > >> - // The plan is to enable DynTypedNode to be storable in a map > or > >> hash > >> - // map. The main problem there is to implement hash functions / > >> - // comparison operators for all types that DynTypedNode > supports > >> that > >> - // do not have pointer identity. > >> - auto &NodeOrVector = (*Parents)[Node]; > >> + auto &NodeOrVector = (*Parents)[createDynTypedNode(Node)]; > >> if (NodeOrVector.isNull()) { > >> NodeOrVector = new > >> ast_type_traits::DynTypedNode(ParentStack.back()); > >> } else { > >> @@ -8757,7 +8765,7 @@ namespace { > >> Vector->push_back(ParentStack.back()); > >> } > >> } > >> - > >> ParentStack.push_back(ast_type_traits::DynTypedNode::create(*Node)); > >> + ParentStack.push_back(createDynTypedNode(Node)); > >> bool Result = (this ->* traverse) (Node); > >> ParentStack.pop_back(); > >> return Result; > >> @@ -8771,6 +8779,15 @@ namespace { > >> return TraverseNode(StmtNode, &VisitorBase::TraverseStmt); > >> } > >> > >> + bool TraverseTypeLoc(TypeLoc TypeLocNode) { > >> + return TraverseNode(TypeLocNode, &VisitorBase::TraverseTypeLoc); > >> + } > >> + > >> + bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc > >> NNSLocNode) { > >> + return TraverseNode(NNSLocNode, > >> + > &VisitorBase::TraverseNestedNameSpecifierLoc); > >> + } > >> + > >> ASTContext::ParentMap *Parents; > >> llvm::SmallVector<ast_type_traits::DynTypedNode, 16> ParentStack; > >> > >> @@ -8781,16 +8798,13 @@ namespace { > >> > >> ArrayRef<ast_type_traits::DynTypedNode> > >> ASTContext::getParents(const ast_type_traits::DynTypedNode &Node) { > >> - assert(Node.getMemoizationData() && > >> - "Invariant broken: only nodes that support memoization may be > " > >> - "used in the parent map."); > >> if (!AllParents) { > >> // We always need to run over the whole translation unit, as > >> // hasAncestor can escape any subtree. > >> AllParents.reset( > >> ParentMapASTVisitor::buildMap(*getTranslationUnitDecl())); > >> } > >> - ParentMap::const_iterator I = > >> AllParents->find(Node.getMemoizationData()); > >> + ParentMap::const_iterator I = AllParents->find(Node); > >> if (I == AllParents->end()) { > >> return None; > >> } > >> > >> Modified: cfe/trunk/lib/ASTMatchers/ASTMatchFinder.cpp > >> URL: > >> > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ASTMatchers/ASTMatchFinder.cpp?rev=250831&r1=250830&r2=250831&view=diff > >> > >> > ============================================================================== > >> --- cfe/trunk/lib/ASTMatchers/ASTMatchFinder.cpp (original) > >> +++ cfe/trunk/lib/ASTMatchers/ASTMatchFinder.cpp Tue Oct 20 10:08:46 > 2015 > >> @@ -621,9 +621,6 @@ private: > >> if (Node.get<TranslationUnitDecl>() == > >> ActiveASTContext->getTranslationUnitDecl()) > >> return false; > >> - assert(Node.getMemoizationData() && > >> - "Invariant broken: only nodes that support memoization may > be > >> " > >> - "used in the parent map."); > >> > >> MatchKey Key; > >> Key.MatcherID = Matcher.getID(); > >> @@ -867,7 +864,11 @@ bool MatchASTVisitor::TraverseNestedName > >> > >> bool MatchASTVisitor::TraverseNestedNameSpecifierLoc( > >> NestedNameSpecifierLoc NNS) { > >> + if (!NNS) > >> + return true; > >> + > >> match(NNS); > >> + > >> // We only match the nested name specifier here (as opposed to > >> traversing it) > >> // because the traversal is already done in the parallel > >> "Loc"-hierarchy. > >> if (NNS.hasQualifier()) > >> > >> Modified: cfe/trunk/unittests/AST/ASTContextParentMapTest.cpp > >> URL: > >> > http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/ASTContextParentMapTest.cpp?rev=250831&r1=250830&r2=250831&view=diff > >> > >> > ============================================================================== > >> --- cfe/trunk/unittests/AST/ASTContextParentMapTest.cpp (original) > >> +++ cfe/trunk/unittests/AST/ASTContextParentMapTest.cpp Tue Oct 20 > >> 10:08:46 2015 > >> @@ -38,6 +38,19 @@ TEST(GetParents, ReturnsParentForStmt) { > >> ifStmt(hasParent(compoundStmt())))); > >> } > >> > >> +TEST(GetParents, ReturnsParentForTypeLoc) { > >> + MatchVerifier<TypeLoc> Verifier; > >> + EXPECT_TRUE( > >> + Verifier.match("namespace a { class b {}; } void f(a::b) {}", > >> + > >> typeLoc(hasParent(typeLoc(hasParent(functionDecl())))))); > >> +} > >> + > >> +TEST(GetParents, ReturnsParentForNestedNameSpecifierLoc) { > >> + MatchVerifier<NestedNameSpecifierLoc> Verifier; > >> + EXPECT_TRUE(Verifier.match("namespace a { class b {}; } void f(a::b) > >> {}", > >> + > >> nestedNameSpecifierLoc(hasParent(typeLoc())))); > >> +} > >> + > >> TEST(GetParents, ReturnsParentInsideTemplateInstantiations) { > >> MatchVerifier<Decl> DeclVerifier; > >> EXPECT_TRUE(DeclVerifier.match( > >> > >> Modified: cfe/trunk/unittests/ASTMatchers/Dynamic/ParserTest.cpp > >> URL: > >> > http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/ASTMatchers/Dynamic/ParserTest.cpp?rev=250831&r1=250830&r2=250831&view=diff > >> > >> > ============================================================================== > >> --- cfe/trunk/unittests/ASTMatchers/Dynamic/ParserTest.cpp (original) > >> +++ cfe/trunk/unittests/ASTMatchers/Dynamic/ParserTest.cpp Tue Oct 20 > >> 10:08:46 2015 > >> @@ -318,7 +318,8 @@ TEST(ParserTest, CompletionNamedValues) > >> Comps[1].MatcherDecl); > >> > >> EXPECT_EQ("arent(", Comps[2].TypedText); > >> - EXPECT_EQ("Matcher<Decl> hasParent(Matcher<Decl|Stmt>)", > >> + EXPECT_EQ("Matcher<Decl> " > >> + > >> "hasParent(Matcher<NestedNameSpecifierLoc|TypeLoc|Decl|...>)", > >> Comps[2].MatcherDecl); > >> } > >> > >> > >> Modified: cfe/trunk/unittests/ASTMatchers/Dynamic/RegistryTest.cpp > >> URL: > >> > http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/ASTMatchers/Dynamic/RegistryTest.cpp?rev=250831&r1=250830&r2=250831&view=diff > >> > >> > ============================================================================== > >> --- cfe/trunk/unittests/ASTMatchers/Dynamic/RegistryTest.cpp (original) > >> +++ cfe/trunk/unittests/ASTMatchers/Dynamic/RegistryTest.cpp Tue Oct 20 > >> 10:08:46 2015 > >> @@ -447,8 +447,10 @@ TEST_F(RegistryTest, Errors) { > >> TEST_F(RegistryTest, Completion) { > >> CompVector Comps = getCompletions(); > >> // Overloaded > >> - EXPECT_TRUE(hasCompletion( > >> - Comps, "hasParent(", "Matcher<Decl|Stmt> > >> hasParent(Matcher<Decl|Stmt>)")); > >> + EXPECT_TRUE(hasCompletion(Comps, "hasParent(", > >> + > >> "Matcher<NestedNameSpecifierLoc|TypeLoc|Decl|...> " > >> + > >> "hasParent(Matcher<NestedNameSpecifierLoc|TypeLoc|" > >> + "Decl|...>)")); > >> // Variadic. > >> EXPECT_TRUE(hasCompletion(Comps, "whileStmt(", > >> "Matcher<Stmt> > >> whileStmt(Matcher<WhileStmt>...)")); > >> @@ -463,8 +465,10 @@ TEST_F(RegistryTest, Completion) { > >> > >> EXPECT_TRUE(hasCompletion(WhileComps, "hasBody(", > >> "Matcher<WhileStmt> > >> hasBody(Matcher<Stmt>)")); > >> - EXPECT_TRUE(hasCompletion(WhileComps, "hasParent(", > >> - "Matcher<Stmt> > >> hasParent(Matcher<Decl|Stmt>)")); > >> + EXPECT_TRUE(hasCompletion(WhileComps, "hasParent(", "Matcher<Stmt> " > >> + > >> "hasParent(Matcher<" > >> + > >> "NestedNameSpecifierLoc|" > >> + > >> "TypeLoc|Decl|...>)")); > >> EXPECT_TRUE( > >> hasCompletion(WhileComps, "allOf(", "Matcher<T> > >> allOf(Matcher<T>...)")); > >> > >> > >> > >> _______________________________________________ > >> cfe-commits mailing list > >> cfe-commits@lists.llvm.org > >> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits > > > > >
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits