1 | //===--- PPCallbacks.h - Callbacks for Preprocessor actions -----*- 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 | /// Defines the PPCallbacks interface. |
11 | /// |
12 | //===----------------------------------------------------------------------===// |
13 | |
14 | #ifndef LLVM_CLANG_LEX_PPCALLBACKS_H |
15 | #define LLVM_CLANG_LEX_PPCALLBACKS_H |
16 | |
17 | #include "clang/Basic/DiagnosticIDs.h" |
18 | #include "clang/Basic/SourceLocation.h" |
19 | #include "clang/Basic/SourceManager.h" |
20 | #include "clang/Lex/ModuleLoader.h" |
21 | #include "clang/Lex/Pragma.h" |
22 | #include "llvm/ADT/StringRef.h" |
23 | |
24 | namespace clang { |
25 | class Token; |
26 | class IdentifierInfo; |
27 | class MacroDefinition; |
28 | class MacroDirective; |
29 | class MacroArgs; |
30 | struct LexEmbedParametersResult; |
31 | |
32 | /// This interface provides a way to observe the actions of the |
33 | /// preprocessor as it does its thing. |
34 | /// |
35 | /// Clients can define their hooks here to implement preprocessor level tools. |
36 | class PPCallbacks { |
37 | public: |
38 | virtual ~PPCallbacks(); |
39 | |
40 | enum FileChangeReason { |
41 | EnterFile, ExitFile, , RenameFile |
42 | }; |
43 | |
44 | /// Callback invoked whenever a source file is entered or exited. |
45 | /// |
46 | /// \param Loc Indicates the new location. |
47 | /// \param PrevFID the file that was exited if \p Reason is ExitFile or the |
48 | /// the file before the new one entered for \p Reason EnterFile. |
49 | virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason, |
50 | SrcMgr::CharacteristicKind FileType, |
51 | FileID PrevFID = FileID()) { |
52 | } |
53 | |
54 | enum class LexedFileChangeReason { EnterFile, ExitFile }; |
55 | |
56 | /// Callback invoked whenever the \p Lexer moves to a different file for |
57 | /// lexing. Unlike \p FileChanged line number directives and other related |
58 | /// pragmas do not trigger callbacks to \p LexedFileChanged. |
59 | /// |
60 | /// \param FID The \p FileID that the \p Lexer moved to. |
61 | /// |
62 | /// \param Reason Whether the \p Lexer entered a new file or exited one. |
63 | /// |
64 | /// \param FileType The \p CharacteristicKind of the file the \p Lexer moved |
65 | /// to. |
66 | /// |
67 | /// \param PrevFID The \p FileID the \p Lexer was using before the change. |
68 | /// |
69 | /// \param Loc The location where the \p Lexer entered a new file from or the |
70 | /// location that the \p Lexer moved into after exiting a file. |
71 | virtual void LexedFileChanged(FileID FID, LexedFileChangeReason Reason, |
72 | SrcMgr::CharacteristicKind FileType, |
73 | FileID PrevFID, SourceLocation Loc) {} |
74 | |
75 | /// Callback invoked whenever a source file is skipped as the result |
76 | /// of header guard optimization. |
77 | /// |
78 | /// \param SkippedFile The file that is skipped instead of entering \#include |
79 | /// |
80 | /// \param FilenameTok The file name token in \#include "FileName" directive |
81 | /// or macro expanded file name token from \#include MACRO(PARAMS) directive. |
82 | /// Note that FilenameTok contains corresponding quotes/angles symbols. |
83 | virtual void FileSkipped(const FileEntryRef &SkippedFile, |
84 | const Token &FilenameTok, |
85 | SrcMgr::CharacteristicKind FileType) {} |
86 | |
87 | /// Callback invoked whenever the preprocessor cannot find a file for an |
88 | /// embed directive. |
89 | /// |
90 | /// \param FileName The name of the file being included, as written in the |
91 | /// source code. |
92 | /// |
93 | /// \returns true to indicate that the preprocessor should skip this file |
94 | /// and not issue any diagnostic. |
95 | virtual bool EmbedFileNotFound(StringRef FileName) { return false; } |
96 | |
97 | /// Callback invoked whenever an embed directive has been processed, |
98 | /// regardless of whether the embed will actually find a file. |
99 | /// |
100 | /// \param HashLoc The location of the '#' that starts the embed directive. |
101 | /// |
102 | /// \param FileName The name of the file being included, as written in the |
103 | /// source code. |
104 | /// |
105 | /// \param IsAngled Whether the file name was enclosed in angle brackets; |
106 | /// otherwise, it was enclosed in quotes. |
107 | /// |
108 | /// \param File The actual file that may be included by this embed directive. |
109 | /// |
110 | /// \param Params The parameters used by the directive. |
111 | virtual void EmbedDirective(SourceLocation HashLoc, StringRef FileName, |
112 | bool IsAngled, OptionalFileEntryRef File, |
113 | const LexEmbedParametersResult &Params) {} |
114 | |
115 | /// Callback invoked whenever the preprocessor cannot find a file for an |
116 | /// inclusion directive. |
117 | /// |
118 | /// \param FileName The name of the file being included, as written in the |
119 | /// source code. |
120 | /// |
121 | /// \returns true to indicate that the preprocessor should skip this file |
122 | /// and not issue any diagnostic. |
123 | virtual bool FileNotFound(StringRef FileName) { return false; } |
124 | |
125 | /// Callback invoked whenever an inclusion directive of |
126 | /// any kind (\c \#include, \c \#import, etc.) has been processed, regardless |
127 | /// of whether the inclusion will actually result in an inclusion. |
128 | /// |
129 | /// \param HashLoc The location of the '#' that starts the inclusion |
130 | /// directive. |
131 | /// |
132 | /// \param IncludeTok The token that indicates the kind of inclusion |
133 | /// directive, e.g., 'include' or 'import'. |
134 | /// |
135 | /// \param FileName The name of the file being included, as written in the |
136 | /// source code. |
137 | /// |
138 | /// \param IsAngled Whether the file name was enclosed in angle brackets; |
139 | /// otherwise, it was enclosed in quotes. |
140 | /// |
141 | /// \param FilenameRange The character range of the quotes or angle brackets |
142 | /// for the written file name. |
143 | /// |
144 | /// \param File The actual file that may be included by this inclusion |
145 | /// directive. |
146 | /// |
147 | /// \param SearchPath Contains the search path which was used to find the file |
148 | /// in the file system. If the file was found via an absolute include path, |
149 | /// SearchPath will be empty. For framework includes, the SearchPath and |
150 | /// RelativePath will be split up. For example, if an include of "Some/Some.h" |
151 | /// is found via the framework path |
152 | /// "path/to/Frameworks/Some.framework/Headers/Some.h", SearchPath will be |
153 | /// "path/to/Frameworks/Some.framework/Headers" and RelativePath will be |
154 | /// "Some.h". |
155 | /// |
156 | /// \param RelativePath The path relative to SearchPath, at which the include |
157 | /// file was found. This is equal to FileName except for framework includes. |
158 | /// |
159 | /// \param SuggestedModule The module suggested for this header, if any. |
160 | /// |
161 | /// \param ModuleImported Whether this include was translated into import of |
162 | /// \p SuggestedModule. |
163 | /// |
164 | /// \param FileType The characteristic kind, indicates whether a file or |
165 | /// directory holds normal user code, system code, or system code which is |
166 | /// implicitly 'extern "C"' in C++ mode. |
167 | /// |
168 | virtual void InclusionDirective(SourceLocation HashLoc, |
169 | const Token &IncludeTok, StringRef FileName, |
170 | bool IsAngled, CharSourceRange FilenameRange, |
171 | OptionalFileEntryRef File, |
172 | StringRef SearchPath, StringRef RelativePath, |
173 | const Module *SuggestedModule, |
174 | bool ModuleImported, |
175 | SrcMgr::CharacteristicKind FileType) {} |
176 | |
177 | /// Callback invoked whenever a submodule was entered. |
178 | /// |
179 | /// \param M The submodule we have entered. |
180 | /// |
181 | /// \param ImportLoc The location of import directive token. |
182 | /// |
183 | /// \param ForPragma If entering from pragma directive. |
184 | /// |
185 | virtual void EnteredSubmodule(Module *M, SourceLocation ImportLoc, |
186 | bool ForPragma) { } |
187 | |
188 | /// Callback invoked whenever a submodule was left. |
189 | /// |
190 | /// \param M The submodule we have left. |
191 | /// |
192 | /// \param ImportLoc The location of import directive token. |
193 | /// |
194 | /// \param ForPragma If entering from pragma directive. |
195 | /// |
196 | virtual void LeftSubmodule(Module *M, SourceLocation ImportLoc, |
197 | bool ForPragma) { } |
198 | |
199 | /// Callback invoked whenever there was an explicit module-import |
200 | /// syntax. |
201 | /// |
202 | /// \param ImportLoc The location of import directive token. |
203 | /// |
204 | /// \param Path The identifiers (and their locations) of the module |
205 | /// "path", e.g., "std.vector" would be split into "std" and "vector". |
206 | /// |
207 | /// \param Imported The imported module; can be null if importing failed. |
208 | /// |
209 | virtual void moduleImport(SourceLocation ImportLoc, |
210 | ModuleIdPath Path, |
211 | const Module *Imported) { |
212 | } |
213 | |
214 | /// Callback invoked when the end of the main file is reached. |
215 | /// |
216 | /// No subsequent callbacks will be made. |
217 | virtual void EndOfMainFile() { |
218 | } |
219 | |
220 | /// Callback invoked when a \#ident or \#sccs directive is read. |
221 | /// \param Loc The location of the directive. |
222 | /// \param str The text of the directive. |
223 | /// |
224 | virtual void Ident(SourceLocation Loc, StringRef str) { |
225 | } |
226 | |
227 | /// Callback invoked when start reading any pragma directive. |
228 | virtual void PragmaDirective(SourceLocation Loc, |
229 | PragmaIntroducerKind Introducer) { |
230 | } |
231 | |
232 | /// Callback invoked when a \#pragma comment directive is read. |
233 | virtual void (SourceLocation Loc, const IdentifierInfo *Kind, |
234 | StringRef Str) { |
235 | } |
236 | |
237 | /// Callback invoked when a \#pragma mark comment is read. |
238 | virtual void PragmaMark(SourceLocation Loc, StringRef Trivia) { |
239 | } |
240 | |
241 | /// Callback invoked when a \#pragma detect_mismatch directive is |
242 | /// read. |
243 | virtual void PragmaDetectMismatch(SourceLocation Loc, StringRef Name, |
244 | StringRef Value) { |
245 | } |
246 | |
247 | /// Callback invoked when a \#pragma clang __debug directive is read. |
248 | /// \param Loc The location of the debug directive. |
249 | /// \param DebugType The identifier following __debug. |
250 | virtual void PragmaDebug(SourceLocation Loc, StringRef DebugType) { |
251 | } |
252 | |
253 | /// Determines the kind of \#pragma invoking a call to PragmaMessage. |
254 | enum PragmaMessageKind { |
255 | /// \#pragma message has been invoked. |
256 | PMK_Message, |
257 | |
258 | /// \#pragma GCC warning has been invoked. |
259 | PMK_Warning, |
260 | |
261 | /// \#pragma GCC error has been invoked. |
262 | PMK_Error |
263 | }; |
264 | |
265 | /// Callback invoked when a \#pragma message directive is read. |
266 | /// \param Loc The location of the message directive. |
267 | /// \param Namespace The namespace of the message directive. |
268 | /// \param Kind The type of the message directive. |
269 | /// \param Str The text of the message directive. |
270 | virtual void PragmaMessage(SourceLocation Loc, StringRef Namespace, |
271 | PragmaMessageKind Kind, StringRef Str) { |
272 | } |
273 | |
274 | /// Callback invoked when a \#pragma gcc diagnostic push directive |
275 | /// is read. |
276 | virtual void PragmaDiagnosticPush(SourceLocation Loc, |
277 | StringRef Namespace) { |
278 | } |
279 | |
280 | /// Callback invoked when a \#pragma gcc diagnostic pop directive |
281 | /// is read. |
282 | virtual void PragmaDiagnosticPop(SourceLocation Loc, |
283 | StringRef Namespace) { |
284 | } |
285 | |
286 | /// Callback invoked when a \#pragma gcc diagnostic directive is read. |
287 | virtual void PragmaDiagnostic(SourceLocation Loc, StringRef Namespace, |
288 | diag::Severity mapping, StringRef Str) {} |
289 | |
290 | /// Called when an OpenCL extension is either disabled or |
291 | /// enabled with a pragma. |
292 | virtual void PragmaOpenCLExtension(SourceLocation NameLoc, |
293 | const IdentifierInfo *Name, |
294 | SourceLocation StateLoc, unsigned State) { |
295 | } |
296 | |
297 | /// Callback invoked when a \#pragma warning directive is read. |
298 | enum PragmaWarningSpecifier { |
299 | PWS_Default, |
300 | PWS_Disable, |
301 | PWS_Error, |
302 | PWS_Once, |
303 | PWS_Suppress, |
304 | PWS_Level1, |
305 | PWS_Level2, |
306 | PWS_Level3, |
307 | PWS_Level4, |
308 | }; |
309 | virtual void PragmaWarning(SourceLocation Loc, |
310 | PragmaWarningSpecifier WarningSpec, |
311 | ArrayRef<int> Ids) {} |
312 | |
313 | /// Callback invoked when a \#pragma warning(push) directive is read. |
314 | virtual void PragmaWarningPush(SourceLocation Loc, int Level) { |
315 | } |
316 | |
317 | /// Callback invoked when a \#pragma warning(pop) directive is read. |
318 | virtual void PragmaWarningPop(SourceLocation Loc) { |
319 | } |
320 | |
321 | /// Callback invoked when a \#pragma execution_character_set(push) directive |
322 | /// is read. |
323 | virtual void PragmaExecCharsetPush(SourceLocation Loc, StringRef Str) {} |
324 | |
325 | /// Callback invoked when a \#pragma execution_character_set(pop) directive |
326 | /// is read. |
327 | virtual void PragmaExecCharsetPop(SourceLocation Loc) {} |
328 | |
329 | /// Callback invoked when a \#pragma clang assume_nonnull begin directive |
330 | /// is read. |
331 | virtual void PragmaAssumeNonNullBegin(SourceLocation Loc) {} |
332 | |
333 | /// Callback invoked when a \#pragma clang assume_nonnull end directive |
334 | /// is read. |
335 | virtual void PragmaAssumeNonNullEnd(SourceLocation Loc) {} |
336 | |
337 | /// Called by Preprocessor::HandleMacroExpandedIdentifier when a |
338 | /// macro invocation is found. |
339 | virtual void MacroExpands(const Token &MacroNameTok, |
340 | const MacroDefinition &MD, SourceRange Range, |
341 | const MacroArgs *Args) {} |
342 | |
343 | /// Hook called whenever a macro definition is seen. |
344 | virtual void MacroDefined(const Token &MacroNameTok, |
345 | const MacroDirective *MD) { |
346 | } |
347 | |
348 | /// Hook called whenever a macro \#undef is seen. |
349 | /// \param MacroNameTok The active Token |
350 | /// \param MD A MacroDefinition for the named macro. |
351 | /// \param Undef New MacroDirective if the macro was defined, null otherwise. |
352 | /// |
353 | /// MD is released immediately following this callback. |
354 | virtual void MacroUndefined(const Token &MacroNameTok, |
355 | const MacroDefinition &MD, |
356 | const MacroDirective *Undef) { |
357 | } |
358 | |
359 | /// Hook called whenever the 'defined' operator is seen. |
360 | /// \param MD The MacroDirective if the name was a macro, null otherwise. |
361 | virtual void Defined(const Token &MacroNameTok, const MacroDefinition &MD, |
362 | SourceRange Range) { |
363 | } |
364 | |
365 | /// Hook called when a '__has_embed' directive is read. |
366 | virtual void HasEmbed(SourceLocation Loc, StringRef FileName, bool IsAngled, |
367 | OptionalFileEntryRef File) {} |
368 | |
369 | /// Hook called when a '__has_include' or '__has_include_next' directive is |
370 | /// read. |
371 | virtual void HasInclude(SourceLocation Loc, StringRef FileName, bool IsAngled, |
372 | OptionalFileEntryRef File, |
373 | SrcMgr::CharacteristicKind FileType); |
374 | |
375 | /// Hook called when a source range is skipped. |
376 | /// \param Range The SourceRange that was skipped. The range begins at the |
377 | /// \#if/\#else directive and ends after the \#endif/\#else directive. |
378 | /// \param EndifLoc The end location of the 'endif' token, which may precede |
379 | /// the range skipped by the directive (e.g excluding comments after an |
380 | /// 'endif'). |
381 | virtual void SourceRangeSkipped(SourceRange Range, SourceLocation EndifLoc) { |
382 | } |
383 | |
384 | enum ConditionValueKind { |
385 | CVK_NotEvaluated, CVK_False, CVK_True |
386 | }; |
387 | |
388 | /// Hook called whenever an \#if is seen. |
389 | /// \param Loc the source location of the directive. |
390 | /// \param ConditionRange The SourceRange of the expression being tested. |
391 | /// \param ConditionValue The evaluated value of the condition. |
392 | /// |
393 | // FIXME: better to pass in a list (or tree!) of Tokens. |
394 | virtual void If(SourceLocation Loc, SourceRange ConditionRange, |
395 | ConditionValueKind ConditionValue) { |
396 | } |
397 | |
398 | /// Hook called whenever an \#elif is seen. |
399 | /// \param Loc the source location of the directive. |
400 | /// \param ConditionRange The SourceRange of the expression being tested. |
401 | /// \param ConditionValue The evaluated value of the condition. |
402 | /// \param IfLoc the source location of the \#if/\#ifdef/\#ifndef directive. |
403 | // FIXME: better to pass in a list (or tree!) of Tokens. |
404 | virtual void Elif(SourceLocation Loc, SourceRange ConditionRange, |
405 | ConditionValueKind ConditionValue, SourceLocation IfLoc) { |
406 | } |
407 | |
408 | /// Hook called whenever an \#ifdef is seen. |
409 | /// \param Loc the source location of the directive. |
410 | /// \param MacroNameTok Information on the token being tested. |
411 | /// \param MD The MacroDefinition if the name was a macro, null otherwise. |
412 | virtual void Ifdef(SourceLocation Loc, const Token &MacroNameTok, |
413 | const MacroDefinition &MD) { |
414 | } |
415 | |
416 | /// Hook called whenever an \#elifdef branch is taken. |
417 | /// \param Loc the source location of the directive. |
418 | /// \param MacroNameTok Information on the token being tested. |
419 | /// \param MD The MacroDefinition if the name was a macro, null otherwise. |
420 | virtual void Elifdef(SourceLocation Loc, const Token &MacroNameTok, |
421 | const MacroDefinition &MD) { |
422 | } |
423 | /// Hook called whenever an \#elifdef is skipped. |
424 | /// \param Loc the source location of the directive. |
425 | /// \param ConditionRange The SourceRange of the expression being tested. |
426 | /// \param IfLoc the source location of the \#if/\#ifdef/\#ifndef directive. |
427 | // FIXME: better to pass in a list (or tree!) of Tokens. |
428 | virtual void Elifdef(SourceLocation Loc, SourceRange ConditionRange, |
429 | SourceLocation IfLoc) { |
430 | } |
431 | |
432 | /// Hook called whenever an \#ifndef is seen. |
433 | /// \param Loc the source location of the directive. |
434 | /// \param MacroNameTok Information on the token being tested. |
435 | /// \param MD The MacroDefiniton if the name was a macro, null otherwise. |
436 | virtual void Ifndef(SourceLocation Loc, const Token &MacroNameTok, |
437 | const MacroDefinition &MD) { |
438 | } |
439 | |
440 | /// Hook called whenever an \#elifndef branch is taken. |
441 | /// \param Loc the source location of the directive. |
442 | /// \param MacroNameTok Information on the token being tested. |
443 | /// \param MD The MacroDefinition if the name was a macro, null otherwise. |
444 | virtual void Elifndef(SourceLocation Loc, const Token &MacroNameTok, |
445 | const MacroDefinition &MD) { |
446 | } |
447 | /// Hook called whenever an \#elifndef is skipped. |
448 | /// \param Loc the source location of the directive. |
449 | /// \param ConditionRange The SourceRange of the expression being tested. |
450 | /// \param IfLoc the source location of the \#if/\#ifdef/\#ifndef directive. |
451 | // FIXME: better to pass in a list (or tree!) of Tokens. |
452 | virtual void Elifndef(SourceLocation Loc, SourceRange ConditionRange, |
453 | SourceLocation IfLoc) { |
454 | } |
455 | |
456 | /// Hook called whenever an \#else is seen. |
457 | /// \param Loc the source location of the directive. |
458 | /// \param IfLoc the source location of the \#if/\#ifdef/\#ifndef directive. |
459 | virtual void Else(SourceLocation Loc, SourceLocation IfLoc) { |
460 | } |
461 | |
462 | /// Hook called whenever an \#endif is seen. |
463 | /// \param Loc the source location of the directive. |
464 | /// \param IfLoc the source location of the \#if/\#ifdef/\#ifndef directive. |
465 | virtual void Endif(SourceLocation Loc, SourceLocation IfLoc) { |
466 | } |
467 | }; |
468 | |
469 | /// Simple wrapper class for chaining callbacks. |
470 | class PPChainedCallbacks : public PPCallbacks { |
471 | std::unique_ptr<PPCallbacks> First, Second; |
472 | |
473 | public: |
474 | PPChainedCallbacks(std::unique_ptr<PPCallbacks> _First, |
475 | std::unique_ptr<PPCallbacks> _Second) |
476 | : First(std::move(_First)), Second(std::move(_Second)) {} |
477 | |
478 | ~PPChainedCallbacks() override; |
479 | |
480 | void FileChanged(SourceLocation Loc, FileChangeReason Reason, |
481 | SrcMgr::CharacteristicKind FileType, |
482 | FileID PrevFID) override { |
483 | First->FileChanged(Loc, Reason, FileType, PrevFID); |
484 | Second->FileChanged(Loc, Reason, FileType, PrevFID); |
485 | } |
486 | |
487 | void LexedFileChanged(FileID FID, LexedFileChangeReason Reason, |
488 | SrcMgr::CharacteristicKind FileType, FileID PrevFID, |
489 | SourceLocation Loc) override { |
490 | First->LexedFileChanged(FID, Reason, FileType, PrevFID, Loc); |
491 | Second->LexedFileChanged(FID, Reason, FileType, PrevFID, Loc); |
492 | } |
493 | |
494 | void FileSkipped(const FileEntryRef &SkippedFile, const Token &FilenameTok, |
495 | SrcMgr::CharacteristicKind FileType) override { |
496 | First->FileSkipped(SkippedFile, FilenameTok, FileType); |
497 | Second->FileSkipped(SkippedFile, FilenameTok, FileType); |
498 | } |
499 | |
500 | bool EmbedFileNotFound(StringRef FileName) override { |
501 | bool Skip = First->FileNotFound(FileName); |
502 | // Make sure to invoke the second callback, no matter if the first already |
503 | // returned true to skip the file. |
504 | Skip |= Second->FileNotFound(FileName); |
505 | return Skip; |
506 | } |
507 | |
508 | void EmbedDirective(SourceLocation HashLoc, StringRef FileName, bool IsAngled, |
509 | OptionalFileEntryRef File, |
510 | const LexEmbedParametersResult &Params) override { |
511 | First->EmbedDirective(HashLoc, FileName, IsAngled, File, Params); |
512 | Second->EmbedDirective(HashLoc, FileName, IsAngled, File, Params); |
513 | } |
514 | |
515 | bool FileNotFound(StringRef FileName) override { |
516 | bool Skip = First->FileNotFound(FileName); |
517 | // Make sure to invoke the second callback, no matter if the first already |
518 | // returned true to skip the file. |
519 | Skip |= Second->FileNotFound(FileName); |
520 | return Skip; |
521 | } |
522 | |
523 | void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, |
524 | StringRef FileName, bool IsAngled, |
525 | CharSourceRange FilenameRange, |
526 | OptionalFileEntryRef File, StringRef SearchPath, |
527 | StringRef RelativePath, const Module *SuggestedModule, |
528 | bool ModuleImported, |
529 | SrcMgr::CharacteristicKind FileType) override { |
530 | First->InclusionDirective(HashLoc, IncludeTok, FileName, IsAngled, |
531 | FilenameRange, File, SearchPath, RelativePath, |
532 | SuggestedModule, ModuleImported, FileType); |
533 | Second->InclusionDirective(HashLoc, IncludeTok, FileName, IsAngled, |
534 | FilenameRange, File, SearchPath, RelativePath, |
535 | SuggestedModule, ModuleImported, FileType); |
536 | } |
537 | |
538 | void EnteredSubmodule(Module *M, SourceLocation ImportLoc, |
539 | bool ForPragma) override { |
540 | First->EnteredSubmodule(M, ImportLoc, ForPragma); |
541 | Second->EnteredSubmodule(M, ImportLoc, ForPragma); |
542 | } |
543 | |
544 | void LeftSubmodule(Module *M, SourceLocation ImportLoc, |
545 | bool ForPragma) override { |
546 | First->LeftSubmodule(M, ImportLoc, ForPragma); |
547 | Second->LeftSubmodule(M, ImportLoc, ForPragma); |
548 | } |
549 | |
550 | void moduleImport(SourceLocation ImportLoc, ModuleIdPath Path, |
551 | const Module *Imported) override { |
552 | First->moduleImport(ImportLoc, Path, Imported); |
553 | Second->moduleImport(ImportLoc, Path, Imported); |
554 | } |
555 | |
556 | void EndOfMainFile() override { |
557 | First->EndOfMainFile(); |
558 | Second->EndOfMainFile(); |
559 | } |
560 | |
561 | void Ident(SourceLocation Loc, StringRef str) override { |
562 | First->Ident(Loc, str); |
563 | Second->Ident(Loc, str); |
564 | } |
565 | |
566 | void PragmaDirective(SourceLocation Loc, |
567 | PragmaIntroducerKind Introducer) override { |
568 | First->PragmaDirective(Loc, Introducer); |
569 | Second->PragmaDirective(Loc, Introducer); |
570 | } |
571 | |
572 | void (SourceLocation Loc, const IdentifierInfo *Kind, |
573 | StringRef Str) override { |
574 | First->PragmaComment(Loc, Kind, Str); |
575 | Second->PragmaComment(Loc, Kind, Str); |
576 | } |
577 | |
578 | void PragmaMark(SourceLocation Loc, StringRef Trivia) override { |
579 | First->PragmaMark(Loc, Trivia); |
580 | Second->PragmaMark(Loc, Trivia); |
581 | } |
582 | |
583 | void PragmaDetectMismatch(SourceLocation Loc, StringRef Name, |
584 | StringRef Value) override { |
585 | First->PragmaDetectMismatch(Loc, Name, Value); |
586 | Second->PragmaDetectMismatch(Loc, Name, Value); |
587 | } |
588 | |
589 | void PragmaDebug(SourceLocation Loc, StringRef DebugType) override { |
590 | First->PragmaDebug(Loc, DebugType); |
591 | Second->PragmaDebug(Loc, DebugType); |
592 | } |
593 | |
594 | void PragmaMessage(SourceLocation Loc, StringRef Namespace, |
595 | PragmaMessageKind Kind, StringRef Str) override { |
596 | First->PragmaMessage(Loc, Namespace, Kind, Str); |
597 | Second->PragmaMessage(Loc, Namespace, Kind, Str); |
598 | } |
599 | |
600 | void PragmaDiagnosticPush(SourceLocation Loc, StringRef Namespace) override { |
601 | First->PragmaDiagnosticPush(Loc, Namespace); |
602 | Second->PragmaDiagnosticPush(Loc, Namespace); |
603 | } |
604 | |
605 | void PragmaDiagnosticPop(SourceLocation Loc, StringRef Namespace) override { |
606 | First->PragmaDiagnosticPop(Loc, Namespace); |
607 | Second->PragmaDiagnosticPop(Loc, Namespace); |
608 | } |
609 | |
610 | void PragmaDiagnostic(SourceLocation Loc, StringRef Namespace, |
611 | diag::Severity mapping, StringRef Str) override { |
612 | First->PragmaDiagnostic(Loc, Namespace, mapping, Str); |
613 | Second->PragmaDiagnostic(Loc, Namespace, mapping, Str); |
614 | } |
615 | |
616 | void HasEmbed(SourceLocation Loc, StringRef FileName, bool IsAngled, |
617 | OptionalFileEntryRef File) override { |
618 | First->HasEmbed(Loc, FileName, IsAngled, File); |
619 | Second->HasEmbed(Loc, FileName, IsAngled, File); |
620 | } |
621 | |
622 | void HasInclude(SourceLocation Loc, StringRef FileName, bool IsAngled, |
623 | OptionalFileEntryRef File, |
624 | SrcMgr::CharacteristicKind FileType) override; |
625 | |
626 | void PragmaOpenCLExtension(SourceLocation NameLoc, const IdentifierInfo *Name, |
627 | SourceLocation StateLoc, unsigned State) override { |
628 | First->PragmaOpenCLExtension(NameLoc, Name, StateLoc, State); |
629 | Second->PragmaOpenCLExtension(NameLoc, Name, StateLoc, State); |
630 | } |
631 | |
632 | void PragmaWarning(SourceLocation Loc, PragmaWarningSpecifier WarningSpec, |
633 | ArrayRef<int> Ids) override { |
634 | First->PragmaWarning(Loc, WarningSpec, Ids); |
635 | Second->PragmaWarning(Loc, WarningSpec, Ids); |
636 | } |
637 | |
638 | void PragmaWarningPush(SourceLocation Loc, int Level) override { |
639 | First->PragmaWarningPush(Loc, Level); |
640 | Second->PragmaWarningPush(Loc, Level); |
641 | } |
642 | |
643 | void PragmaWarningPop(SourceLocation Loc) override { |
644 | First->PragmaWarningPop(Loc); |
645 | Second->PragmaWarningPop(Loc); |
646 | } |
647 | |
648 | void PragmaExecCharsetPush(SourceLocation Loc, StringRef Str) override { |
649 | First->PragmaExecCharsetPush(Loc, Str); |
650 | Second->PragmaExecCharsetPush(Loc, Str); |
651 | } |
652 | |
653 | void PragmaExecCharsetPop(SourceLocation Loc) override { |
654 | First->PragmaExecCharsetPop(Loc); |
655 | Second->PragmaExecCharsetPop(Loc); |
656 | } |
657 | |
658 | void PragmaAssumeNonNullBegin(SourceLocation Loc) override { |
659 | First->PragmaAssumeNonNullBegin(Loc); |
660 | Second->PragmaAssumeNonNullBegin(Loc); |
661 | } |
662 | |
663 | void PragmaAssumeNonNullEnd(SourceLocation Loc) override { |
664 | First->PragmaAssumeNonNullEnd(Loc); |
665 | Second->PragmaAssumeNonNullEnd(Loc); |
666 | } |
667 | |
668 | void MacroExpands(const Token &MacroNameTok, const MacroDefinition &MD, |
669 | SourceRange Range, const MacroArgs *Args) override { |
670 | First->MacroExpands(MacroNameTok, MD, Range, Args); |
671 | Second->MacroExpands(MacroNameTok, MD, Range, Args); |
672 | } |
673 | |
674 | void MacroDefined(const Token &MacroNameTok, |
675 | const MacroDirective *MD) override { |
676 | First->MacroDefined(MacroNameTok, MD); |
677 | Second->MacroDefined(MacroNameTok, MD); |
678 | } |
679 | |
680 | void MacroUndefined(const Token &MacroNameTok, |
681 | const MacroDefinition &MD, |
682 | const MacroDirective *Undef) override { |
683 | First->MacroUndefined(MacroNameTok, MD, Undef); |
684 | Second->MacroUndefined(MacroNameTok, MD, Undef); |
685 | } |
686 | |
687 | void Defined(const Token &MacroNameTok, const MacroDefinition &MD, |
688 | SourceRange Range) override { |
689 | First->Defined(MacroNameTok, MD, Range); |
690 | Second->Defined(MacroNameTok, MD, Range); |
691 | } |
692 | |
693 | void SourceRangeSkipped(SourceRange Range, SourceLocation EndifLoc) override { |
694 | First->SourceRangeSkipped(Range, EndifLoc); |
695 | Second->SourceRangeSkipped(Range, EndifLoc); |
696 | } |
697 | |
698 | /// Hook called whenever an \#if is seen. |
699 | void If(SourceLocation Loc, SourceRange ConditionRange, |
700 | ConditionValueKind ConditionValue) override { |
701 | First->If(Loc, ConditionRange, ConditionValue); |
702 | Second->If(Loc, ConditionRange, ConditionValue); |
703 | } |
704 | |
705 | /// Hook called whenever an \#elif is seen. |
706 | void Elif(SourceLocation Loc, SourceRange ConditionRange, |
707 | ConditionValueKind ConditionValue, SourceLocation IfLoc) override { |
708 | First->Elif(Loc, ConditionRange, ConditionValue, IfLoc); |
709 | Second->Elif(Loc, ConditionRange, ConditionValue, IfLoc); |
710 | } |
711 | |
712 | /// Hook called whenever an \#ifdef is seen. |
713 | void Ifdef(SourceLocation Loc, const Token &MacroNameTok, |
714 | const MacroDefinition &MD) override { |
715 | First->Ifdef(Loc, MacroNameTok, MD); |
716 | Second->Ifdef(Loc, MacroNameTok, MD); |
717 | } |
718 | |
719 | /// Hook called whenever an \#elifdef is taken. |
720 | void Elifdef(SourceLocation Loc, const Token &MacroNameTok, |
721 | const MacroDefinition &MD) override { |
722 | First->Elifdef(Loc, MacroNameTok, MD); |
723 | Second->Elifdef(Loc, MacroNameTok, MD); |
724 | } |
725 | /// Hook called whenever an \#elifdef is skipped. |
726 | void Elifdef(SourceLocation Loc, SourceRange ConditionRange, |
727 | SourceLocation IfLoc) override { |
728 | First->Elifdef(Loc, ConditionRange, IfLoc); |
729 | Second->Elifdef(Loc, ConditionRange, IfLoc); |
730 | } |
731 | |
732 | /// Hook called whenever an \#ifndef is seen. |
733 | void Ifndef(SourceLocation Loc, const Token &MacroNameTok, |
734 | const MacroDefinition &MD) override { |
735 | First->Ifndef(Loc, MacroNameTok, MD); |
736 | Second->Ifndef(Loc, MacroNameTok, MD); |
737 | } |
738 | |
739 | /// Hook called whenever an \#elifndef is taken. |
740 | void Elifndef(SourceLocation Loc, const Token &MacroNameTok, |
741 | const MacroDefinition &MD) override { |
742 | First->Elifndef(Loc, MacroNameTok, MD); |
743 | Second->Elifndef(Loc, MacroNameTok, MD); |
744 | } |
745 | /// Hook called whenever an \#elifndef is skipped. |
746 | void Elifndef(SourceLocation Loc, SourceRange ConditionRange, |
747 | SourceLocation IfLoc) override { |
748 | First->Elifndef(Loc, ConditionRange, IfLoc); |
749 | Second->Elifndef(Loc, ConditionRange, IfLoc); |
750 | } |
751 | |
752 | /// Hook called whenever an \#else is seen. |
753 | void Else(SourceLocation Loc, SourceLocation IfLoc) override { |
754 | First->Else(Loc, IfLoc); |
755 | Second->Else(Loc, IfLoc); |
756 | } |
757 | |
758 | /// Hook called whenever an \#endif is seen. |
759 | void Endif(SourceLocation Loc, SourceLocation IfLoc) override { |
760 | First->Endif(Loc, IfLoc); |
761 | Second->Endif(Loc, IfLoc); |
762 | } |
763 | }; |
764 | |
765 | } // end namespace clang |
766 | |
767 | #endif |
768 | |