diff options
Diffstat (limited to 'tools/clang-func-mapping/ClangFnMapGen.cpp')
-rw-r--r-- | tools/clang-func-mapping/ClangFnMapGen.cpp | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/tools/clang-func-mapping/ClangFnMapGen.cpp b/tools/clang-func-mapping/ClangFnMapGen.cpp new file mode 100644 index 000000000000..4bf812fffe34 --- /dev/null +++ b/tools/clang-func-mapping/ClangFnMapGen.cpp @@ -0,0 +1,124 @@ +//===- ClangFnMapGen.cpp -----------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--------------------------------------------------------------------===// +// +// Clang tool which creates a list of defined functions and the files in which +// they are defined. +// +//===--------------------------------------------------------------------===// + +#include "clang/AST/ASTConsumer.h" +#include "clang/AST/ASTContext.h" +#include "clang/AST/GlobalDecl.h" +#include "clang/AST/Mangle.h" +#include "clang/AST/StmtVisitor.h" +#include "clang/Basic/SourceManager.h" +#include "clang/Basic/TargetInfo.h" +#include "clang/CrossTU/CrossTranslationUnit.h" +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Frontend/FrontendActions.h" +#include "clang/Index/USRGeneration.h" +#include "clang/Tooling/CommonOptionsParser.h" +#include "clang/Tooling/Tooling.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/Path.h" +#include "llvm/Support/Signals.h" +#include <sstream> +#include <string> +#include <vector> + +using namespace llvm; +using namespace clang; +using namespace clang::cross_tu; +using namespace clang::tooling; + +static cl::OptionCategory ClangFnMapGenCategory("clang-fnmapgen options"); + +class MapFunctionNamesConsumer : public ASTConsumer { +public: + MapFunctionNamesConsumer(ASTContext &Context) : Ctx(Context) {} + + ~MapFunctionNamesConsumer() { + // Flush results to standard output. + llvm::outs() << createCrossTUIndexString(Index); + } + + virtual void HandleTranslationUnit(ASTContext &Ctx) { + handleDecl(Ctx.getTranslationUnitDecl()); + } + +private: + void handleDecl(const Decl *D); + + ASTContext &Ctx; + llvm::StringMap<std::string> Index; + std::string CurrentFileName; +}; + +void MapFunctionNamesConsumer::handleDecl(const Decl *D) { + if (!D) + return; + + if (const auto *FD = dyn_cast<FunctionDecl>(D)) { + if (FD->isThisDeclarationADefinition()) { + if (const Stmt *Body = FD->getBody()) { + std::string LookupName = CrossTranslationUnitContext::getLookupName(FD); + const SourceManager &SM = Ctx.getSourceManager(); + if (CurrentFileName.empty()) { + CurrentFileName = + SM.getFileEntryForID(SM.getMainFileID())->tryGetRealPathName(); + if (CurrentFileName.empty()) + CurrentFileName = "invalid_file"; + } + + switch (FD->getLinkageInternal()) { + case ExternalLinkage: + case VisibleNoLinkage: + case UniqueExternalLinkage: + if (SM.isInMainFile(Body->getLocStart())) + Index[LookupName] = CurrentFileName; + default: + break; + } + } + } + } + + if (const auto *DC = dyn_cast<DeclContext>(D)) + for (const Decl *D : DC->decls()) + handleDecl(D); +} + +class MapFunctionNamesAction : public ASTFrontendAction { +protected: + std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI, + llvm::StringRef) { + std::unique_ptr<ASTConsumer> PFC( + new MapFunctionNamesConsumer(CI.getASTContext())); + return PFC; + } +}; + +static cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage); + +int main(int argc, const char **argv) { + // Print a stack trace if we signal out. + sys::PrintStackTraceOnErrorSignal(argv[0], false); + PrettyStackTraceProgram X(argc, argv); + + const char *Overview = "\nThis tool collects the USR name and location " + "of all functions definitions in the source files " + "(excluding headers).\n"; + CommonOptionsParser OptionsParser(argc, argv, ClangFnMapGenCategory, + cl::ZeroOrMore, Overview); + + ClangTool Tool(OptionsParser.getCompilations(), + OptionsParser.getSourcePathList()); + Tool.run(newFrontendActionFactory<MapFunctionNamesAction>().get()); + return 0; +} |