1 | //===- ClangExtDefMapGen.cpp -----------------------------------------------===// |
---|---|
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===--------------------------------------------------------------------===// |
8 | // |
9 | // Clang tool which creates a list of defined functions and the files in which |
10 | // they are defined. |
11 | // |
12 | //===--------------------------------------------------------------------===// |
13 | |
14 | #include "clang/AST/ASTConsumer.h" |
15 | #include "clang/AST/ASTContext.h" |
16 | #include "clang/Basic/SourceManager.h" |
17 | #include "clang/CrossTU/CrossTranslationUnit.h" |
18 | #include "clang/Frontend/CompilerInstance.h" |
19 | #include "clang/Frontend/FrontendActions.h" |
20 | #include "clang/Tooling/CommonOptionsParser.h" |
21 | #include "clang/Tooling/Tooling.h" |
22 | #include "llvm/Support/CommandLine.h" |
23 | #include "llvm/Support/Signals.h" |
24 | #include <sstream> |
25 | #include <string> |
26 | |
27 | using namespace llvm; |
28 | using namespace clang; |
29 | using namespace clang::cross_tu; |
30 | using namespace clang::tooling; |
31 | |
32 | static cl::OptionCategory ClangExtDefMapGenCategory("clang-extdefmapgen options"); |
33 | |
34 | class MapExtDefNamesConsumer : public ASTConsumer { |
35 | public: |
36 | MapExtDefNamesConsumer(ASTContext &Context) |
37 | : SM(Context.getSourceManager()) {} |
38 | |
39 | ~MapExtDefNamesConsumer() { |
40 | // Flush results to standard output. |
41 | llvm::outs() << createCrossTUIndexString(Index); |
42 | } |
43 | |
44 | void HandleTranslationUnit(ASTContext &Ctx) override { |
45 | handleDecl(Ctx.getTranslationUnitDecl()); |
46 | } |
47 | |
48 | private: |
49 | void handleDecl(const Decl *D); |
50 | |
51 | SourceManager &SM; |
52 | llvm::StringMap<std::string> Index; |
53 | std::string CurrentFileName; |
54 | }; |
55 | |
56 | void MapExtDefNamesConsumer::handleDecl(const Decl *D) { |
57 | if (!D) |
58 | return; |
59 | |
60 | if (const auto *FD = dyn_cast<FunctionDecl>(D)) { |
61 | if (FD->isThisDeclarationADefinition()) { |
62 | if (const Stmt *Body = FD->getBody()) { |
63 | if (CurrentFileName.empty()) { |
64 | CurrentFileName = |
65 | SM.getFileEntryForID(SM.getMainFileID())->tryGetRealPathName(); |
66 | if (CurrentFileName.empty()) |
67 | CurrentFileName = "invalid_file"; |
68 | } |
69 | |
70 | switch (FD->getLinkageInternal()) { |
71 | case ExternalLinkage: |
72 | case VisibleNoLinkage: |
73 | case UniqueExternalLinkage: |
74 | if (SM.isInMainFile(Body->getBeginLoc())) { |
75 | std::string LookupName = |
76 | CrossTranslationUnitContext::getLookupName(FD); |
77 | Index[LookupName] = CurrentFileName; |
78 | } |
79 | break; |
80 | default: |
81 | break; |
82 | } |
83 | } |
84 | } |
85 | } |
86 | |
87 | if (const auto *DC = dyn_cast<DeclContext>(D)) |
88 | for (const Decl *D : DC->decls()) |
89 | handleDecl(D); |
90 | } |
91 | |
92 | class MapExtDefNamesAction : public ASTFrontendAction { |
93 | protected: |
94 | std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI, |
95 | llvm::StringRef) { |
96 | return llvm::make_unique<MapExtDefNamesConsumer>(CI.getASTContext()); |
97 | } |
98 | }; |
99 | |
100 | static cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage); |
101 | |
102 | int main(int argc, const char **argv) { |
103 | // Print a stack trace if we signal out. |
104 | sys::PrintStackTraceOnErrorSignal(argv[0], false); |
105 | PrettyStackTraceProgram X(argc, argv); |
106 | |
107 | const char *Overview = "\nThis tool collects the USR name and location " |
108 | "of external definitions in the source files " |
109 | "(excluding headers).\n"; |
110 | CommonOptionsParser OptionsParser(argc, argv, ClangExtDefMapGenCategory, |
111 | cl::ZeroOrMore, Overview); |
112 | |
113 | ClangTool Tool(OptionsParser.getCompilations(), |
114 | OptionsParser.getSourcePathList()); |
115 | |
116 | return Tool.run(newFrontendActionFactory<MapExtDefNamesAction>().get()); |
117 | } |
118 |