# include "clang/AST/AST.h"
# include "clang/AST/ASTConsumer.h"
# include "clang/AST/RecursiveASTVisitor.h"
# include "clang/Frontend/FrontendActions.h"
# include "clang/Frontend/CompilerInstance.h"
# include "clang/Tooling/CommonOptionsParser.h"
# include "clang/Tooling/Tooling.h"
# include "llvm/Support/CommandLine.h"
# include <set>
/*
Visit....函数看这个文件:
clang\AST\DeclCXX.h
*/
using namespace clang;
using namespace clang::tooling;
using namespace llvm;
class HtlVisitor : public RecursiveASTVisitor<HtlVisitor> {
public:
explicit HtlVisitor(ASTContext* Context) : Context(Context) {}
bool VisitCXXRecordDecl(CXXRecordDecl* d) {
auto& c = d->getASTContext();
if (d->isInStdNamespace()) {
return true;
}
if (d->isCanonicalDecl()) {
return true;
}
if (!(d->isStruct() || d->isClass())) {
return true;
}
if (m.find(d) != m.end()) {
return true;
}
m.emplace(d);
if (d->getNameAsString() == "A") {
outs() << "=================================================\n";
}
outs() << d->getQualifiedNameAsString() << " \n";
for (auto&& x : d->fields()) {
outs()
<< x->getType() << " "
<< x->getNameAsString()
<< "\n"
;
}
if (d->getNameAsString() == "A") {
outs() << "--------------------------------------------------------------\n";
}
return true;
}
private:
ASTContext* Context;
std::set<CXXRecordDecl*> m;
};
class HtlConsumer : public clang::ASTConsumer {
public:
explicit HtlConsumer(ASTContext* Context) : Visitor(Context) {}
virtual void HandleTagDeclDefinition(TagDecl* d) {
Visitor.TraverseDecl(d->getTranslationUnitDecl());
}
private:
HtlVisitor Visitor;
};
class HtlAction : public clang::ASTFrontendAction {
public:
virtual std::unique_ptr<clang::ASTConsumer> CreateASTConsumer(
clang::CompilerInstance& Compiler
, llvm::StringRef InFile
) {
return std::make_unique<HtlConsumer>(&Compiler.getASTContext());
}
};
static cl::OptionCategory MyToolCategory("my-tool options");
static cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage);
static cl::extrahelp MoreHelp("\nMore help text...\n");
int main(int argc, const char** argv) {
auto OptionsParser = CommonOptionsParser::create(argc, argv, MyToolCategory);
ClangTool Tool(OptionsParser->getCompilations(), OptionsParser->getSourcePathList());
return Tool.run(newFrontendActionFactory<HtlAction>().get());
}
struct [[abc]] A{};
how to get that “abc”?