如何在ClangTool中获取Preprocessor对象以提取源文件宏名?
在ClangTool中获取Preprocessor对象的方法
要在ClangTool中拿到clang::Preprocessor对象,核心是通过自定义FrontendAction,借助CompilerInstance来获取。以下是具体实现步骤:
1. 自定义FrontendAction
ClangTool的工作依赖于FrontendAction,你可以选择继承ASTFrontendAction(需要处理AST时)或PreprocessorFrontendAction(仅处理预处理阶段时),两者都能通过CompilerInstance拿到Preprocessor。
示例1:基于ASTFrontendAction的实现
如果需要同时处理AST逻辑,用这个方式:
#include "clang/Frontend/FrontendAction.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Lex/Preprocessor.h" #include "clang/AST/ASTConsumer.h" #include "llvm/Support/raw_ostream.h" class MacroExtractAction : public clang::ASTFrontendAction { protected: std::unique_ptr<clang::ASTConsumer> CreateASTConsumer( clang::CompilerInstance &CI, llvm::StringRef InFile) override { // 从CompilerInstance获取Preprocessor对象 clang::Preprocessor &PP = CI.getPreprocessor(); // 调用getPredefines()获取预定义宏 llvm::StringRef predefMacros = PP.getPredefines(); llvm::errs() << "预定义宏列表:\n" << predefMacros << "\n"; // 返回空ASTConsumer(若无需处理AST) return std::make_unique<clang::ASTConsumer>(); } };
示例2:基于PreprocessorFrontendAction的实现
如果只需要预处理阶段的逻辑,用这个更轻量:
#include "clang/Frontend/FrontendAction.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Lex/Preprocessor.h" #include "llvm/Support/raw_ostream.h" class MacroExtractAction : public clang::PreprocessorFrontendAction { public: bool BeginSourceFileAction(clang::CompilerInstance &CI) override { clang::Preprocessor &PP = CI.getPreprocessor(); llvm::StringRef predefMacros = PP.getPredefines(); llvm::errs() << "预定义宏列表:\n" << predefMacros << "\n"; return true; } };
2. 在ClangTool中运行自定义Action
将上述Action传入ClangTool的run方法,完成工具的搭建:
#include "clang/Tooling/CommonOptionsParser.h" #include "clang/Tooling/Tooling.h" #include "llvm/Support/CommandLine.h" int main(int argc, const char **argv) { llvm::cl::OptionCategory ToolOpts("宏提取工具选项"); clang::tooling::CommonOptionsParser optsParser(argc, argv, ToolOpts); clang::tooling::ClangTool tool(optsParser.getCompilations(), optsParser.getSourcePathList()); // 运行自定义Action return tool.run(clang::tooling::newFrontendActionFactory<MacroExtractAction>().get()); }
关键说明
CompilerInstance是Clang前端的核心实例,包含了预处理、编译等所有阶段的组件,通过它的getPreprocessor()方法可直接拿到Preprocessor对象。getPredefines()返回的是包含所有预定义宏的字符串(格式类似#define __GNUC__ 12),如果需要提取单个宏名称,可自行解析该字符串,或使用Preprocessor的getMacroInfo()等方法遍历宏列表。
内容的提问来源于stack exchange,提问作者Bhushan
相关产品推荐
相关产品推荐

