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
24namespace clang {
25class Token;
26class IdentifierInfo;
27class MacroDefinition;
28class MacroDirective;
29class MacroArgs;
30struct 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.
36class PPCallbacks {
37public:
38 virtual ~PPCallbacks();
39
40 enum FileChangeReason {
41 EnterFile, ExitFile, SystemHeaderPragma, 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 PragmaComment(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.
470class PPChainedCallbacks : public PPCallbacks {
471 std::unique_ptr<PPCallbacks> First, Second;
472
473public:
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 PragmaComment(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