这是一个匹配器:
varDecl(
has(
cxxConstructExpr()
)
,hasType(
classTemplateSpecializationDecl().bind(sp_dcl_bd_name_)
)
).bind(var_bd_name_);
它始于VarDecl,遍历到类型,这是一个嵌入在vector的ClassTemplateDecl中的ClassTemplateSpecializationDecl。在回调中,可以从ClassTemplateSpecializationDecl转到模板参数列表,并对各个模板参数进行操作:
using CTSD = ClassTemplateSpecializationDecl;
CTSD * spec_decl =
const_cast<CTSD *>(result.Nodes.getNodeAs<CTSD>(sp_dcl_bd_name_));
VarDecl * var_decl =
const_cast<VarDecl *>(result.Nodes.getNodeAs<VarDecl>(var_bd_name_));
if(spec_decl && var_decl) {
TemplateArgumentList const &tal(spec_decl->getTemplateArgs());
for(unsigned i = 0; i < tal.size(); ++i){
TemplateArgument const &ta(tal[i]);
TemplateArgument::ArgKind k(ta.getKind());
std::string argName = "";
if(k==TemplateArgument::ArgKind::Type){
QualType t = ta.getAsType();
argName = t.getAsString();
}
std::cout << "For variable declared at "
<< corct::sourceRangeAsString(var_decl->getSourceRange(),&sm) << ":"
<< spec_decl->getNameAsString()
<< ": template arg " << (i+1) << ": " << argName << std::endl;
}
}
对于这段代码:
struct B{int b_;};
std::vector<B> vb(1);
这个产生:
For variable declared at <line:14:1, col:20>:vector: template arg 1: struct B
For variable declared at <col:1, col:20>:vector: template arg 2: class std::__1::allocator<struct B>
完整的示例在 Github 上的 Code Analysis and Refactoring with Clang Tools 示例存储库中:
https://github.com/lanl/CoARCT(请参见 apps/TemplateType.cc)。