aaron.ballman added inline comments. ================ Comment at: unittests/ASTMatchers/ASTMatchersTest.cpp:4994 @@ +4993,3 @@ + EXPECT_TRUE(matches("typedef int hasUnderlyingTypeTest;", + typedefDecl(hasUnderlyingType(asString("int"))))); + EXPECT_TRUE(matches("typedef const int T;", ---------------- LegalizeAdulthood wrote: > aaron.ballman wrote: > > Thank you for those examples! Given the following code: > > ``` > > typedef int foo; > > typedef foo bar; > > > > bar i; > > ``` > > clang-query> match varDecl(hasType(asString("int"))) > > 0 matches. > > clang-query> match varDecl(hasType(asString("foo"))) > > 0 matches. > > clang-query> match varDecl(hasType(asString("bar"))) > > > > Match #1: > > > > E:\Desktop\t.cpp:4:1: note: "root" binds here > > bar i; > > ^~~~~ > > 1 match. > > > > So hasType() looks at what the immediate type is for the declaration (which > > we document, yay us!). Based on that, I don't think hasUnderlyingType() > > makes sense -- you should modify hasType() to work on a TypedefNameDecl > > (not just a TypedefDecl!) so that it looks at the immediate type of the > > type definition. I would expect your tests then to result in: > > ``` > > 1: typedef void (fn)(void); > > 2: typedef fn foo; > > 3: typedef int bar; > > 4: typedef int (f); > > 5: typedef int (fn2)(int); > > clang-query> match typedefDecl(hasType(asString("int"))) > > > > Match #1: > > > > /tmp/a.cpp:3:1: note: "root" binds here > > typedef int bar; > > ^~~~~~~~~~~~~~~ > > > > Match #2: > > > > /tmp/a.cpp:4:1: note: "root" binds here > > typedef int (f); > > ^~~~~~~~~~~~~~~ > > 2 matches. > > clang-query> match typedefDecl(hasType(typedefType())) > > > > Match #1: > > > > /tmp/a.cpp:2:1: note: "root" binds here > > typedef fn foo; > > ^~~~~~~~~~~~~~ > > 1 match. > > clang-query> match typedefDecl(hasType(parenType())) > > > > Match #1: > > > > /tmp/a.cpp:1:1: note: "root" binds here > > typedef void (fn)(void); > > ^~~~~~~~~~~~~~~~~~~~~~~ > > > > Match #2: > > > > /tmp/a.cpp:4:1: note: "root" binds here > > typedef int (f); > > ^~~~~~~~~~~~~~~ > > > > Match #3: > > > > /tmp/a.cpp:5:1: note: "root" binds here > > typedef int (fn2)(int); > > ^~~~~~~~~~~~~~~~~~~~~~ > > 3 matches. > > clang-query> match > > typedefDecl(hasType(parenType(innerType(functionType())))) > > > > Match #1: > > > > /tmp/a.cpp:1:1: note: "root" binds here > > typedef void (fn)(void); > > ^~~~~~~~~~~~~~~~~~~~~~~ > > > > Match #2: > > > > /tmp/a.cpp:5:1: note: "root" binds here > > typedef int (fn2)(int); > > ^~~~~~~~~~~~~~~~~~~~~~ > > 2 matches. > > ``` > > The end results are the same, so this is just changing the way the > > information is surfaced to the user that is logically consistent. > > ValueDecls have an immediate type, and so do TypedefDecls. By using > > TypedefNameDecl instead of TypedefDecl, this also covers the case where > > hasType() is useful for an alias-declaration. (We don't expose the matcher > > for that yet, but it seems quite reasonable to add in the future, and it > > would be nice for hasType to automatically work with that.) > > > > You can implement this with a helper function to handle abstracting away > > the call to getType() vs getUnderlyingType(), then updating the hasType() > > matchers to use it. Something like: > > ``` > > template <typename Ty> > > struct UnderlyingTypeGetter { > > static QualType get(const Ty &Node) { > > return Node.getType(); > > } > > }; > > > > template <> > > QualType UnderlyingTypeGetter<TypedefNameDecl>::get(const TypedefNameDecl > > &Node) { > > return Node.getUnderlyingType(); > > } > > ``` > > (Somewhere in ASTMatchersInternal.h most likely.) > > > When I try to extend `hasType` to work on `TypedefDecl`, I get this error: > > ``` > error: static assertion failed: right polymorphic conversion > static_assert(TypeListContainsSuperOf<ReturnTypes, T>::value, > ``` > > ...because `TypedefDecl` is derived from `NamedDecl` and the existing > definition for `hasType` looks like this: > > ``` > AST_POLYMORPHIC_MATCHER_P_OVERLOAD(hasType, > AST_POLYMORPHIC_SUPPORTED_TYPES(Expr, > ValueDecl), > internal::Matcher<Decl>, InnerMatcher, 1) { > return qualType(hasDeclaration(InnerMatcher)) > .matches(Node.getType(), Finder, Builder); > } > ``` > > So I'll need some guidance on how to extend `hasType` to work for > `TypedefNamedDecl` nodes. I don't understand exactly what all these nasty > macros do. So far, I've simply made changes by imitation, but my approach > didn't work this time. This ({F1302460}) does all of what you need (sans documentation, testing, etc).
(File should be attached, but if you need me to send it to you via email, I can do so -- I've never tried this with Phab before.) http://reviews.llvm.org/D8149 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits