clang-tools  9.0.0
PPTrace.cpp
Go to the documentation of this file.
1 //===--- tools/pp-trace/PPTrace.cpp - Clang preprocessor tracer -----------===//
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 // This file implements pp-trace, a tool for displaying a textual trace
10 // of the Clang preprocessor activity. It's based on a derivation of the
11 // PPCallbacks class, that once registerd with Clang, receives callback calls
12 // to its virtual members, and outputs the information passed to the callbacks
13 // in a high-level YAML format.
14 //
15 // The pp-trace tool also serves as the basis for a test of the PPCallbacks
16 // mechanism.
17 //
18 // The pp-trace tool supports the following general command line format:
19 //
20 // pp-trace [options] file... [-- compiler options]
21 //
22 // Basically you put the pp-trace options first, then the source file or files,
23 // and then -- followed by any options you want to pass to the compiler.
24 //
25 //===----------------------------------------------------------------------===//
26 
27 #include "PPCallbacksTracker.h"
28 #include "clang/AST/ASTConsumer.h"
29 #include "clang/AST/ASTContext.h"
30 #include "clang/Basic/SourceManager.h"
31 #include "clang/Driver/Options.h"
32 #include "clang/Frontend/CompilerInstance.h"
33 #include "clang/Frontend/FrontendActions.h"
34 #include "clang/Lex/Preprocessor.h"
35 #include "clang/Tooling/Execution.h"
36 #include "clang/Tooling/Tooling.h"
37 #include "llvm/Option/Arg.h"
38 #include "llvm/Option/ArgList.h"
39 #include "llvm/Option/OptTable.h"
40 #include "llvm/Option/Option.h"
41 #include "llvm/Support/CommandLine.h"
42 #include "llvm/Support/FileSystem.h"
43 #include "llvm/Support/GlobPattern.h"
44 #include "llvm/Support/InitLLVM.h"
45 #include "llvm/Support/Path.h"
46 #include "llvm/Support/ToolOutputFile.h"
47 #include "llvm/Support/WithColor.h"
48 #include <string>
49 #include <vector>
50 
51 using namespace llvm;
52 
53 namespace clang {
54 namespace pp_trace {
55 
56 static cl::OptionCategory Cat("pp-trace options");
57 
58 static cl::opt<std::string> Callbacks(
59  "callbacks", cl::init("*"),
60  cl::desc("Comma-separated list of globs describing the list of callbacks "
61  "to output. Globs are processed in order of appearance. Globs "
62  "with the '-' prefix remove callbacks from the set. e.g. "
63  "'*,-Macro*'."),
64  cl::cat(Cat));
65 
66 static cl::opt<std::string> OutputFileName(
67  "output", cl::init("-"),
68  cl::desc("Output trace to the given file name or '-' for stdout."),
69  cl::cat(Cat));
70 
71 LLVM_ATTRIBUTE_NORETURN static void error(Twine Message) {
72  WithColor::error() << Message << '\n';
73  exit(1);
74 }
75 
76 namespace {
77 
78 class PPTraceAction : public ASTFrontendAction {
79 public:
80  PPTraceAction(const FilterType &Filters, raw_ostream &OS)
81  : Filters(Filters), OS(OS) {}
82 
83 protected:
84  std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
85  StringRef InFile) override {
86  Preprocessor &PP = CI.getPreprocessor();
87  PP.addPPCallbacks(
88  llvm::make_unique<PPCallbacksTracker>(Filters, CallbackCalls, PP));
89  return llvm::make_unique<ASTConsumer>();
90  }
91 
92  void EndSourceFileAction() override {
93  OS << "---\n";
94  for (const CallbackCall &Callback : CallbackCalls) {
95  OS << "- Callback: " << Callback.Name << "\n";
96  for (const Argument &Arg : Callback.Arguments)
97  OS << " " << Arg.Name << ": " << Arg.Value << "\n";
98  }
99  OS << "...\n";
100 
101  CallbackCalls.clear();
102  }
103 
104 private:
105  const FilterType &Filters;
106  raw_ostream &OS;
107  std::vector<CallbackCall> CallbackCalls;
108 };
109 
110 class PPTraceFrontendActionFactory : public tooling::FrontendActionFactory {
111 public:
112  PPTraceFrontendActionFactory(const FilterType &Filters, raw_ostream &OS)
113  : Filters(Filters), OS(OS) {}
114 
115  PPTraceAction *create() override { return new PPTraceAction(Filters, OS); }
116 
117 private:
118  const FilterType &Filters;
119  raw_ostream &OS;
120 };
121 } // namespace
122 } // namespace pp_trace
123 } // namespace clang
124 
125 int main(int argc, const char **argv) {
126  using namespace clang::pp_trace;
127  InitLLVM X(argc, argv);
128  auto OptionsParser = clang::tooling::CommonOptionsParser::create(
129  argc, argv, Cat, llvm::cl::ZeroOrMore);
130  if (!OptionsParser)
131  error(toString(OptionsParser.takeError()));
132  // Parse the IgnoreCallbacks list into strings.
133  SmallVector<StringRef, 32> Patterns;
134  FilterType Filters;
135  StringRef(Callbacks).split(Patterns, ",",
136  /*MaxSplit=*/-1, /*KeepEmpty=*/false);
137  for (StringRef Pattern : Patterns) {
138  Pattern = Pattern.trim();
139  bool Enabled = !Pattern.consume_front("-");
140  Expected<GlobPattern> Pat = GlobPattern::create(Pattern);
141  if (Pat)
142  Filters.emplace_back(std::move(*Pat), Enabled);
143  else
144  error(toString(Pat.takeError()));
145  }
146 
147  // Create the tool and run the compilation.
148  clang::tooling::ClangTool Tool(OptionsParser->getCompilations(),
149  OptionsParser->getSourcePathList());
150 
151  std::error_code EC;
152  llvm::ToolOutputFile Out(OutputFileName, EC, llvm::sys::fs::F_Text);
153  if (EC)
154  error(EC.message());
155  PPTraceFrontendActionFactory Factory(Filters, Out.os());
156  int HadErrors = Tool.run(&Factory);
157 
158  // If we had errors, exit early.
159  if (HadErrors)
160  return HadErrors;
161 
162  Out.keep();
163 
164  return 0;
165 }
Some operations such as code completion produce a set of candidates.
static cl::opt< std::string > Callbacks("callbacks", cl::init("*"), cl::desc("Comma-separated list of globs describing the list of callbacks " "to output. Globs are processed in order of appearance. Globs " "with the '-' prefix remove callbacks from the set. e.g. " "'*,-Macro*'."), cl::cat(Cat))
constexpr llvm::StringLiteral Message
static llvm::StringRef toString(SpecialMemberFunctionsCheck::SpecialMemberFunctionKind K)
llvm::unique_function< void(llvm::Expected< T >)> Callback
A Callback<T> is a void function that accepts Expected<T>.
Definition: Function.h:28
static ClangTidyModuleRegistry::Add< AbseilModule > X("abseil-module", "Add Abseil checks.")
static LLVM_ATTRIBUTE_NORETURN void error(Twine Message)
Definition: PPTrace.cpp:71
This class represents one callback call by name and an array of arguments.
int main(int argc, const char **argv)
Definition: PPTrace.cpp:125
Classes and definitions for preprocessor tracking.
static cl::opt< std::string > OutputFileName("output", cl::init("-"), cl::desc("Output trace to the given file name or '-' for stdout."), cl::cat(Cat))
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
std::vector< std::pair< llvm::GlobPattern, bool > > FilterType
static cl::OptionCategory Cat("pp-trace options")