LegalizeAdulthood marked an inline comment as done.

================
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;",
----------------
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.


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