clang15插件(c++源码修改插件)小结(非llvm插件)

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

猜你喜欢

转载自blog.csdn.net/hfcaoguilin/article/details/131892551