<div dir="ltr">Hi Edwin,<div><br></div><div style>You have probably seen the email from the buildbot about the broken ARM build.</div><div style><br></div><div style>I had a look at the file and I don't understand how "int i" can match a structure or a class, but since the test is full of define goodness, and it's quite late around here, so I gave up quite quickly. ;) </div>
<div style><br></div><div style>If you have any idea why that would happen, please have a look, it seems to only be breaking on ARM, so no fun trying to find out what happened without proper hardware.</div><div style><br>
</div><div style>Let me know if you need something...</div><div style><br></div><div style>cheers,</div><div style>--renato</div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On 25 February 2013 20:43, Edwin Vane <span dir="ltr"><<a href="mailto:edwin.vane@intel.com" target="_blank">edwin.vane@intel.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: revane<br>
Date: Mon Feb 25 14:43:32 2013<br>
New Revision: 176047<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=176047&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=176047&view=rev</a><br>
Log:<br>
Various additions to ASTMatcher library:<br>
<br>
New type matchers:<br>
* recordType<br>
* elaboratedType<br>
<br>
New narrowing matchers:<br>
* hasQualifier<br>
* namesType<br>
* hasDeclContext<br>
<br>
Added tests and updated LibASTMatchersReference.<br>
<br>
Reviewers: klimek<br>
<br>
Modified:<br>
    cfe/trunk/docs/LibASTMatchersReference.html<br>
    cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h<br>
    cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp<br>
<br>
Modified: cfe/trunk/docs/LibASTMatchersReference.html<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/LibASTMatchersReference.html?rev=176047&r1=176046&r2=176047&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/LibASTMatchersReference.html?rev=176047&r1=176046&r2=176047&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/docs/LibASTMatchersReference.html (original)<br>
+++ cfe/trunk/docs/LibASTMatchersReference.html Mon Feb 25 14:43:32 2013<br>
@@ -930,6 +930,26 @@ dependentSizedArrayType<br>
 </pre></td></tr><br>
<br>
<br>
+<tr><td>Matcher&lt<a href="<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html" target="_blank">http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html</a>">TypeLoc</a>&gt;</td><td class="name" onclick="toggle('elaboratedTypeLoc0')"><a name="elaboratedTypeLoc0Anchor">elaboratedTypeLoc</a></td><td>Matcher&lt<a href="<a href="http://clang.llvm.org/doxygen/classclang_1_1ElaboratedTypeLoc.html" target="_blank">http://clang.llvm.org/doxygen/classclang_1_1ElaboratedTypeLoc.html</a>">ElaboratedTypeLoc</a>&gt;...</td></tr><br>

+<tr><td colspan="4" class="doc" id="elaboratedTypeLoc0"><pre>Matches types specified with an elaborated type keyword or with a<br>
+qualified name.<br>
+<br>
+Given<br>
+  namespace N {<br>
+    namespace M {<br>
+      class D {};<br>
+    }<br>
+  }<br>
+  class C {};<br>
+<br>
+  class C c;<br>
+  N::M::D d;<br>
+<br>
+elaboratedType() matches the type of the variable declarations of both<br>
+c and d.<br>
+</pre></td></tr><br>
+<br>
+<br>
 <tr><td>Matcher&lt<a href="<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html" target="_blank">http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html</a>">TypeLoc</a>&gt;</td><td class="name" onclick="toggle('functionTypeLoc0')"><a name="functionTypeLoc0Anchor">functionTypeLoc</a></td><td>Matcher&lt<a href="<a href="http://clang.llvm.org/doxygen/classclang_1_1FunctionTypeLoc.html" target="_blank">http://clang.llvm.org/doxygen/classclang_1_1FunctionTypeLoc.html</a>">FunctionTypeLoc</a>&gt;...</td></tr><br>

 <tr><td colspan="4" class="doc" id="functionTypeLoc0"><pre>Matches FunctionType nodes.<br>
<br>
@@ -975,6 +995,21 @@ pointerType()<br>
 </pre></td></tr><br>
<br>
<br>
+<tr><td>Matcher&lt<a href="<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html" target="_blank">http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html</a>">TypeLoc</a>&gt;</td><td class="name" onclick="toggle('recordTypeLoc0')"><a name="recordTypeLoc0Anchor">recordTypeLoc</a></td><td>Matcher&lt<a href="<a href="http://clang.llvm.org/doxygen/classclang_1_1RecordTypeLoc.html" target="_blank">http://clang.llvm.org/doxygen/classclang_1_1RecordTypeLoc.html</a>">RecordTypeLoc</a>&gt;...</td></tr><br>

+<tr><td colspan="4" class="doc" id="recordTypeLoc0"><pre>Matches record types (e.g. structs, classes).<br>
+<br>
+Given<br>
+  class C {};<br>
+  struct S {};<br>
+<br>
+  C c;<br>
+  S s;<br>
+<br>
+recordType() matches the type of the variable declarations of both c<br>
+and s.<br>
+</pre></td></tr><br>
+<br>
+<br>
 <tr><td>Matcher&lt<a href="<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html" target="_blank">http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html</a>">TypeLoc</a>&gt;</td><td class="name" onclick="toggle('referenceTypeLoc0')"><a name="referenceTypeLoc0Anchor">referenceTypeLoc</a></td><td>Matcher&lt<a href="<a href="http://clang.llvm.org/doxygen/classclang_1_1ReferenceTypeLoc.html" target="_blank">http://clang.llvm.org/doxygen/classclang_1_1ReferenceTypeLoc.html</a>">ReferenceTypeLoc</a>&gt;...</td></tr><br>

 <tr><td colspan="4" class="doc" id="referenceTypeLoc0"><pre>Matches reference types.<br>
<br>
@@ -1124,6 +1159,26 @@ dependentSizedArrayType<br>
 </pre></td></tr><br>
<br>
<br>
+<tr><td>Matcher&lt<a href="<a href="http://clang.llvm.org/doxygen/classclang_1_1Type.html" target="_blank">http://clang.llvm.org/doxygen/classclang_1_1Type.html</a>">Type</a>&gt;</td><td class="name" onclick="toggle('elaboratedType0')"><a name="elaboratedType0Anchor">elaboratedType</a></td><td>Matcher&lt<a href="<a href="http://clang.llvm.org/doxygen/classclang_1_1ElaboratedType.html" target="_blank">http://clang.llvm.org/doxygen/classclang_1_1ElaboratedType.html</a>">ElaboratedType</a>&gt;...</td></tr><br>

+<tr><td colspan="4" class="doc" id="elaboratedType0"><pre>Matches types specified with an elaborated type keyword or with a<br>
+qualified name.<br>
+<br>
+Given<br>
+  namespace N {<br>
+    namespace M {<br>
+      class D {};<br>
+    }<br>
+  }<br>
+  class C {};<br>
+<br>
+  class C c;<br>
+  N::M::D d;<br>
+<br>
+elaboratedType() matches the type of the variable declarations of both<br>
+c and d.<br>
+</pre></td></tr><br>
+<br>
+<br>
 <tr><td>Matcher&lt<a href="<a href="http://clang.llvm.org/doxygen/classclang_1_1Type.html" target="_blank">http://clang.llvm.org/doxygen/classclang_1_1Type.html</a>">Type</a>&gt;</td><td class="name" onclick="toggle('functionType0')"><a name="functionType0Anchor">functionType</a></td><td>Matcher&lt<a href="<a href="http://clang.llvm.org/doxygen/classclang_1_1FunctionType.html" target="_blank">http://clang.llvm.org/doxygen/classclang_1_1FunctionType.html</a>">FunctionType</a>&gt;...</td></tr><br>

 <tr><td colspan="4" class="doc" id="functionType0"><pre>Matches FunctionType nodes.<br>
<br>
@@ -1169,6 +1224,21 @@ pointerType()<br>
 </pre></td></tr><br>
<br>
<br>
+<tr><td>Matcher&lt<a href="<a href="http://clang.llvm.org/doxygen/classclang_1_1Type.html" target="_blank">http://clang.llvm.org/doxygen/classclang_1_1Type.html</a>">Type</a>&gt;</td><td class="name" onclick="toggle('recordType0')"><a name="recordType0Anchor">recordType</a></td><td>Matcher&lt<a href="<a href="http://clang.llvm.org/doxygen/classclang_1_1RecordType.html" target="_blank">http://clang.llvm.org/doxygen/classclang_1_1RecordType.html</a>">RecordType</a>&gt;...</td></tr><br>

+<tr><td colspan="4" class="doc" id="recordType0"><pre>Matches record types (e.g. structs, classes).<br>
+<br>
+Given<br>
+  class C {};<br>
+  struct S {};<br>
+<br>
+  C c;<br>
+  S s;<br>
+<br>
+recordType() matches the type of the variable declarations of both c<br>
+and s.<br>
+</pre></td></tr><br>
+<br>
+<br>
 <tr><td>Matcher&lt<a href="<a href="http://clang.llvm.org/doxygen/classclang_1_1Type.html" target="_blank">http://clang.llvm.org/doxygen/classclang_1_1Type.html</a>">Type</a>&gt;</td><td class="name" onclick="toggle('referenceType0')"><a name="referenceType0Anchor">referenceType</a></td><td>Matcher&lt<a href="<a href="http://clang.llvm.org/doxygen/classclang_1_1ReferenceType.html" target="_blank">http://clang.llvm.org/doxygen/classclang_1_1ReferenceType.html</a>">ReferenceType</a>&gt;...</td></tr><br>

 <tr><td colspan="4" class="doc" id="referenceType0"><pre>Matches reference types.<br>
<br>
@@ -2399,6 +2469,22 @@ declStmt(hasSingleDecl(anything()))<br>
 </pre></td></tr><br>
<br>
<br>
+<tr><td>Matcher&lt<a href="<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html" target="_blank">http://clang.llvm.org/doxygen/classclang_1_1Decl.html</a>">Decl</a>&gt;</td><td class="name" onclick="toggle('hasDeclContext0')"><a name="hasDeclContext0Anchor">hasDeclContext</a></td><td>Matcher&lt<a href="<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html" target="_blank">http://clang.llvm.org/doxygen/classclang_1_1Decl.html</a>">Decl</a>&gt; InnerMatcher</td></tr><br>

+<tr><td colspan="4" class="doc" id="hasDeclContext0"><pre>Matches declarations whose declaration context, interpreted as a<br>
+Decl, matches InnerMatcher.<br>
+<br>
+Given<br>
+  namespace N {<br>
+    namespace M {<br>
+      class D {};<br>
+    }<br>
+  }<br>
+<br>
+recordDecl(hasDeclContext(namedDecl(hasName("M")))) matches the<br>
+declaration of class D.<br>
+</pre></td></tr><br>
+<br>
+<br>
 <tr><td>Matcher&lt<a href="<a href="http://clang.llvm.org/doxygen/classclang_1_1DoStmt.html" target="_blank">http://clang.llvm.org/doxygen/classclang_1_1DoStmt.html</a>">DoStmt</a>&gt;</td><td class="name" onclick="toggle('hasBody0')"><a name="hasBody0Anchor">hasBody</a></td><td>Matcher&lt<a href="<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html" target="_blank">http://clang.llvm.org/doxygen/classclang_1_1Stmt.html</a>">Stmt</a>&gt; InnerMatcher</td></tr><br>

 <tr><td colspan="4" class="doc" id="hasBody0"><pre>Matches a 'for', 'while', or 'do while' statement that has<br>
 a given body.<br>
@@ -2421,6 +2507,40 @@ Example matches true (matcher = hasCondi<br>
 </pre></td></tr><br>
<br>
<br>
+<tr><td>Matcher&lt<a href="<a href="http://clang.llvm.org/doxygen/classclang_1_1ElaboratedType.html" target="_blank">http://clang.llvm.org/doxygen/classclang_1_1ElaboratedType.html</a>">ElaboratedType</a>&gt;</td><td class="name" onclick="toggle('hasQualifier0')"><a name="hasQualifier0Anchor">hasQualifier</a></td><td>Matcher&lt<a href="<a href="http://clang.llvm.org/doxygen/classclang_1_1NestedNameSpecifier.html" target="_blank">http://clang.llvm.org/doxygen/classclang_1_1NestedNameSpecifier.html</a>">NestedNameSpecifier</a>&gt; InnerMatcher</td></tr><br>

+<tr><td colspan="4" class="doc" id="hasQualifier0"><pre>Matches ElaboratedTypes whose qualifier, a NestedNameSpecifier,<br>
+matches InnerMatcher.<br>
+<br>
+Given<br>
+  namespace N {<br>
+    namespace M {<br>
+      class D {};<br>
+    }<br>
+  }<br>
+  N::M::D d;<br>
+<br>
+elaboratedType(hasQualifier(hasPrefix(specifiesNamespace(hasName("N"))))<br>
+matches the type of the variable declaration of d.<br>
+</pre></td></tr><br>
+<br>
+<br>
+<tr><td>Matcher&lt<a href="<a href="http://clang.llvm.org/doxygen/classclang_1_1ElaboratedType.html" target="_blank">http://clang.llvm.org/doxygen/classclang_1_1ElaboratedType.html</a>">ElaboratedType</a>&gt;</td><td class="name" onclick="toggle('namesType0')"><a name="namesType0Anchor">namesType</a></td><td>Matcher&lt<a href="<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html" target="_blank">http://clang.llvm.org/doxygen/classclang_1_1QualType.html</a>">QualType</a>&gt; InnerMatcher</td></tr><br>

+<tr><td colspan="4" class="doc" id="namesType0"><pre>Matches ElaboratedTypes whose named type matches InnerMatcher.<br>
+<br>
+Given<br>
+  namespace N {<br>
+    namespace M {<br>
+      class D {};<br>
+    }<br>
+  }<br>
+  N::M::D d;<br>
+<br>
+elaboratedType(namesType(recordType(<br>
+hasDeclaration(namedDecl(hasName("D")))))) matches the type of the variable<br>
+declaration of d.<br>
+</pre></td></tr><br>
+<br>
+<br>
 <tr><td>Matcher&lt<a href="<a href="http://clang.llvm.org/doxygen/classclang_1_1ExplicitCastExpr.html" target="_blank">http://clang.llvm.org/doxygen/classclang_1_1ExplicitCastExpr.html</a>">ExplicitCastExpr</a>&gt;</td><td class="name" onclick="toggle('hasDestinationType0')"><a name="hasDestinationType0Anchor">hasDestinationType</a></td><td>Matcher&lt<a href="<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html" target="_blank">http://clang.llvm.org/doxygen/classclang_1_1QualType.html</a>">QualType</a>&gt; InnerMatcher</td></tr><br>

 <tr><td colspan="4" class="doc" id="hasDestinationType0"><pre>Matches casts whose destination type matches a given matcher.<br>
<br>
<br>
Modified: cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h?rev=176047&r1=176046&r2=176047&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h?rev=176047&r1=176046&r2=176047&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h (original)<br>
+++ cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h Mon Feb 25 14:43:32 2013<br>
@@ -2929,6 +2929,100 @@ AST_TYPE_MATCHER(TypedefType, typedefTyp<br>
 /// instantiation in \c A and the type of the variable declaration in \c B.<br>
 AST_TYPE_MATCHER(TemplateSpecializationType, templateSpecializationType);<br>
<br>
+/// \brief Matches record types (e.g. structs, classes).<br>
+///<br>
+/// Given<br>
+/// \code<br>
+///   class C {};<br>
+///   struct S {};<br>
+///<br>
+///   C c;<br>
+///   S s;<br>
+/// \code<br>
+///<br>
+/// \c recordType() matches the type of the variable declarations of both \c c<br>
+/// and \c s.<br>
+AST_TYPE_MATCHER(RecordType, recordType);<br>
+<br>
+/// \brief Matches types specified with an elaborated type keyword or with a<br>
+/// qualified name.<br>
+///<br>
+/// Given<br>
+/// \code<br>
+///   namespace N {<br>
+///     namespace M {<br>
+///       class D {};<br>
+///     }<br>
+///   }<br>
+///   class C {};<br>
+///<br>
+///   class C c;<br>
+///   N::M::D d;<br>
+/// \code<br>
+///<br>
+/// \c elaboratedType() matches the type of the variable declarations of both<br>
+/// \c c and \c d.<br>
+AST_TYPE_MATCHER(ElaboratedType, elaboratedType);<br>
+<br>
+/// \brief Matches ElaboratedTypes whose qualifier, a NestedNameSpecifier,<br>
+/// matches \c InnerMatcher.<br>
+///<br>
+/// Given<br>
+/// \code<br>
+///   namespace N {<br>
+///     namespace M {<br>
+///       class D {};<br>
+///     }<br>
+///   }<br>
+///   N::M::D d;<br>
+/// \code<br>
+///<br>
+/// \c elaboratedType(hasQualifier(hasPrefix(specifiesNamespace(hasName("N"))))<br>
+/// matches the type of the variable declaration of \c d.<br>
+AST_MATCHER_P(ElaboratedType, hasQualifier,<br>
+              internal::Matcher<NestedNameSpecifier>, InnerMatcher) {<br>
+  return InnerMatcher.matches(*Node.getQualifier(), Finder, Builder);<br>
+}<br>
+<br>
+/// \brief Matches ElaboratedTypes whose named type matches \c InnerMatcher.<br>
+///<br>
+/// Given<br>
+/// \code<br>
+///   namespace N {<br>
+///     namespace M {<br>
+///       class D {};<br>
+///     }<br>
+///   }<br>
+///   N::M::D d;<br>
+/// \code<br>
+///<br>
+/// \c elaboratedType(namesType(recordType(<br>
+/// hasDeclaration(namedDecl(hasName("D")))))) matches the type of the variable<br>
+/// declaration of \c d.<br>
+AST_MATCHER_P(ElaboratedType, namesType, internal::Matcher<QualType>,<br>
+              InnerMatcher) {<br>
+  return InnerMatcher.matches(Node.getNamedType(), Finder, Builder);<br>
+}<br>
+<br>
+/// \brief Matches declarations whose declaration context, interpreted as a<br>
+/// Decl, matches \c InnerMatcher.<br>
+///<br>
+/// Given<br>
+/// \code<br>
+///   namespace N {<br>
+///     namespace M {<br>
+///       class D {};<br>
+///     }<br>
+///   }<br>
+/// \code<br>
+///<br>
+/// \c recordDecl(hasDeclContext(namedDecl(hasName("M")))) matches the<br>
+/// declaration of \c class \c D.<br>
+AST_MATCHER_P(Decl, hasDeclContext, internal::Matcher<Decl>, InnerMatcher) {<br>
+  return InnerMatcher.matches(*Decl::castFromDeclContext(Node.getDeclContext()),<br>
+                              Finder, Builder);<br>
+}<br>
+<br>
 /// \brief Matches nested name specifiers.<br>
 ///<br>
 /// Given<br>
<br>
Modified: cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp?rev=176047&r1=176046&r2=176047&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp?rev=176047&r1=176046&r2=176047&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp (original)<br>
+++ cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp Mon Feb 25 14:43:32 2013<br>
@@ -323,6 +323,23 @@ TEST(DeclarationMatcher, ClassDerivedFro<br>
      recordDecl(hasName("B"), isDerivedFrom(recordDecl()))));<br>
 }<br>
<br>
+TEST(DeclarationMatcher, hasDeclContext) {<br>
+  EXPECT_TRUE(matches(<br>
+      "namespace N {"<br>
+      "  namespace M {"<br>
+      "    class D {};"<br>
+      "  }"<br>
+      "}",<br>
+      recordDecl(hasDeclContext(namedDecl(hasName("M"))))));<br>
+  EXPECT_TRUE(notMatches(<br>
+      "namespace N {"<br>
+      "  namespace M {"<br>
+      "    class D {};"<br>
+      "  }"<br>
+      "}",<br>
+      recordDecl(hasDeclContext(namedDecl(hasName("N"))))));<br>
+}<br>
+<br>
 TEST(ClassTemplate, DoesNotMatchClass) {<br>
   DeclarationMatcher ClassX = classTemplateDecl(hasName("X"));<br>
   EXPECT_TRUE(notMatches("class X;", ClassX));<br>
@@ -3413,10 +3430,63 @@ TEST(TypeMatching, MatchesTypedefTypes)<br>
 }<br>
<br>
 TEST(TypeMatching, MatchesTemplateSpecializationType) {<br>
-  EXPECT_TRUE(matches("template <typename T> class A{}; A<int>a;",<br>
+  EXPECT_TRUE(matches("template <typename T> class A{}; A<int> a;",<br>
                       templateSpecializationType()));<br>
 }<br>
<br>
+TEST(TypeMatching, MatchesRecordType) {<br>
+  EXPECT_TRUE(matches("class C{}; C c;", recordType()));<br>
+  EXPECT_TRUE(matches("struct S{}; S s;", recordType()));<br>
+  EXPECT_TRUE(notMatches("int i;", recordType()));<br>
+}<br>
+<br>
+TEST(TypeMatching, MatchesElaboratedType) {<br>
+  EXPECT_TRUE(matches(<br>
+    "namespace N {"<br>
+    "  namespace M {"<br>
+    "    class D {};"<br>
+    "  }"<br>
+    "}"<br>
+    "N::M::D d;", elaboratedType()));<br>
+  EXPECT_TRUE(matches("class C {} c;", elaboratedType()));<br>
+  EXPECT_TRUE(notMatches("class C {}; C c;", elaboratedType()));<br>
+}<br>
+<br>
+TEST(ElaboratedTypeNarrowing, hasQualifier) {<br>
+  EXPECT_TRUE(matches(<br>
+    "namespace N {"<br>
+    "  namespace M {"<br>
+    "    class D {};"<br>
+    "  }"<br>
+    "}"<br>
+    "N::M::D d;",<br>
+    elaboratedType(hasQualifier(hasPrefix(specifiesNamespace(hasName("N")))))));<br>
+  EXPECT_TRUE(notMatches(<br>
+    "namespace M {"<br>
+    "  class D {};"<br>
+    "}"<br>
+    "M::D d;",<br>
+    elaboratedType(hasQualifier(hasPrefix(specifiesNamespace(hasName("N")))))));<br>
+}<br>
+<br>
+TEST(ElaboratedTypeNarrowing, namesType) {<br>
+  EXPECT_TRUE(matches(<br>
+    "namespace N {"<br>
+    "  namespace M {"<br>
+    "    class D {};"<br>
+    "  }"<br>
+    "}"<br>
+    "N::M::D d;",<br>
+    elaboratedType(elaboratedType(namesType(recordType(<br>
+        hasDeclaration(namedDecl(hasName("D")))))))));<br>
+  EXPECT_TRUE(notMatches(<br>
+    "namespace M {"<br>
+    "  class D {};"<br>
+    "}"<br>
+    "M::D d;",<br>
+    elaboratedType(elaboratedType(namesType(typedefType())))));<br>
+}<br>
+<br>
 TEST(NNS, MatchesNestedNameSpecifiers) {<br>
   EXPECT_TRUE(matches("namespace ns { struct A {}; } ns::A a;",<br>
                       nestedNameSpecifier()));<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div>