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