I am working on a Clang AST generated from the following source code:
template<class T>
struct my_class
{
template<class U>
void foo(U arg);
};
template<class V>
template<class W> void my_class<V>::foo(W arg)
{
}
int main()
{
return 0;
}
I have a FunctionDecl corresponding to foo's definition at line 9. I want to find the SourceLocation of template<class V> at line 8.
Is this possible?
I am analyzing the AST for the purposes of rewriting it.
The "outer" template parameter lists are associated with the
DeclaratorDecl, and can be retrieved using thegetNumTemplateParameterLists()andgetTemplateParameterList(unsigned)methods.The methods don't have any documentation, but if you look into the
Decl.hsource code, you can see that these methods access aQualifierInfostructure, which has documentation on the two relevant fields.Then, once we get the relevant
TemplateParameterList, the locations of thetemplatekeyword and the angle brackets can be obtained by callinggetTemplateLoc(),getLAngleLoc(), andgetRAngleLoc(). Locations for the individual parameters are available from theNamedDeclnodes accessible viaasArray().So, given a
FunctionDecl *functionDecl, we can print (say) the locations of the outertemplatekeywords like this:One related quirk/detail: When a
DeclaratorDecl(which is a base class ofFunctionDeclandCXXMethodDecl) has "outer" template parameters, itsgetBeginLoc()method will return the location of thetemplatekeyword of the first outer. If you want to get the location of the beginning of the declaration after all template parameter lists (both inner and outer, despite the documentation only mentioning outer), useDeclaratorDecl::getInnerLocStart(). For the example in the question, that returns the location of thevoidkeyword (for both declarations offoo).Complete example
Here is a complete program demonstrating the method:
When run on
test.cc, the example in the question:it prints:
When run on this more complicated example:
it prints: