[cfe-dev] RecursiveASTVisitor and template instantiations
Benoit Belley
Benoit.Belley at autodesk.com
Wed Aug 25 13:41:51 PDT 2010
Hi Everyone,
I am trying to write a custom static analyzer check for Clang. In my checker, I need to traverse all of the template instantiations because I need to know how function calls made by template instantiations are actually resolved.
I am using the RecursiveASTVisitor to achieve this. Unfortunately, the RecursiveASTVisitor does not traverse template instantiations by default and I had to customize it. I was able to achieve this customization all in my derived class, with the exception of redeclaring RecursiveASTVisitor::TraverseCXXRecordHelper() protected instead of private. Please look below for the code.
I am wondering if :
a) Clang has another visitor better suited for what I am trying to achieve, or if
b) it would be a good idea to augment the RecursiveASTVisitor class to optionally visit the template instantiations.
I am willing to submit a patch for option b) if others also agree that this would a useful improvement.
Thanks for your help,
Benoit
-----------
Here’s what my current solution looks like for traversing template instantiations:
class RecursiveASTVisitorWithInstantiations :
public RecursiveASTVisitor<RecursiveASTVisitorWithInstantiations> {
typedef RecursiveASTVisitor<RecursiveASTVisitorWithInstantiations> BaseClass;
public:
//============================================================================
// Traversal functions for template instantiations
//============================================================================
// RecursiveASTVisitor skips the traversal of template
// instantiations because these are not part of the source code. We
// therefore have to reimplement a few of these functions to
// traverse all of the AST.
virtual bool TraverseFunctionTemplateDecl (FunctionTemplateDecl *D)
{
{
if (!BaseClass::TraverseFunctionTemplateDecl(D)) {
return false;
}
}
{
FunctionTemplateDecl::spec_iterator end = D->spec_end();
for (FunctionTemplateDecl::spec_iterator it = D->spec_begin(); it != end; ++it) {
if ( !TraverseFunctionDecl(*it) ) {
return false;
}
}
}
return true;
}
virtual bool TraverseClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl *D)
{
if (!getDerived().WalkUpFromClassTemplateSpecializationDecl (D)) {
return false;
}
if (!getDerived().TraverseCXXRecordHelper(D)) {
return false;
}
if (!getDerived().TraverseDeclContextHelper(dyn_cast<DeclContext>(D))) {
return false;
}
return true;
}
virtual bool TraverseClassTemplateDecl (ClassTemplateDecl *D)
{
{
if (!BaseClass::TraverseClassTemplateDecl(D)) {
return false;
}
}
{
ClassTemplateDecl::spec_iterator end = D->spec_end();
for (ClassTemplateDecl::spec_iterator it = D->spec_begin(); it != end; ++it) {
if ( !TraverseClassTemplateSpecializationDecl(*it) ) {
return false;
}
}
}
{
ClassTemplateDecl::partial_spec_iterator end = D->partial_spec_end();
for (ClassTemplateDecl::partial_spec_iterator it = D->partial_spec_begin(); it != end; ++it) {
if ( !TraverseClassTemplatePartialSpecializationDecl(*it) ) {
return false;
}
}
}
return true;
}
}
Thanks for you help,
Benoit
Benoit Belley
Sr Principal Developer
M&E-Product Development Group
Autodesk Canada Inc.
10 Rue Duke
Montreal, Quebec H3C 2L7
Canada
Direct 514 954-7154
-------------- next part --------------
A non-text attachment was scrubbed...
Name: image002.gif
Type: image/gif
Size: 651 bytes
Desc: image002.gif
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20100825/f861e5f7/attachment.gif>
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: ATT00001..txt
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20100825/f861e5f7/attachment.txt>
More information about the cfe-dev
mailing list