forked from OSchip/llvm-project
Support in hasDeclaration for types with getDecl()
Re-introducing r175532. The has_getDecl metafunction didn't compile with Visual Studio. This revision 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: 176019
This commit is contained in:
parent
64c3851be6
commit
8342598d1b
|
@ -353,6 +353,23 @@ inline Matcher<T> makeMatcher(MatcherInterface<T> *Implementation) {
|
|||
return Matcher<T>(Implementation);
|
||||
}
|
||||
|
||||
/// \brief Metafunction to determine if type T has a member called getDecl.
|
||||
template <typename T> struct has_getDecl {
|
||||
struct Default { int getDecl; };
|
||||
struct Derived : T, Default { };
|
||||
|
||||
template<typename C, C> struct CheckT;
|
||||
|
||||
// If T::getDecl exists, an ambiguity arises and CheckT will
|
||||
// not be instantiable. This makes f(...) the only available
|
||||
// overload.
|
||||
template<typename C>
|
||||
static char (&f(CheckT<int Default::*, &C::getDecl>*))[1];
|
||||
template<typename C> static char (&f(...))[2];
|
||||
|
||||
static bool const value = sizeof(f<Derived>(0)) == 2;
|
||||
};
|
||||
|
||||
/// \brief Matches declarations for QualType and CallExpr.
|
||||
///
|
||||
/// Type argument DeclMatcherT is required by PolymorphicMatcherWithParam1 but
|
||||
|
@ -376,11 +393,13 @@ 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) const {
|
||||
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,
|
||||
|
@ -393,6 +412,15 @@ private:
|
|||
return matchesDecl(Node->getAsCXXRecordDecl(), Finder, Builder);
|
||||
}
|
||||
|
||||
/// \brief Gets the TemplateDecl from a TemplateSpecializationType
|
||||
/// and returns whether the inner matches on it.
|
||||
bool matchesSpecialized(const TemplateSpecializationType &Node,
|
||||
ASTMatchFinder *Finder,
|
||||
BoundNodesTreeBuilder *Builder) const {
|
||||
return matchesDecl(Node.getTemplateName().getAsTemplateDecl(),
|
||||
Finder, Buidler);
|
||||
}
|
||||
|
||||
/// \brief Extracts the Decl of the callee of a CallExpr and returns whether
|
||||
/// the inner matcher matches on it.
|
||||
bool matchesSpecialized(const CallExpr &Node, ASTMatchFinder *Finder,
|
||||
|
|
|
@ -818,6 +818,12 @@ TEST(HasDeclaration, HasDeclarationOfEnumType) {
|
|||
qualType(hasDeclaration(enumDecl(hasName("X")))))))));
|
||||
}
|
||||
|
||||
TEST(HasDeclaration, HasGetDeclTraitTest) {
|
||||
EXPECT_TRUE(internal::has_getDecl<TypedefType>::value);
|
||||
EXPECT_TRUE(internal::has_getDecl<RecordType>::value);
|
||||
EXPECT_FALSE(internal::has_getDecl<TemplateSpecializationType>::value);
|
||||
}
|
||||
|
||||
TEST(HasDeclaration, HasDeclarationOfTypeWithDecl) {
|
||||
EXPECT_TRUE(matches("typedef int X; X a;",
|
||||
varDecl(hasName("a"),
|
||||
|
|
Loading…
Reference in New Issue