On Tue, Feb 19, 2013 at 12:14 PM, Edwin Vane <[email protected]> wrote:
> Author: revane
> Date: Tue Feb 19 11:14:34 2013
> New Revision: 175532
>
> URL: http://llvm.org/viewvc/llvm-project?rev=175532&view=rev
> Log:
> Support in hasDeclaration for types with getDecl()
>
> Using a new metafunction for detecting the presence of the member
> 'getDecl' in a type T, added support to hasDeclaration for any such type
> T. This allows hasDecl() to be replaced and enables several other
> subclasses of clang::Type to use hasDeclaration.
>
> Updated unittests and LibASTMatchersReference.html.
>
> Reviewers: klimek
>
> Modified:
>     cfe/trunk/docs/LibASTMatchersReference.html
>     cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
>     cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h
>     cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp
>
> Modified: cfe/trunk/docs/LibASTMatchersReference.html
> URL: 
> http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/LibASTMatchersReference.html?rev=175532&r1=175531&r2=175532&view=diff
> ==============================================================================
> --- cfe/trunk/docs/LibASTMatchersReference.html (original)
> +++ cfe/trunk/docs/LibASTMatchersReference.html Tue Feb 19 11:14:34 2013
> @@ -1979,12 +1979,16 @@ Usable as: Matcher&lt<a href="http://cla
>  </pre></td></tr>
>
>
> -<tr><td>Matcher&lt<a 
> href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html";>CXXConstructExpr</a>&gt;</td><td
>  class="name" onclick="toggle('hasDeclaration1')"><a 
> name="hasDeclaration1Anchor">hasDeclaration</a></td><td>Matcher&lt<a 
> href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html";>Decl</a>&gt;  
> InnerMatcher</td></tr>
> -<tr><td colspan="4" class="doc" id="hasDeclaration1"><pre>Matches a type if 
> the declaration of the type matches the given
> +<tr><td>Matcher&lt<a 
> href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html";>CXXConstructExpr</a>&gt;</td><td
>  class="name" onclick="toggle('hasDeclaration2')"><a 
> name="hasDeclaration2Anchor">hasDeclaration</a></td><td>Matcher&lt<a 
> href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html";>Decl</a>&gt;  
> InnerMatcher</td></tr>
> +<tr><td colspan="4" class="doc" id="hasDeclaration2"><pre>Matches a type if 
> the declaration of the type matches the given
>  matcher.
>
> +In addition to being usable as Matcher&lt<a 
> href="http://clang.llvm.org/doxygen/classclang_1_1TypedefType.html";>TypedefType</a>&gt;,
>  also usable as
> +Matcher&lt;T&gt; for any T supporting the getDecl() member function. e.g. 
> various
> +subtypes of clang::Type.
> +
>  Usable as: Matcher&lt<a 
> href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html";>QualType</a>&gt;,
>  Matcher&lt<a 
> href="http://clang.llvm.org/doxygen/classclang_1_1CallExpr.html";>CallExpr</a>&gt;,
>  Matcher&lt<a 
> href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html";>CXXConstructExpr</a>&gt;,
> -  Matcher&lt<a 
> href="http://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html";>MemberExpr</a>&gt;
> +  Matcher&lt<a 
> href="http://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html";>MemberExpr</a>&gt;,
>  Matcher&lt<a 
> href="http://clang.llvm.org/doxygen/classclang_1_1TypedefType.html";>TypedefType</a>&gt;
>  </pre></td></tr>
>
>
> @@ -2130,12 +2134,16 @@ Example matches y in x(y)
>  </pre></td></tr>
>
>
> -<tr><td>Matcher&lt<a 
> href="http://clang.llvm.org/doxygen/classclang_1_1CallExpr.html";>CallExpr</a>&gt;</td><td
>  class="name" onclick="toggle('hasDeclaration2')"><a 
> name="hasDeclaration2Anchor">hasDeclaration</a></td><td>Matcher&lt<a 
> href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html";>Decl</a>&gt;  
> InnerMatcher</td></tr>
> -<tr><td colspan="4" class="doc" id="hasDeclaration2"><pre>Matches a type if 
> the declaration of the type matches the given
> +<tr><td>Matcher&lt<a 
> href="http://clang.llvm.org/doxygen/classclang_1_1CallExpr.html";>CallExpr</a>&gt;</td><td
>  class="name" onclick="toggle('hasDeclaration3')"><a 
> name="hasDeclaration3Anchor">hasDeclaration</a></td><td>Matcher&lt<a 
> href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html";>Decl</a>&gt;  
> InnerMatcher</td></tr>
> +<tr><td colspan="4" class="doc" id="hasDeclaration3"><pre>Matches a type if 
> the declaration of the type matches the given
>  matcher.
>
> +In addition to being usable as Matcher&lt<a 
> href="http://clang.llvm.org/doxygen/classclang_1_1TypedefType.html";>TypedefType</a>&gt;,
>  also usable as
> +Matcher&lt;T&gt; for any T supporting the getDecl() member function. e.g. 
> various
> +subtypes of clang::Type.
> +
>  Usable as: Matcher&lt<a 
> href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html";>QualType</a>&gt;,
>  Matcher&lt<a 
> href="http://clang.llvm.org/doxygen/classclang_1_1CallExpr.html";>CallExpr</a>&gt;,
>  Matcher&lt<a 
> href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html";>CXXConstructExpr</a>&gt;,
> -  Matcher&lt<a 
> href="http://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html";>MemberExpr</a>&gt;
> +  Matcher&lt<a 
> href="http://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html";>MemberExpr</a>&gt;,
>  Matcher&lt<a 
> href="http://clang.llvm.org/doxygen/classclang_1_1TypedefType.html";>TypedefType</a>&gt;
>  </pre></td></tr>
>
>
> @@ -2523,12 +2531,16 @@ FIXME: Unit test this matcher
>  </pre></td></tr>
>
>
> -<tr><td>Matcher&lt<a 
> href="http://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html";>MemberExpr</a>&gt;</td><td
>  class="name" onclick="toggle('hasDeclaration0')"><a 
> name="hasDeclaration0Anchor">hasDeclaration</a></td><td>Matcher&lt<a 
> href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html";>Decl</a>&gt;  
> InnerMatcher</td></tr>
> -<tr><td colspan="4" class="doc" id="hasDeclaration0"><pre>Matches a type if 
> the declaration of the type matches the given
> +<tr><td>Matcher&lt<a 
> href="http://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html";>MemberExpr</a>&gt;</td><td
>  class="name" onclick="toggle('hasDeclaration1')"><a 
> name="hasDeclaration1Anchor">hasDeclaration</a></td><td>Matcher&lt<a 
> href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html";>Decl</a>&gt;  
> InnerMatcher</td></tr>
> +<tr><td colspan="4" class="doc" id="hasDeclaration1"><pre>Matches a type if 
> the declaration of the type matches the given
>  matcher.
>
> +In addition to being usable as Matcher&lt<a 
> href="http://clang.llvm.org/doxygen/classclang_1_1TypedefType.html";>TypedefType</a>&gt;,
>  also usable as
> +Matcher&lt;T&gt; for any T supporting the getDecl() member function. e.g. 
> various
> +subtypes of clang::Type.
> +
>  Usable as: Matcher&lt<a 
> href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html";>QualType</a>&gt;,
>  Matcher&lt<a 
> href="http://clang.llvm.org/doxygen/classclang_1_1CallExpr.html";>CallExpr</a>&gt;,
>  Matcher&lt<a 
> href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html";>CXXConstructExpr</a>&gt;,
> -  Matcher&lt<a 
> href="http://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html";>MemberExpr</a>&gt;
> +  Matcher&lt<a 
> href="http://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html";>MemberExpr</a>&gt;,
>  Matcher&lt<a 
> href="http://clang.llvm.org/doxygen/classclang_1_1TypedefType.html";>TypedefType</a>&gt;
>  </pre></td></tr>
>
>
> @@ -2689,12 +2701,16 @@ Usable as: Matcher&lt<a href="http://cla
>  </pre></td></tr>
>
>
> -<tr><td>Matcher&lt<a 
> href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html";>QualType</a>&gt;</td><td
>  class="name" onclick="toggle('hasDeclaration3')"><a 
> name="hasDeclaration3Anchor">hasDeclaration</a></td><td>Matcher&lt<a 
> href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html";>Decl</a>&gt;  
> InnerMatcher</td></tr>
> -<tr><td colspan="4" class="doc" id="hasDeclaration3"><pre>Matches a type if 
> the declaration of the type matches the given
> +<tr><td>Matcher&lt<a 
> href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html";>QualType</a>&gt;</td><td
>  class="name" onclick="toggle('hasDeclaration4')"><a 
> name="hasDeclaration4Anchor">hasDeclaration</a></td><td>Matcher&lt<a 
> href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html";>Decl</a>&gt;  
> InnerMatcher</td></tr>
> +<tr><td colspan="4" class="doc" id="hasDeclaration4"><pre>Matches a type if 
> the declaration of the type matches the given
>  matcher.
>
> +In addition to being usable as Matcher&lt<a 
> href="http://clang.llvm.org/doxygen/classclang_1_1TypedefType.html";>TypedefType</a>&gt;,
>  also usable as
> +Matcher&lt;T&gt; for any T supporting the getDecl() member function. e.g. 
> various
> +subtypes of clang::Type.
> +
>  Usable as: Matcher&lt<a 
> href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html";>QualType</a>&gt;,
>  Matcher&lt<a 
> href="http://clang.llvm.org/doxygen/classclang_1_1CallExpr.html";>CallExpr</a>&gt;,
>  Matcher&lt<a 
> href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html";>CXXConstructExpr</a>&gt;,
> -  Matcher&lt<a 
> href="http://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html";>MemberExpr</a>&gt;
> +  Matcher&lt<a 
> href="http://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html";>MemberExpr</a>&gt;,
>  Matcher&lt<a 
> href="http://clang.llvm.org/doxygen/classclang_1_1TypedefType.html";>TypedefType</a>&gt;
>  </pre></td></tr>
>
>
> @@ -2785,9 +2801,16 @@ QualType-matcher matches.
>  </pre></td></tr>
>
>
> -<tr><td>Matcher&lt<a 
> href="http://clang.llvm.org/doxygen/classclang_1_1TypedefType.html";>TypedefType</a>&gt;</td><td
>  class="name" onclick="toggle('hasDecl0')"><a 
> name="hasDecl0Anchor">hasDecl</a></td><td>Matcher&lt<a 
> href="http://clang.llvm.org/doxygen/classclang_1_1TypedefNameDecl.html";>TypedefNameDecl</a>&gt;
>  InnerMatcher</td></tr>
> -<tr><td colspan="4" class="doc" id="hasDecl0"><pre>Matches TypedefTypes 
> referring to a specific
> -TypedefNameDecl.
> +<tr><td>Matcher&lt<a 
> href="http://clang.llvm.org/doxygen/classclang_1_1TypedefType.html";>TypedefType</a>&gt;</td><td
>  class="name" onclick="toggle('hasDeclaration0')"><a 
> name="hasDeclaration0Anchor">hasDeclaration</a></td><td>Matcher&lt<a 
> href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html";>Decl</a>&gt;  
> InnerMatcher</td></tr>
> +<tr><td colspan="4" class="doc" id="hasDeclaration0"><pre>Matches a type if 
> the declaration of the type matches the given
> +matcher.
> +
> +In addition to being usable as Matcher&lt<a 
> href="http://clang.llvm.org/doxygen/classclang_1_1TypedefType.html";>TypedefType</a>&gt;,
>  also usable as
> +Matcher&lt;T&gt; for any T supporting the getDecl() member function. e.g. 
> various
> +subtypes of clang::Type.
> +
> +Usable as: Matcher&lt<a 
> href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html";>QualType</a>&gt;,
>  Matcher&lt<a 
> href="http://clang.llvm.org/doxygen/classclang_1_1CallExpr.html";>CallExpr</a>&gt;,
>  Matcher&lt<a 
> href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html";>CXXConstructExpr</a>&gt;,
> +  Matcher&lt<a 
> href="http://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html";>MemberExpr</a>&gt;,
>  Matcher&lt<a 
> href="http://clang.llvm.org/doxygen/classclang_1_1TypedefType.html";>TypedefType</a>&gt;
>  </pre></td></tr>
>
>
>
> Modified: cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
> URL: 
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h?rev=175532&r1=175531&r2=175532&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h (original)
> +++ cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h Tue Feb 19 11:14:34 2013
> @@ -1561,8 +1561,12 @@ unless(const M &InnerMatcher) {
>  /// \brief Matches a type if the declaration of the type matches the given
>  /// matcher.
>  ///
> +/// In addition to being usable as Matcher<TypedefType>, also usable as
> +/// Matcher<T> for any T supporting the getDecl() member function. e.g. 
> various
> +/// subtypes of clang::Type.
> +///
>  /// Usable as: Matcher<QualType>, Matcher<CallExpr>, 
> Matcher<CXXConstructExpr>,
> -///   Matcher<MemberExpr>
> +///   Matcher<MemberExpr>, Matcher<TypedefType>
>  inline internal::PolymorphicMatcherWithParam1< 
> internal::HasDeclarationMatcher,
>                                       internal::Matcher<Decl> >
>      hasDeclaration(const internal::Matcher<Decl> &InnerMatcher) {
> @@ -2846,13 +2850,6 @@ AST_TYPELOC_TRAVERSE_MATCHER(pointee, ge
>  ///   matches "typedef int X"
>  AST_TYPE_MATCHER(TypedefType, typedefType);
>
> -/// \brief Matches \c TypedefTypes referring to a specific
> -/// \c TypedefNameDecl.
> -AST_MATCHER_P(TypedefType, hasDecl,
> -              internal::Matcher<TypedefNameDecl>, InnerMatcher) {
> -  return InnerMatcher.matches(*Node.getDecl(), Finder, Builder);
> -}
> -
>  /// \brief Matches nested name specifiers.
>  ///
>  /// Given
>
> Modified: cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h
> URL: 
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h?rev=175532&r1=175531&r2=175532&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h (original)
> +++ cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h Tue Feb 19 
> 11:14:34 2013
> @@ -353,6 +353,18 @@ inline Matcher<T> makeMatcher(MatcherInt
>    return Matcher<T>(Implementation);
>  }
>
> +/// \brief Metafunction to determine if type T has a member called getDecl.
> +template <typename T> struct has_getDecl {
> +  typedef char yes[1];
> +  typedef char no[2];
> +
> +  template <typename TestType>
> +  static yes &test(char[sizeof(&TestType::getDecl)]);
> +  template <typename> static no &test(...);
> +
> +  static bool const value = sizeof(test<T>(0)) == sizeof(yes);

Unfortunately, this breaks the MSVC build.  Declarations which contain
a getDecl call cause: error C2070: 'overloaded-function': illegal
sizeof operand

This happens in both MSVC 10 and 11, and can be reproduced with a
simple test app:

#include <stdio.h>

class c {
public:
  void getDecl() {}
};

template <typename T> struct has_getDecl {
  typedef char yes[1];
  typedef char no[2];

  template <typename TestType>
  static yes &test(char[sizeof(&TestType::getDecl)]);
  template <typename> static no &test(...);

  static bool const value = sizeof(test<T>(0)) == sizeof(yes);
};

int main( void ) {
  if (has_getDecl< c >::value)
    ::printf( "yes\n" );

  return 0;
}

~Aaron

_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to