2.0 KiB
2.0 KiB
本小节会详细介绍Preprocessor提供的一些给用户的接口
using namespace clang;
class Callback : public clang::PPCallbacks {
public:
Preprocessor& pp;
SourceRange last;
Callback(Preprocessor& pp) : pp(pp) {}
/// Called by Preprocessor::HandleMacroExpandedIdentifier when a
/// macro invocation is found.
void MacroExpands(const Token& MacroNameTok,
const MacroDefinition& MD,
SourceRange Range,
const MacroArgs* Args) override {
auto name = MacroNameTok.getIdentifierInfo()->getName();
if(name.starts_with("__"))
return;
llvm::outs() << "MacroExpands: " << name;
if(MD.getMacroInfo()->isFunctionLike()) {
llvm::outs() << "(";
int len = Args->getNumMacroArguments();
for(auto i = 0; i < len; i++) {
auto arg = Args->getUnexpArgument(i);
auto len2 = Args->getArgLength(arg);
for(auto j = 0; j < len2; j++) {
llvm::outs() << pp.getSpelling(*(arg + j));
}
if(i < len - 1)
llvm::outs() << ", ";
}
llvm::outs() << ")";
}
llvm::outs() << "\n";
auto& m = pp.getSourceManager();
auto x = m.getExpansionRange(Range);
// auto z = m.getImmediateExpansionRange(x.getBegin());
auto text = Lexer::getSourceText(x, m, pp.getLangOpts());
llvm::outs() << text << "\n";
}
/// Hook called whenever a macro definition is seen.
void MacroDefined(const Token& MacroNameTok, const MacroDirective* MD) override {
auto name = MacroNameTok.getIdentifierInfo()->getName();
if(name.starts_with("__"))
return;
// llvm::outs() << "MacroDefined: " << name << "\n";
}
}
// must be after BeginSourceFile
auto& preprocessor = instance->getPreprocessor();
preprocessor.addPPCallbacks(std::make_unique<Callback>(preprocessor));