clang 15插件,输入是c++源码。
clang插件并非LLVM插件。
LLVM插件的输入是中间表示 。
c++源码被转成中间表示,源码中的各种可读符号此时难以获取。
虽然理论上LLVM插件面对中间表示时,可以从dwarf等调试信息库中拿到符号,但不容易不直接。
clang15插件(c++源码修改插件)小结:
-1. SourceRange::fullyContains 结果是错误的
0. case的子句拿不全,但对 myRecursiveASTVisitor.TraverseStmt(switchStmt) 却能触碰到case的全部子句,这说明clang的风格是Visitor为主 甚至 高于 看起来很合理的 方法名
//CaseStmt.getSourceRange 拿到case子语句有许多不完整情况
//CaseStmt::children 拿到case子语句有许多不完整情况
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后运行本插件
ret

&spm=1001.2101.3001.5002&articleId=131892551&d=1&t=3&u=2373134b0d6b46afb727c33f1fbf57fa)
5242

被折叠的 条评论
为什么被折叠?



