[PATCH] Support in hasDeclaration for types with getDecl()
Edwin Vane
edwin.vane at intel.com
Sun Feb 17 08:03:52 PST 2013
Hi klimek, gribozavr,
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.
http://llvm-reviews.chandlerc.com/D417
Files:
include/clang/ASTMatchers/ASTMatchers.h
include/clang/ASTMatchers/ASTMatchersInternal.h
unittests/ASTMatchers/ASTMatchersTest.cpp
Index: include/clang/ASTMatchers/ASTMatchers.h
===================================================================
--- include/clang/ASTMatchers/ASTMatchers.h
+++ include/clang/ASTMatchers/ASTMatchers.h
@@ -52,6 +52,9 @@
#include "llvm/Support/Regex.h"
#include <iterator>
+#include "clang/Basic/LangOptions.h"
+#include "llvm/Support/raw_ostream.h"
+
namespace clang {
namespace ast_matchers {
@@ -1562,7 +1565,8 @@
/// matcher.
///
/// Usable as: Matcher<QualType>, Matcher<CallExpr>, Matcher<CXXConstructExpr>,
-/// Matcher<MemberExpr>
+/// Matcher<MemberExpr>, Matcher<T> where T has the getDecl() member (e.g.
+/// various subclasses of clang::Type).
inline internal::PolymorphicMatcherWithParam1< internal::HasDeclarationMatcher,
internal::Matcher<Decl> >
hasDeclaration(const internal::Matcher<Decl> &InnerMatcher) {
@@ -2846,13 +2850,6 @@
/// 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
@@ -2927,6 +2924,7 @@
internal::Matcher<NestedNameSpecifier>, InnerMatcher,
0) {
NestedNameSpecifier *NextNode = Node.getPrefix();
+ LangOptions opts;
if (NextNode == NULL)
return false;
return InnerMatcher.matches(*NextNode, Finder, Builder);
Index: include/clang/ASTMatchers/ASTMatchersInternal.h
===================================================================
--- include/clang/ASTMatchers/ASTMatchersInternal.h
+++ include/clang/ASTMatchers/ASTMatchersInternal.h
@@ -353,6 +353,18 @@
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);
+};
+
/// \brief Matches declarations for QualType and CallExpr.
///
/// Type argument DeclMatcherT is required by PolymorphicMatcherWithParam1 but
@@ -373,6 +385,15 @@
}
private:
+ /// \brief If getDecl exists as a member of U, returns whether the inner
+ /// matcher matches Node.getDecl().
+ template <typename U>
+ bool matchesSpecialized(
+ const U &Node, ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder,
+ typename llvm::enable_if<has_getDecl<U>, int>::type = 0) const {
+ return matchesDecl(Node.getDecl(), Finder, Builder);
+ }
+
/// \brief Extracts the CXXRecordDecl or EnumDecl of a QualType and returns
/// whether the inner matcher matches on it.
bool matchesSpecialized(const QualType &Node, ASTMatchFinder *Finder,
Index: unittests/ASTMatchers/ASTMatchersTest.cpp
===================================================================
--- unittests/ASTMatchers/ASTMatchersTest.cpp
+++ unittests/ASTMatchers/ASTMatchersTest.cpp
@@ -816,6 +816,10 @@
EXPECT_TRUE(matches("enum X {}; void y(X *x) { x; }",
expr(hasType(pointsTo(
qualType(hasDeclaration(enumDecl(hasName("X")))))))));
+
+ EXPECT_TRUE(matches("typedef int X; X a;",
+ varDecl(hasName("a"),
+ hasType(typedefType(hasDeclaration(decl()))))));
}
TEST(HasType, TakesQualTypeMatcherAndMatchesExpr) {
@@ -3350,10 +3354,6 @@
TEST(TypeMatching, MatchesTypedefTypes) {
EXPECT_TRUE(matches("typedef int X; X a;", varDecl(hasName("a"),
hasType(typedefType()))));
-
- EXPECT_TRUE(matches("typedef int X; X a;",
- varDecl(hasName("a"),
- hasType(typedefType(hasDecl(decl()))))));
}
TEST(NNS, MatchesNestedNameSpecifiers) {
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D417.1.patch
Type: text/x-patch
Size: 4118 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130217/ac2c7a7e/attachment.bin>
More information about the cfe-commits
mailing list