Problems retrieving container type specializations in function prototypes from the clang AST

Hello everybody,

I have started to use libtooling to write some software that can parse a c++ header in order to generate automatic code used in a SDK. In order to do this I have implemented RecursiveASTVisitor and its virtual member function VisitFunctionDecl. In VisitFunctionDecl i collect all kinds of data from the Function prototype in order to expand the string templates in the code Id like to generate. When sorting through the parameter declarations I’m experiencing difficulties in uniquely identifying some of the class types. Whereas it is quite clear how to handle builtin types and enumerals I am struggling with class types. Heres an example of a prototype that i am visiting:

CallResult ExampleApiCall(std::vectorstd::string &outputVector);

Now I am interested in identifying the exact type of the LValue outputVector. What I have been able to do up until now is check if the desugared type pointer is a class type. This is straight forward. Once I know it is a class type such as in the above example I am interested in its unique class type. Up until now all i could manage to do retrieve the CXXRecordDecl from the type im looking at. Now I can find out the kind name and qualified name string of this class which is vector. So naively spoken i can string compare (which I dont want to really) the unqualified name with the string “vector” and I’d now that I am looking at a vector type. I am also interested in knowing what type of vector container this is though as I will generate different code depending on what is in the container. This, I have not been able to find out yet. How can I access the specified template parameter? One of the things I tried was

const ClassTemplateSpecializationDecl *cltmplsdcl = desugaredType->getAs();

but to no avail. Maybe Im barking up the completely wrong tree here, my experience with clang AST is very limited. I’d appreciate any help and ideas from the community. Thanks a lot!

Here’s an excerpt of the code Im using right now in VisitFunctionDecl :

// desugar the parameter qualifier type
const QualType desugaredQualType = parmQualType.getCanonicalType().getTypePtr()->getPointeeType();
// get the desugared type pointer
const Type *desugaredType = desugaredQualType.getTypePtr();

// handle class types
if(desugaredType->isClassType()) {
// get the class type
const CXXRecordDecl *cxxrcdcl = desugaredType->getAsCXXRecordDecl();
if(nullptr == cxxrcdcl
) {
cout << “Could not cast class type to CXXRecordDecl” << endl;
return hdt_CXXRecord_NA;
}
// some cxx record decl tests —> this gets me the class type but not the template specification
cout << "cxxrcdcl->getKindName(): " << cxxrcdcl->getKindName() << endl;
cout << "cxxrcdcl->getQualifiedNameAsString(): " << cxxrcdcl->getQualifiedNameAsString() << endl;
return hdt_CXXRecord_NA;
}

Cheers,

Benjamin Fabricius
Software Engineer

Leica Geosystems AG, part of Hexagon
Machine Control Division
Heinrich-Wild-Strasse
9435 Heerbrugg, Switzerland
Skype: b.fabricius
Phone: +41 71 727 3407
E-Mail: benjamin.fabricius@leica-geosystems.com
Website: http://www.leica-geosystems.com

Social Networks: