From ed936457393fa19d86bd9223f815b8cead44e20d Mon Sep 17 00:00:00 2001 From: Edwin Vane Date: Mon, 25 Feb 2013 14:32:42 +0000 Subject: [PATCH] Support in hasDeclaration for types with getDecl() Re-introducing r175532. The has_getDecl metafunction didn't compile with Visual Studio. This revision uses approaches has_getDecl from a different angle that isn't a problem for Visual Studio. Added dedicated tests for the metafunction. Reviewers: klimek llvm-svn: 176024 --- .../clang/ASTMatchers/ASTMatchersInternal.h | 22 ++++++++++++++++++++-- clang/unittests/ASTMatchers/ASTMatchersTest.cpp | 6 ++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/clang/include/clang/ASTMatchers/ASTMatchersInternal.h b/clang/include/clang/ASTMatchers/ASTMatchersInternal.h index e18e325..ac85f50 100644 --- a/clang/include/clang/ASTMatchers/ASTMatchersInternal.h +++ b/clang/include/clang/ASTMatchers/ASTMatchersInternal.h @@ -353,6 +353,23 @@ inline Matcher makeMatcher(MatcherInterface *Implementation) { return Matcher(Implementation); } +/// \brief Metafunction to determine if type T has a member called getDecl. +template struct has_getDecl { + struct Default { int getDecl; }; + struct Derived : T, Default { }; + + template struct CheckT; + + // If T::getDecl exists, an ambiguity arises and CheckT will + // not be instantiable. This makes f(...) the only available + // overload. + template + static char (&f(CheckT*))[1]; + template static char (&f(...))[2]; + + static bool const value = sizeof(f(0)) == 2; +}; + /// \brief Matches declarations for QualType and CallExpr. /// /// Type argument DeclMatcherT is required by PolymorphicMatcherWithParam1 but @@ -376,8 +393,9 @@ private: /// \brief If getDecl exists as a member of U, returns whether the inner /// matcher matches Node.getDecl(). template - bool matchesSpecialized(const U &Node, ASTMatchFinder *Finder, - BoundNodesTreeBuilder *Builder) const { + bool matchesSpecialized( + const U &Node, ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder, + typename llvm::enable_if, int>::type = 0) const { return matchesDecl(Node.getDecl(), Finder, Builder); } diff --git a/clang/unittests/ASTMatchers/ASTMatchersTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersTest.cpp index 6301747..a759df9 100644 --- a/clang/unittests/ASTMatchers/ASTMatchersTest.cpp +++ b/clang/unittests/ASTMatchers/ASTMatchersTest.cpp @@ -818,6 +818,12 @@ TEST(HasDeclaration, HasDeclarationOfEnumType) { qualType(hasDeclaration(enumDecl(hasName("X"))))))))); } +TEST(HasDeclaration, HasGetDeclTraitTest) { + EXPECT_TRUE(internal::has_getDecl::value); + EXPECT_TRUE(internal::has_getDecl::value); + EXPECT_FALSE(internal::has_getDecl::value); +} + TEST(HasDeclaration, HasDeclarationOfTypeWithDecl) { EXPECT_TRUE(matches("typedef int X; X a;", varDecl(hasName("a"), -- 2.7.4