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

source code of clang/include/clang/Lex/PPCallbacks.h