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

Reply via email to