summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/ASTMatchers/ASTMatchersInternal.h28
-rw-r--r--clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp4
2 files changed, 23 insertions, 9 deletions
diff --git a/clang/include/clang/ASTMatchers/ASTMatchersInternal.h b/clang/include/clang/ASTMatchers/ASTMatchersInternal.h
index 2a85ac6c99a..cd59bbcaeb4 100644
--- a/clang/include/clang/ASTMatchers/ASTMatchersInternal.h
+++ b/clang/include/clang/ASTMatchers/ASTMatchersInternal.h
@@ -741,24 +741,34 @@ private:
/// matcher matches on it.
bool matchesSpecialized(const Type &Node, ASTMatchFinder *Finder,
BoundNodesTreeBuilder *Builder) const {
+
+ // DeducedType does not have declarations of its own, so
+ // match the deduced type instead.
+ const Type *EffectiveType = &Node;
+ if (const auto *S = dyn_cast<DeducedType>(&Node)) {
+ EffectiveType = S->getDeducedType().getTypePtrOrNull();
+ if (!EffectiveType)
+ return false;
+ }
+
// First, for any types that have a declaration, extract the declaration and
// match on it.
- if (const auto *S = dyn_cast<TagType>(&Node)) {
+ if (const auto *S = dyn_cast<TagType>(EffectiveType)) {
return matchesDecl(S->getDecl(), Finder, Builder);
}
- if (const auto *S = dyn_cast<InjectedClassNameType>(&Node)) {
+ if (const auto *S = dyn_cast<InjectedClassNameType>(EffectiveType)) {
return matchesDecl(S->getDecl(), Finder, Builder);
}
- if (const auto *S = dyn_cast<TemplateTypeParmType>(&Node)) {
+ if (const auto *S = dyn_cast<TemplateTypeParmType>(EffectiveType)) {
return matchesDecl(S->getDecl(), Finder, Builder);
}
- if (const auto *S = dyn_cast<TypedefType>(&Node)) {
+ if (const auto *S = dyn_cast<TypedefType>(EffectiveType)) {
return matchesDecl(S->getDecl(), Finder, Builder);
}
- if (const auto *S = dyn_cast<UnresolvedUsingType>(&Node)) {
+ if (const auto *S = dyn_cast<UnresolvedUsingType>(EffectiveType)) {
return matchesDecl(S->getDecl(), Finder, Builder);
}
- if (const auto *S = dyn_cast<ObjCObjectType>(&Node)) {
+ if (const auto *S = dyn_cast<ObjCObjectType>(EffectiveType)) {
return matchesDecl(S->getInterface(), Finder, Builder);
}
@@ -770,14 +780,14 @@ private:
// template<typename T> struct X { T t; } class A {}; X<A> a;
// The following matcher will match, which otherwise would not:
// fieldDecl(hasType(pointerType())).
- if (const auto *S = dyn_cast<SubstTemplateTypeParmType>(&Node)) {
+ if (const auto *S = dyn_cast<SubstTemplateTypeParmType>(EffectiveType)) {
return matchesSpecialized(S->getReplacementType(), Finder, Builder);
}
// For template specialization types, we want to match the template
// declaration, as long as the type is still dependent, and otherwise the
// declaration of the instantiated tag type.
- if (const auto *S = dyn_cast<TemplateSpecializationType>(&Node)) {
+ if (const auto *S = dyn_cast<TemplateSpecializationType>(EffectiveType)) {
if (!S->isTypeAlias() && S->isSugared()) {
// If the template is non-dependent, we want to match the instantiated
// tag type.
@@ -796,7 +806,7 @@ private:
// FIXME: We desugar elaborated types. This makes the assumption that users
// do never want to match on whether a type is elaborated - there are
// arguments for both sides; for now, continue desugaring.
- if (const auto *S = dyn_cast<ElaboratedType>(&Node)) {
+ if (const auto *S = dyn_cast<ElaboratedType>(EffectiveType)) {
return matchesSpecialized(S->desugar(), Finder, Builder);
}
return false;
diff --git a/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp
index 58c26eafd7e..712c3854c48 100644
--- a/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp
+++ b/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp
@@ -1184,6 +1184,10 @@ TEST(TypeMatching, MatchesAutoTypes) {
EXPECT_TRUE(matches("int v[] = { 2, 3 }; void f() { for (int i : v) {} }",
autoType()));
+ EXPECT_TRUE(matches("auto i = 2;", varDecl(hasType(isInteger()))));
+ EXPECT_TRUE(matches("struct X{}; auto x = X{};",
+ varDecl(hasType(recordDecl(hasName("X"))))));
+
// FIXME: Matching against the type-as-written can't work here, because the
// type as written was not deduced.
//EXPECT_TRUE(matches("auto a = 1;",
OpenPOWER on IntegriCloud