在 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 中生成默认构造函数的主要内容,如果未能解决你的问题,请参考以下文章