Author: fgross Date: Fri Aug 4 11:59:19 2017 New Revision: 310095 URL: http://llvm.org/viewvc/llvm-project?rev=310095&view=rev Log: [ASTMatcher] Add handling for DeducedType to HasDeclarationMatcher
HasDeclarationMatcher did not handle DeducedType, it always returned false for deduced types. So with code like this: struct X{}; auto x = X{}; This did no longer match: varDecl(hasType(recordDecl(hasName("X")))) Because HasDeclarationMatcher didn't resolve the DeducedType of x. Differential Revision: https://reviews.llvm.org/D36308 Modified: cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h cfe/trunk/unittests/ASTMatchers/ASTMatchersNodeTest.cpp Modified: cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h?rev=310095&r1=310094&r2=310095&view=diff ============================================================================== --- cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h (original) +++ cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h Fri Aug 4 11:59:19 2017 @@ -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; Modified: cfe/trunk/unittests/ASTMatchers/ASTMatchersNodeTest.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/ASTMatchers/ASTMatchersNodeTest.cpp?rev=310095&r1=310094&r2=310095&view=diff ============================================================================== --- cfe/trunk/unittests/ASTMatchers/ASTMatchersNodeTest.cpp (original) +++ cfe/trunk/unittests/ASTMatchers/ASTMatchersNodeTest.cpp Fri Aug 4 11:59:19 2017 @@ -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;", _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits