在 Clang 中生成默认构造函数

Posted

技术标签:

【中文标题】在 Clang 中生成默认构造函数【英文标题】:Generate the default constructor in Clang 【发布时间】:2019-01-03 21:23:22 【问题描述】:

我正在尝试使用插件从 Clang 中提取 AST,并且我想获取默认构造函数的“源代码”。例如,在我的源代码中,我有:

class T  public: T() = default; 

在 Clang AST 中,构造函数对象的 getBody() 成员返回 null。有没有办法将默认实现作为Stmt?在这种情况下,它将返回 ,但在一般情况下,它会涉及调用父构造函数等。

一个简单的例子,在一个文件中写入以下内容:

class P  
int main() 
  // P x;
  return 0;

此文件不会生成任何构造函数代码(您可以使用 (clang++ -Xclang -ast-dump -fsyntax-only test-ctor.cpp) 转储 AST,但如果取消注释 P x 行,则相同的命令将生成默认构造函数:

| CXXConstructorDecl 0x562bdb879eb0 <line:5:5, col:17> col:5 used P 'void () noexcept' default trivial
| `-CompoundStmt 0x562bdb87a570 <col:17>

谢谢!

【问题讨论】:

AST只代表你的cpp文件的来源,构造函数代码是由编译器的后续阶段生成的,生成的构造函数的源代码不存在 我正在查看 -ast-dump 的结果。如果我有一个简单的class P ;,那么转储不包含任何构造函数代码,但是一旦我编写了一个简单的int main() P x; return 0; ,clang 就会为隐式构造函数生成 AST 节点(它们甚至具有指向打开类的 。模板实例化实际上也是如此。AST 包括模板声明,以及提到的所有特化。 【参考方案1】:

这可以通过Sema 对象使用诸如DefineImplicitDefaultConstructor 之类的函数来实现。 Sema 对象可从 CompilerInstance 获得。

【讨论】:

【参考方案2】:

基于this post 和 C++11,

默认构造函数且未定义为已删除的默认构造函数在被 odr 使用 (3.2) 创建其类类型 (1.8) 的对象时或在其第一次声明后显式默认时被隐式定义。

所以当P x在代码中时有一个CXXConstructorDecl节点,即对象x被创建其类类型P

【讨论】:

感谢您的帮助。我的问题更多关于 clang++ api。你知道 clang 中的哪些代码实际上为构造函数生成了 AST 吗? @Gregory,我不知道 Clang 中有任何可以生成构造函数的函数。如果我们谈论 AST,它只是源代码的一种表示。生成“未定义”构造函数还不够“聪明”。如果构造函数被隐式定义,我们只能拥有该节点,这是怎么发生的?通过在代码中添加 P x。 我不确定我是否理解您的观点。我知道 C++ 的语义说构造函数只有在使用时才会生成。本质上,我想做的是让 clang 假装调用了构造函数并适当地生成代码。具体来说,我想对具有隐式构造函数的头文件进行静态分析。为了使我的静态分析起作用,我需要查看定义并为其计算签名。但是我不想每次包含头文件时都重新计算这个签名,只有一次。

以上是关于在 Clang 中生成默认构造函数的主要内容,如果未能解决你的问题,请参考以下文章

当我在 Visual Studio 中生成以二维数组作为参数的构造函数时,这些星号是啥?

“这个类应该有一个默认构造函数”[Android]

显式默认构造函数

C++:类中两个易被忽略的默认函数

构造函数

构造函数