1 | //===--- PPCallbacksTracker.h - Preprocessor tracking -----------*- C++ -*-===// |
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 | /// \file |
10 | /// Classes and definitions for preprocessor tracking. |
11 | /// |
12 | /// The core definition is the PPCallbacksTracker class, derived from Clang's |
13 | /// PPCallbacks class from the Lex library, which overrides all the callbacks |
14 | /// and collects information about each callback call, saving it in a |
15 | /// data structure built up of CallbackCall and Argument objects, which |
16 | /// record the preprocessor callback name and arguments in high-level string |
17 | /// form for later inspection. |
18 | /// |
19 | //===----------------------------------------------------------------------===// |
20 | |
21 | #ifndef PPTRACE_PPCALLBACKSTRACKER_H |
22 | #define PPTRACE_PPCALLBACKSTRACKER_H |
23 | |
24 | #include "clang/Lex/PPCallbacks.h" |
25 | #include "clang/Lex/Preprocessor.h" |
26 | #include "clang/Basic/SourceManager.h" |
27 | #include "llvm/ADT/ArrayRef.h" |
28 | #include "llvm/ADT/SmallSet.h" |
29 | #include "llvm/ADT/StringMap.h" |
30 | #include "llvm/ADT/StringRef.h" |
31 | #include "llvm/Support/GlobPattern.h" |
32 | #include <string> |
33 | #include <vector> |
34 | |
35 | namespace clang { |
36 | namespace pp_trace { |
37 | |
38 | // This struct represents one callback function argument by name and value. |
39 | struct Argument { |
40 | std::string Name; |
41 | std::string Value; |
42 | }; |
43 | |
44 | /// This class represents one callback call by name and an array |
45 | /// of arguments. |
46 | class CallbackCall { |
47 | public: |
48 | CallbackCall(llvm::StringRef Name) : Name(Name) {} |
49 | CallbackCall() = default; |
50 | |
51 | std::string Name; |
52 | std::vector<Argument> Arguments; |
53 | }; |
54 | |
55 | using FilterType = std::vector<std::pair<llvm::GlobPattern, bool>>; |
56 | |
57 | /// This class overrides the PPCallbacks class for tracking preprocessor |
58 | /// activity by means of its callback functions. |
59 | /// |
60 | /// This object is given a vector for storing the trace information, built up |
61 | /// of CallbackCall and subordinate Argument objects for representing the |
62 | /// callback calls and their arguments. It's a reference so the vector can |
63 | /// exist beyond the lifetime of this object, because it's deleted by the |
64 | /// preprocessor automatically in its destructor. |
65 | /// |
66 | /// This class supports a mechanism for inhibiting trace output for |
67 | /// specific callbacks by name, for the purpose of eliminating output for |
68 | /// callbacks of no interest that might clutter the output. |
69 | /// |
70 | /// Following the constructor and destructor function declarations, the |
71 | /// overridden callback functions are defined. The remaining functions are |
72 | /// helpers for recording the trace data, to reduce the coupling between it |
73 | /// and the recorded data structure. |
74 | class PPCallbacksTracker : public PPCallbacks { |
75 | public: |
76 | /// Note that all of the arguments are references, and owned |
77 | /// by the caller. |
78 | /// \param Filters - List of (Glob,Enabled) pairs used to filter callbacks. |
79 | /// \param CallbackCalls - Trace buffer. |
80 | /// \param PP - The preprocessor. Needed for getting some argument strings. |
81 | PPCallbacksTracker(const FilterType &Filters, |
82 | std::vector<CallbackCall> &CallbackCalls, |
83 | Preprocessor &PP); |
84 | |
85 | ~PPCallbacksTracker() override; |
86 | |
87 | // Overridden callback functions. |
88 | |
89 | void FileChanged(SourceLocation Loc, PPCallbacks::FileChangeReason Reason, |
90 | SrcMgr::CharacteristicKind FileType, |
91 | FileID PrevFID = FileID()) override; |
92 | void FileSkipped(const FileEntryRef &SkippedFile, const Token &FilenameTok, |
93 | SrcMgr::CharacteristicKind FileType) override; |
94 | void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, |
95 | llvm::StringRef FileName, bool IsAngled, |
96 | CharSourceRange FilenameRange, |
97 | OptionalFileEntryRef File, llvm::StringRef SearchPath, |
98 | llvm::StringRef RelativePath, |
99 | const Module *SuggestedModule, bool ModuleImported, |
100 | SrcMgr::CharacteristicKind FileType) override; |
101 | void moduleImport(SourceLocation ImportLoc, ModuleIdPath Path, |
102 | const Module *Imported) override; |
103 | void EndOfMainFile() override; |
104 | void Ident(SourceLocation Loc, llvm::StringRef str) override; |
105 | void PragmaDirective(SourceLocation Loc, |
106 | PragmaIntroducerKind Introducer) override; |
107 | void (SourceLocation Loc, const IdentifierInfo *Kind, |
108 | llvm::StringRef Str) override; |
109 | void PragmaDetectMismatch(SourceLocation Loc, llvm::StringRef Name, |
110 | llvm::StringRef Value) override; |
111 | void PragmaDebug(SourceLocation Loc, llvm::StringRef DebugType) override; |
112 | void PragmaMessage(SourceLocation Loc, llvm::StringRef Namespace, |
113 | PPCallbacks::PragmaMessageKind Kind, |
114 | llvm::StringRef Str) override; |
115 | void PragmaDiagnosticPush(SourceLocation Loc, |
116 | llvm::StringRef Namespace) override; |
117 | void PragmaDiagnosticPop(SourceLocation Loc, |
118 | llvm::StringRef Namespace) override; |
119 | void PragmaDiagnostic(SourceLocation Loc, llvm::StringRef Namespace, |
120 | diag::Severity mapping, llvm::StringRef Str) override; |
121 | void PragmaOpenCLExtension(SourceLocation NameLoc, const IdentifierInfo *Name, |
122 | SourceLocation StateLoc, unsigned State) override; |
123 | void PragmaWarning(SourceLocation Loc, PragmaWarningSpecifier WarningSpec, |
124 | llvm::ArrayRef<int> Ids) override; |
125 | void PragmaWarningPush(SourceLocation Loc, int Level) override; |
126 | void PragmaWarningPop(SourceLocation Loc) override; |
127 | void PragmaExecCharsetPush(SourceLocation Loc, StringRef Str) override; |
128 | void PragmaExecCharsetPop(SourceLocation Loc) override; |
129 | void MacroExpands(const Token &MacroNameTok, const MacroDefinition &MD, |
130 | SourceRange Range, const MacroArgs *Args) override; |
131 | void MacroDefined(const Token &MacroNameTok, |
132 | const MacroDirective *MD) override; |
133 | void MacroUndefined(const Token &MacroNameTok, const MacroDefinition &MD, |
134 | const MacroDirective *Undef) override; |
135 | void Defined(const Token &MacroNameTok, const MacroDefinition &MD, |
136 | SourceRange Range) override; |
137 | void SourceRangeSkipped(SourceRange Range, SourceLocation EndifLoc) override; |
138 | void If(SourceLocation Loc, SourceRange ConditionRange, |
139 | ConditionValueKind ConditionValue) override; |
140 | void Elif(SourceLocation Loc, SourceRange ConditionRange, |
141 | ConditionValueKind ConditionValue, SourceLocation IfLoc) override; |
142 | void Ifdef(SourceLocation Loc, const Token &MacroNameTok, |
143 | const MacroDefinition &MD) override; |
144 | void Ifndef(SourceLocation Loc, const Token &MacroNameTok, |
145 | const MacroDefinition &MD) override; |
146 | void Else(SourceLocation Loc, SourceLocation IfLoc) override; |
147 | void Endif(SourceLocation Loc, SourceLocation IfLoc) override; |
148 | |
149 | // Helper functions. |
150 | |
151 | /// Start a new callback. |
152 | void beginCallback(const char *Name); |
153 | |
154 | /// Append a string to the top trace item. |
155 | void append(const char *Str); |
156 | |
157 | /// Append a bool argument to the top trace item. |
158 | void appendArgument(const char *Name, bool Value); |
159 | |
160 | /// Append an int argument to the top trace item. |
161 | void appendArgument(const char *Name, int Value); |
162 | |
163 | /// Append a string argument to the top trace item. |
164 | void appendArgument(const char *Name, const char *Value); |
165 | |
166 | /// Append a string reference object argument to the top trace item. |
167 | void appendArgument(const char *Name, llvm::StringRef Value); |
168 | |
169 | /// Append a string object argument to the top trace item. |
170 | void appendArgument(const char *Name, const std::string &Value); |
171 | |
172 | /// Append a token argument to the top trace item. |
173 | void appendArgument(const char *Name, const Token &Value); |
174 | |
175 | /// Append an enum argument to the top trace item. |
176 | void appendArgument(const char *Name, int Value, const char *const Strings[]); |
177 | |
178 | /// Append a FileID argument to the top trace item. |
179 | void appendArgument(const char *Name, FileID Value); |
180 | |
181 | /// Append a FileEntryRef argument to the top trace item. |
182 | void appendArgument(const char *Name, OptionalFileEntryRef Value); |
183 | void appendArgument(const char *Name, FileEntryRef Value); |
184 | |
185 | /// Append a SourceLocation argument to the top trace item. |
186 | void appendArgument(const char *Name, SourceLocation Value); |
187 | |
188 | /// Append a SourceRange argument to the top trace item. |
189 | void appendArgument(const char *Name, SourceRange Value); |
190 | |
191 | /// Append a CharSourceRange argument to the top trace item. |
192 | void appendArgument(const char *Name, CharSourceRange Value); |
193 | |
194 | /// Append a ModuleIdPath argument to the top trace item. |
195 | void appendArgument(const char *Name, ModuleIdPath Value); |
196 | |
197 | /// Append an IdentifierInfo argument to the top trace item. |
198 | void appendArgument(const char *Name, const IdentifierInfo *Value); |
199 | |
200 | /// Append a MacroDirective argument to the top trace item. |
201 | void appendArgument(const char *Name, const MacroDirective *Value); |
202 | |
203 | /// Append a MacroDefinition argument to the top trace item. |
204 | void appendArgument(const char *Name, const MacroDefinition &Value); |
205 | |
206 | /// Append a MacroArgs argument to the top trace item. |
207 | void appendArgument(const char *Name, const MacroArgs *Value); |
208 | |
209 | /// Append a Module argument to the top trace item. |
210 | void appendArgument(const char *Name, const Module *Value); |
211 | |
212 | /// Append a double-quoted argument to the top trace item. |
213 | void appendQuotedArgument(const char *Name, const std::string &Value); |
214 | |
215 | /// Append a double-quoted file path argument to the top trace item. |
216 | void appendFilePathArgument(const char *Name, llvm::StringRef Value); |
217 | |
218 | /// Get the raw source string of the range. |
219 | llvm::StringRef getSourceString(CharSourceRange Range); |
220 | |
221 | /// Callback trace information. |
222 | /// We use a reference so the trace will be preserved for the caller |
223 | /// after this object is destructed. |
224 | std::vector<CallbackCall> &CallbackCalls; |
225 | |
226 | // List of (Glob,Enabled) pairs used to filter callbacks. |
227 | const FilterType &Filters; |
228 | |
229 | // Whether a callback should be printed. |
230 | llvm::StringMap<bool> CallbackIsEnabled; |
231 | |
232 | /// Inhibit trace while this is set. |
233 | bool DisableTrace; |
234 | |
235 | Preprocessor &PP; |
236 | }; |
237 | |
238 | } // namespace pp_trace |
239 | } // namespace clang |
240 | |
241 | #endif // PPTRACE_PPCALLBACKSTRACKER_H |
242 | |