Clang Project

clang_source_code/tools/clang-extdef-mapping/ClangExtDefMapGen.cpp
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
27using namespace llvm;
28using namespace clang;
29using namespace clang::cross_tu;
30using namespace clang::tooling;
31
32static cl::OptionCategory ClangExtDefMapGenCategory("clang-extdefmapgen options");
33
34class MapExtDefNamesConsumer : public ASTConsumer {
35public:
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
48private:
49  void handleDecl(const Decl *D);
50
51  SourceManager &SM;
52  llvm::StringMap<std::string> Index;
53  std::string CurrentFileName;
54};
55
56void 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
92class MapExtDefNamesAction : public ASTFrontendAction {
93protected:
94  std::unique_ptr<ASTConsumerCreateASTConsumer(CompilerInstance &CI,
95                                                 llvm::StringRef) {
96    return llvm::make_unique<MapExtDefNamesConsumer>(CI.getASTContext());
97  }
98};
99
100static cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage);
101
102int main(int argcconst 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
MapExtDefNamesConsumer::HandleTranslationUnit