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