clang 15插件,输入是c++源码。
clang插件并非LLVM插件。
LLVM插件的输入是中间表示 。
c++源码被转成中间表示,源码中的各种可读符号此时难以获取。
虽然理论上LLVM插件面对中间表示时,可以从dwarf等调试信息库中拿到符号,但不容易不直接。
clang15插件(c++源码修改插件)小结:
1. 共用Rewriter,导致后写入覆盖前写入,前写入丢失
- 因此正确写法是,本插件全局 只能有一个Rewriter对象。
2. 单纯Rewriter对象,早期(Act中)不会崩溃,晚期(Visitor)会崩溃,应该用所谓智能指针const std::shared_ptr
- 单纯Rewriter对象
Rewriter rewriter;
作为Act成员字段, 早期(Act中CreateASTConsumer方法内)不会Segmentation fault,晚期(Visitor)会Segmentation fault。- 单纯对象 改为
const std::shared_ptr<Rewriter> mRewriter_ptr
后,正常,不再Segmentation fault。
3. 插件独立运行与插件被clang加载运行并不等同
- 单纯Rewriter对象
Rewriter rewriter;
在插件独立运行中 并不会 Segmentation fault,而在插件被clang加载运行时 会 Segmentation fault。
由此可见 Rewriter 正确写法如下:
/Act中(早期)的Rewriter样子:(Act是Rewriter源头、是Rewriter的创建者。)
class XxxAstAct : public PluginASTAction {
public:
std::unique_ptr<ASTConsumer>
CreateASTConsumer(CompilerInstance &CI,
llvm::StringRef inFile) override {
SourceManager &SM = CI.getSourceManager();
LangOptions &langOptions = CI.getLangOpts();
ASTContext &astContext = CI.getASTContext();
mRewriter_ptr->setSourceMgr(SM, langOptions);//Rewriter对象设置
return std::make_unique<XxxAstConsumer>(CI,mRewriter_ptr, &astContext, SM, langOptions);//Consumer进一步把Rewriter
}
PluginASTAction::ActionType getActionType() override {
//本插件自动运行: 在MainAction后运行本插件
return AddAfterMainAction;
}
private:
const std::shared_ptr<Rewriter