加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 从Clang AST中的CXXConstructExpr中检索模板参数

发布时间:2020-12-16 07:21:21 所属栏目:百科 来源:网络整理
导读:假设我有一个像这样的变量声明: std::vectorMyType myVector(1); 这表示为Clang AST中的CXXConstructExpr.我有一个匹配器找到这个CXXConstructExpr,但我想从中提取MyType的decl. 我尝试了各种各样的东西,但似乎没有任何作用: const CXXConstructExpr* cons
假设我有一个像这样的变量声明:

std::vector<MyType> myVector(1);

这表示为Clang AST中的CXXConstructExpr.我有一个匹配器找到这个CXXConstructExpr,但我想从中提取MyType的decl.

我尝试了各种各样的东西,但似乎没有任何作用:

const CXXConstructExpr* construct = Result.Nodes.getNodeAs<CXXConstructExpr>("expr");
construct->getConstructor()->getTemplateSpecializationArgs()  // Always nullptr
construct->getConstructor()->getParent()  // Seems to lose the template parameters
construct->getConstructor()->getDescribedTemplate()  // Always nullptr

解决方法

这是一个匹配器:

varDecl(
  has(
    cxxConstructExpr()
  ),hasType(
    classTemplateSpecializationDecl().bind(sp_dcl_bd_name_)
  )
).bind(var_bd_name_);

它从VarDecl开始并遍历到类型,这是一个埋在向量的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) {
  // get the template args
  TemplateArgumentList const &tal(spec_decl->getTemplateArgs());
  for(unsigned i = 0; i < tal.size(); ++i){
    TemplateArgument const &ta(tal[i]);
    // is this arg a type arg? If so,get that type
    TemplateArgument::ArgKind k(ta.getKind());
    std::string argName = "";
    if(k==TemplateArgument::ArgKind::Type){
      QualType t = ta.getAsType();
      argName = t.getAsString();
    }
    // Could do similar actions for integral args,etc...
    std::cout << "For variable declared at "
      << corct::sourceRangeAsString(var_decl->getSourceRange(),&sm) << ":"
      << spec_decl->getNameAsString()
      << ": template arg " << (i+1) << ": " << argName << std::endl;
  } // for template args
} // if

对于此代码:

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>

完整示例位于代码分析和重构与Clang工具示例repo在github:https://github.com/lanl/CoARCT(请参阅apps / TemplateType.cc)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读