-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathprint-uses.cpp
69 lines (58 loc) · 2.5 KB
/
print-uses.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#ifndef PRINTUSES_H
#define PRINTUSES_H
#include "common.h"
struct PrintUses : clang::ASTFrontendAction {
struct Impl : clang::ASTConsumer, clang::RecursiveASTVisitor<Impl> {
clang::SourceManager & sourceManager;
clang::StringRef sourceFile;
bool indent;
Impl(clang::SourceManager & sourceManager, clang::StringRef sourceFile):
sourceManager(sourceManager), sourceFile(sourceFile), indent(false) {}
void HandleTranslationUnit(clang::ASTContext & context) override { // from ASTConsumer
std::cout << "Parsing file \"" << sourceFile.str() << '"' << std::endl;
TraverseDecl(context.getTranslationUnitDecl());
}
bool VisitStmt(clang::Stmt * stmt) { // from RecursiveASTVisitor
if(llvm::dyn_cast<clang::DeclRefExpr>(stmt)) {
if(sourceManager.getFilename(stmt->getLocStart()).equals(sourceFile)) {
clang::ValueDecl* decl = static_cast<clang::DeclRefExpr*>(stmt)->getDecl();
if(llvm::dyn_cast<clang::FunctionDecl>(decl)) {
if(sourceManager.getFilename(decl->getLocation()).equals(sourceFile)) {
std::cout << 'L' << sourceManager.getExpansionLineNumber(stmt->getLocStart()) << '\t';
if(indent) std::cout << '\t';
std::cout << "\tUse " << decl->getQualifiedNameAsString() << std::endl;
}
}
}
}
return true;
}
bool VisitDecl(clang::Decl *decl) { // from RecursiveASTVisitor
bool func = llvm::dyn_cast<clang::FunctionDecl>(decl);
if(llvm::dyn_cast<clang::CXXRecordDecl>(decl) || (func && decl->hasBody())) {
if(sourceManager.getFilename(decl->getLocation()).equals(sourceFile)) {
std::cout << 'L' << sourceManager.getExpansionLineNumber(decl->getLocStart()) << '\t';
indent = func && llvm::dyn_cast<clang::CXXMethodDecl>(decl);
if(indent) std::cout << '\t';
if(func) std::cout << "function ";
else std::cout << "class ";
std::cout << (static_cast<clang::NamedDecl*>(decl))->getQualifiedNameAsString() << std::endl;
}
}
return true;
}
};
virtual Impl* CreateASTConsumer(clang::CompilerInstance& ci, llvm::StringRef sourceFile) override {
return new Impl(ci.getSourceManager(), sourceFile);
}
static int run(const clang::tooling::CompilationDatabase & db, llvm::ArrayRef<std::string> sources) {
clang::tooling::ClangTool tool(db, sources);
return tool.run(clang::tooling::newFrontendActionFactory<PrintUses>());
}
};
namespace tools {
int print_uses(const clang::tooling::CompilationDatabase & db, llvm::ArrayRef<std::string> sources) {
return PrintUses::run(db, sources);
}
}
#endif // SIMPLEPARSE_H