clang 24.0.0git
PPCallbacks.h
Go to the documentation of this file.
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
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;
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.
38public:
39 virtual ~PPCallbacks();
40
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.
52 FileID PrevFID = FileID()) {
53 }
54
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.
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,
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,
173 StringRef SearchPath, StringRef RelativePath,
174 const Module *SuggestedModule,
175 bool ModuleImported,
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 whenever a module load was skipped due to enabled
216 /// single-module-parse-mode.
217 ///
218 /// \param Skipped The module that was not loaded.
219 ///
220 virtual void moduleLoadSkipped(Module *Skipped) {}
221
222 /// Callback invoked when the end of the main file is reached.
223 ///
224 /// No subsequent callbacks will be made.
225 virtual void EndOfMainFile() {
226 }
227
228 /// Callback invoked when a \#ident or \#sccs directive is read.
229 /// \param Loc The location of the directive.
230 /// \param str The text of the directive.
231 ///
232 virtual void Ident(SourceLocation Loc, StringRef str) {
233 }
234
235 /// Callback invoked when start reading any pragma directive.
237 PragmaIntroducerKind Introducer) {
238 }
239
240 /// Callback invoked when a \#pragma comment directive is read.
241 virtual void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind,
242 StringRef Str) {
243 }
244
245 /// Callback invoked when a \#pragma mark comment is read.
246 virtual void PragmaMark(SourceLocation Loc, StringRef Trivia) {
247 }
248
249 /// Callback invoked when a \#pragma detect_mismatch directive is
250 /// read.
251 virtual void PragmaDetectMismatch(SourceLocation Loc, StringRef Name,
252 StringRef Value) {
253 }
254
255 /// Callback invoked when a \#pragma clang __debug directive is read.
256 /// \param Loc The location of the debug directive.
257 /// \param DebugType The identifier following __debug.
258 virtual void PragmaDebug(SourceLocation Loc, StringRef DebugType) {
259 }
260
261 /// Determines the kind of \#pragma invoking a call to PragmaMessage.
263 /// \#pragma message has been invoked.
265
266 /// \#pragma GCC warning has been invoked.
268
269 /// \#pragma GCC error has been invoked.
271 };
272
273 /// Callback invoked when a \#pragma message directive is read.
274 /// \param Loc The location of the message directive.
275 /// \param Namespace The namespace of the message directive.
276 /// \param Kind The type of the message directive.
277 /// \param Str The text of the message directive.
278 virtual void PragmaMessage(SourceLocation Loc, StringRef Namespace,
279 PragmaMessageKind Kind, StringRef Str) {
280 }
281
282 /// Callback invoked when a \#pragma gcc diagnostic push directive
283 /// is read.
285 StringRef Namespace) {
286 }
287
288 /// Callback invoked when a \#pragma gcc diagnostic pop directive
289 /// is read.
291 StringRef Namespace) {
292 }
293
294 /// Callback invoked when a \#pragma gcc diagnostic directive is read.
295 virtual void PragmaDiagnostic(SourceLocation Loc, StringRef Namespace,
296 diag::Severity mapping, StringRef Str) {}
297
298 /// Called when an OpenCL extension is either disabled or
299 /// enabled with a pragma.
301 const IdentifierInfo *Name,
302 SourceLocation StateLoc, unsigned State) {
303 }
304
305 /// Callback invoked when a \#pragma warning directive is read.
318 PragmaWarningSpecifier WarningSpec,
319 ArrayRef<int> Ids) {}
320
321 /// Callback invoked when a \#pragma warning(push) directive is read.
322 virtual void PragmaWarningPush(SourceLocation Loc, int Level) {
323 }
324
325 /// Callback invoked when a \#pragma warning(pop) directive is read.
327 }
328
329 /// Callback invoked when a \#pragma execution_character_set(push) directive
330 /// is read.
331 virtual void PragmaExecCharsetPush(SourceLocation Loc, StringRef Str) {}
332
333 /// Callback invoked when a \#pragma execution_character_set(pop) directive
334 /// is read.
336
337 /// Callback invoked when a \#pragma clang assume_nonnull begin directive
338 /// is read.
340
341 /// Callback invoked when a \#pragma clang assume_nonnull end directive
342 /// is read.
344
345 /// Callback invoked when a \#pragma clang __set_pp_state directive is read.
346 virtual void PragmaSetPPState(SourceLocation Loc, IdentifierInfo *MacroName,
347 std::uint64_t Value) {}
348
349 /// Called by Preprocessor::HandleMacroExpandedIdentifier when a
350 /// macro invocation is found.
351 virtual void MacroExpands(const Token &MacroNameTok,
352 const MacroDefinition &MD, SourceRange Range,
353 const MacroArgs *Args) {}
354
355 /// Hook called whenever a macro definition is seen.
356 virtual void MacroDefined(const Token &MacroNameTok,
357 const MacroDirective *MD) {
358 }
359
360 /// Hook called whenever a macro \#undef is seen.
361 /// \param MacroNameTok The active Token
362 /// \param MD A MacroDefinition for the named macro.
363 /// \param Undef New MacroDirective if the macro was defined, null otherwise.
364 ///
365 /// MD is released immediately following this callback.
366 virtual void MacroUndefined(const Token &MacroNameTok,
367 const MacroDefinition &MD,
368 const MacroDirective *Undef) {
369 }
370
371 /// Hook called whenever the 'defined' operator is seen.
372 /// \param MD The MacroDirective if the name was a macro, null otherwise.
373 virtual void Defined(const Token &MacroNameTok, const MacroDefinition &MD,
374 SourceRange Range) {
375 }
376
377 /// Hook called when a '__has_embed' directive is read.
378 virtual void HasEmbed(SourceLocation Loc, StringRef FileName, bool IsAngled,
380
381 /// Hook called when a '__has_include' or '__has_include_next' directive is
382 /// read.
383 virtual void HasInclude(SourceLocation Loc, StringRef FileName, bool IsAngled,
386
387 /// Hook called when a source range is skipped.
388 /// \param Range The SourceRange that was skipped. The range begins at the
389 /// \#if/\#else directive and ends after the \#endif/\#else directive.
390 /// \param EndifLoc The end location of the 'endif' token, which may precede
391 /// the range skipped by the directive (e.g excluding comments after an
392 /// 'endif').
393 virtual void SourceRangeSkipped(SourceRange Range, SourceLocation EndifLoc) {
394 }
395
399
400 /// Hook called whenever an \#if is seen.
401 /// \param Loc the source location of the directive.
402 /// \param ConditionRange The SourceRange of the expression being tested.
403 /// \param ConditionValue The evaluated value of the condition.
404 ///
405 // FIXME: better to pass in a list (or tree!) of Tokens.
406 virtual void If(SourceLocation Loc, SourceRange ConditionRange,
407 ConditionValueKind ConditionValue) {
408 }
409
410 /// Hook called whenever an \#elif is seen.
411 /// \param Loc the source location of the directive.
412 /// \param ConditionRange The SourceRange of the expression being tested.
413 /// \param ConditionValue The evaluated value of the condition.
414 /// \param IfLoc the source location of the \#if/\#ifdef/\#ifndef directive.
415 // FIXME: better to pass in a list (or tree!) of Tokens.
416 virtual void Elif(SourceLocation Loc, SourceRange ConditionRange,
417 ConditionValueKind ConditionValue, SourceLocation IfLoc) {
418 }
419
420 /// Hook called whenever an \#ifdef is seen.
421 /// \param Loc the source location of the directive.
422 /// \param MacroNameTok Information on the token being tested.
423 /// \param MD The MacroDefinition if the name was a macro, null otherwise.
424 virtual void Ifdef(SourceLocation Loc, const Token &MacroNameTok,
425 const MacroDefinition &MD) {
426 }
427
428 /// Hook called whenever an \#elifdef branch is taken.
429 /// \param Loc the source location of the directive.
430 /// \param MacroNameTok Information on the token being tested.
431 /// \param MD The MacroDefinition if the name was a macro, null otherwise.
432 virtual void Elifdef(SourceLocation Loc, const Token &MacroNameTok,
433 const MacroDefinition &MD) {
434 }
435 /// Hook called whenever an \#elifdef is skipped.
436 /// \param Loc the source location of the directive.
437 /// \param ConditionRange The SourceRange of the expression being tested.
438 /// \param IfLoc the source location of the \#if/\#ifdef/\#ifndef directive.
439 // FIXME: better to pass in a list (or tree!) of Tokens.
440 virtual void Elifdef(SourceLocation Loc, SourceRange ConditionRange,
441 SourceLocation IfLoc) {
442 }
443
444 /// Hook called whenever an \#ifndef is seen.
445 /// \param Loc the source location of the directive.
446 /// \param MacroNameTok Information on the token being tested.
447 /// \param MD The MacroDefiniton if the name was a macro, null otherwise.
448 virtual void Ifndef(SourceLocation Loc, const Token &MacroNameTok,
449 const MacroDefinition &MD) {
450 }
451
452 /// Hook called whenever an \#elifndef branch is taken.
453 /// \param Loc the source location of the directive.
454 /// \param MacroNameTok Information on the token being tested.
455 /// \param MD The MacroDefinition if the name was a macro, null otherwise.
456 virtual void Elifndef(SourceLocation Loc, const Token &MacroNameTok,
457 const MacroDefinition &MD) {
458 }
459 /// Hook called whenever an \#elifndef is skipped.
460 /// \param Loc the source location of the directive.
461 /// \param ConditionRange The SourceRange of the expression being tested.
462 /// \param IfLoc the source location of the \#if/\#ifdef/\#ifndef directive.
463 // FIXME: better to pass in a list (or tree!) of Tokens.
464 virtual void Elifndef(SourceLocation Loc, SourceRange ConditionRange,
465 SourceLocation IfLoc) {
466 }
467
468 /// Hook called whenever an \#else is seen.
469 /// \param Loc the source location of the directive.
470 /// \param IfLoc the source location of the \#if/\#ifdef/\#ifndef directive.
471 virtual void Else(SourceLocation Loc, SourceLocation IfLoc) {
472 }
473
474 /// Hook called whenever an \#endif is seen.
475 /// \param Loc the source location of the directive.
476 /// \param IfLoc the source location of the \#if/\#ifdef/\#ifndef directive.
477 virtual void Endif(SourceLocation Loc, SourceLocation IfLoc) {
478 }
479
480 /// Walk owned descendants. For each descendant whose raw pointer satisfies
481 /// `Pred`, release ownership from its owning unique_ptr and append the raw
482 /// pointer to `Released`. Default: leaf — no descendants to walk.
483 virtual void
484 releasePreservedDescendants(llvm::function_ref<bool(PPCallbacks *)> Pred,
486
487 /// Walk the subtree rooted at `CB` (recursing into descendants first), then
488 /// check `CB` itself. Any `CB` whose contents satisfy `Pred` has its
489 /// ownership released and the raw pointer appended to `Released`. After this
490 /// returns, `CB` may be safely reset/destroyed without freeing the released
491 /// pointers.
492 static void releaseIfPreserved(std::unique_ptr<PPCallbacks> &CB,
493 llvm::function_ref<bool(PPCallbacks *)> Pred,
495 if (!CB)
496 return;
497 CB->releasePreservedDescendants(Pred, Released);
498 if (Pred(CB.get()))
499 Released.push_back(CB.release());
500 }
501};
502
503/// Simple wrapper class for chaining callbacks.
505 std::unique_ptr<PPCallbacks> First, Second;
506
507public:
508 PPChainedCallbacks(std::unique_ptr<PPCallbacks> _First,
509 std::unique_ptr<PPCallbacks> _Second)
510 : First(std::move(_First)), Second(std::move(_Second)) {}
511
513
516 FileID PrevFID) override {
517 First->FileChanged(Loc, Reason, FileType, PrevFID);
518 Second->FileChanged(Loc, Reason, FileType, PrevFID);
519 }
520
523 SourceLocation Loc) override {
524 First->LexedFileChanged(FID, Reason, FileType, PrevFID, Loc);
525 Second->LexedFileChanged(FID, Reason, FileType, PrevFID, Loc);
526 }
527
528 void FileSkipped(const FileEntryRef &SkippedFile, const Token &FilenameTok,
530 First->FileSkipped(SkippedFile, FilenameTok, FileType);
531 Second->FileSkipped(SkippedFile, FilenameTok, FileType);
532 }
533
534 bool EmbedFileNotFound(StringRef FileName) override {
535 bool Skip = First->EmbedFileNotFound(FileName);
536 // Make sure to invoke the second callback, no matter if the first already
537 // returned true to skip the file.
538 Skip |= Second->EmbedFileNotFound(FileName);
539 return Skip;
540 }
541
542 void EmbedDirective(SourceLocation HashLoc, StringRef FileName, bool IsAngled,
544 const LexEmbedParametersResult &Params) override {
545 First->EmbedDirective(HashLoc, FileName, IsAngled, File, Params);
546 Second->EmbedDirective(HashLoc, FileName, IsAngled, File, Params);
547 }
548
549 bool FileNotFound(StringRef FileName) override {
550 bool Skip = First->FileNotFound(FileName);
551 // Make sure to invoke the second callback, no matter if the first already
552 // returned true to skip the file.
553 Skip |= Second->FileNotFound(FileName);
554 return Skip;
555 }
556
557 void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
558 StringRef FileName, bool IsAngled,
559 CharSourceRange FilenameRange,
560 OptionalFileEntryRef File, StringRef SearchPath,
561 StringRef RelativePath, const Module *SuggestedModule,
562 bool ModuleImported,
564 First->InclusionDirective(HashLoc, IncludeTok, FileName, IsAngled,
565 FilenameRange, File, SearchPath, RelativePath,
566 SuggestedModule, ModuleImported, FileType);
567 Second->InclusionDirective(HashLoc, IncludeTok, FileName, IsAngled,
568 FilenameRange, File, SearchPath, RelativePath,
569 SuggestedModule, ModuleImported, FileType);
570 }
571
573 bool ForPragma) override {
574 First->EnteredSubmodule(M, ImportLoc, ForPragma);
575 Second->EnteredSubmodule(M, ImportLoc, ForPragma);
576 }
577
579 bool ForPragma) override {
580 First->LeftSubmodule(M, ImportLoc, ForPragma);
581 Second->LeftSubmodule(M, ImportLoc, ForPragma);
582 }
583
585 const Module *Imported) override {
586 First->moduleImport(ImportLoc, Path, Imported);
587 Second->moduleImport(ImportLoc, Path, Imported);
588 }
589
590 void moduleLoadSkipped(Module *Skipped) override {
591 First->moduleLoadSkipped(Skipped);
592 Second->moduleLoadSkipped(Skipped);
593 }
594
595 void EndOfMainFile() override {
596 First->EndOfMainFile();
597 Second->EndOfMainFile();
598 }
599
600 void Ident(SourceLocation Loc, StringRef str) override {
601 First->Ident(Loc, str);
602 Second->Ident(Loc, str);
603 }
604
606 PragmaIntroducerKind Introducer) override {
607 First->PragmaDirective(Loc, Introducer);
608 Second->PragmaDirective(Loc, Introducer);
609 }
610
612 StringRef Str) override {
613 First->PragmaComment(Loc, Kind, Str);
614 Second->PragmaComment(Loc, Kind, Str);
615 }
616
617 void PragmaMark(SourceLocation Loc, StringRef Trivia) override {
618 First->PragmaMark(Loc, Trivia);
619 Second->PragmaMark(Loc, Trivia);
620 }
621
622 void PragmaDetectMismatch(SourceLocation Loc, StringRef Name,
623 StringRef Value) override {
624 First->PragmaDetectMismatch(Loc, Name, Value);
625 Second->PragmaDetectMismatch(Loc, Name, Value);
626 }
627
628 void PragmaDebug(SourceLocation Loc, StringRef DebugType) override {
629 First->PragmaDebug(Loc, DebugType);
630 Second->PragmaDebug(Loc, DebugType);
631 }
632
633 void PragmaMessage(SourceLocation Loc, StringRef Namespace,
634 PragmaMessageKind Kind, StringRef Str) override {
635 First->PragmaMessage(Loc, Namespace, Kind, Str);
636 Second->PragmaMessage(Loc, Namespace, Kind, Str);
637 }
638
639 void PragmaDiagnosticPush(SourceLocation Loc, StringRef Namespace) override {
640 First->PragmaDiagnosticPush(Loc, Namespace);
641 Second->PragmaDiagnosticPush(Loc, Namespace);
642 }
643
644 void PragmaDiagnosticPop(SourceLocation Loc, StringRef Namespace) override {
645 First->PragmaDiagnosticPop(Loc, Namespace);
646 Second->PragmaDiagnosticPop(Loc, Namespace);
647 }
648
649 void PragmaDiagnostic(SourceLocation Loc, StringRef Namespace,
650 diag::Severity mapping, StringRef Str) override {
651 First->PragmaDiagnostic(Loc, Namespace, mapping, Str);
652 Second->PragmaDiagnostic(Loc, Namespace, mapping, Str);
653 }
654
655 void HasEmbed(SourceLocation Loc, StringRef FileName, bool IsAngled,
656 OptionalFileEntryRef File) override {
657 First->HasEmbed(Loc, FileName, IsAngled, File);
658 Second->HasEmbed(Loc, FileName, IsAngled, File);
659 }
660
661 void HasInclude(SourceLocation Loc, StringRef FileName, bool IsAngled,
664
666 SourceLocation StateLoc, unsigned State) override {
667 First->PragmaOpenCLExtension(NameLoc, Name, StateLoc, State);
668 Second->PragmaOpenCLExtension(NameLoc, Name, StateLoc, State);
669 }
670
672 ArrayRef<int> Ids) override {
673 First->PragmaWarning(Loc, WarningSpec, Ids);
674 Second->PragmaWarning(Loc, WarningSpec, Ids);
675 }
676
677 void PragmaWarningPush(SourceLocation Loc, int Level) override {
678 First->PragmaWarningPush(Loc, Level);
679 Second->PragmaWarningPush(Loc, Level);
680 }
681
682 void PragmaWarningPop(SourceLocation Loc) override {
683 First->PragmaWarningPop(Loc);
684 Second->PragmaWarningPop(Loc);
685 }
686
687 void PragmaExecCharsetPush(SourceLocation Loc, StringRef Str) override {
688 First->PragmaExecCharsetPush(Loc, Str);
689 Second->PragmaExecCharsetPush(Loc, Str);
690 }
691
693 First->PragmaExecCharsetPop(Loc);
694 Second->PragmaExecCharsetPop(Loc);
695 }
696
698 First->PragmaAssumeNonNullBegin(Loc);
699 Second->PragmaAssumeNonNullBegin(Loc);
700 }
701
703 First->PragmaAssumeNonNullEnd(Loc);
704 Second->PragmaAssumeNonNullEnd(Loc);
705 }
706
708 std::uint64_t Value) override {
709 First->PragmaSetPPState(Loc, MacroName, Value);
710 Second->PragmaSetPPState(Loc, MacroName, Value);
711 }
712
713 void MacroExpands(const Token &MacroNameTok, const MacroDefinition &MD,
714 SourceRange Range, const MacroArgs *Args) override {
715 First->MacroExpands(MacroNameTok, MD, Range, Args);
716 Second->MacroExpands(MacroNameTok, MD, Range, Args);
717 }
718
719 void MacroDefined(const Token &MacroNameTok,
720 const MacroDirective *MD) override {
721 First->MacroDefined(MacroNameTok, MD);
722 Second->MacroDefined(MacroNameTok, MD);
723 }
724
725 void MacroUndefined(const Token &MacroNameTok,
726 const MacroDefinition &MD,
727 const MacroDirective *Undef) override {
728 First->MacroUndefined(MacroNameTok, MD, Undef);
729 Second->MacroUndefined(MacroNameTok, MD, Undef);
730 }
731
732 void Defined(const Token &MacroNameTok, const MacroDefinition &MD,
733 SourceRange Range) override {
734 First->Defined(MacroNameTok, MD, Range);
735 Second->Defined(MacroNameTok, MD, Range);
736 }
737
738 void SourceRangeSkipped(SourceRange Range, SourceLocation EndifLoc) override {
739 First->SourceRangeSkipped(Range, EndifLoc);
740 Second->SourceRangeSkipped(Range, EndifLoc);
741 }
742
743 /// Hook called whenever an \#if is seen.
744 void If(SourceLocation Loc, SourceRange ConditionRange,
745 ConditionValueKind ConditionValue) override {
746 First->If(Loc, ConditionRange, ConditionValue);
747 Second->If(Loc, ConditionRange, ConditionValue);
748 }
749
750 /// Hook called whenever an \#elif is seen.
751 void Elif(SourceLocation Loc, SourceRange ConditionRange,
752 ConditionValueKind ConditionValue, SourceLocation IfLoc) override {
753 First->Elif(Loc, ConditionRange, ConditionValue, IfLoc);
754 Second->Elif(Loc, ConditionRange, ConditionValue, IfLoc);
755 }
756
757 /// Hook called whenever an \#ifdef is seen.
758 void Ifdef(SourceLocation Loc, const Token &MacroNameTok,
759 const MacroDefinition &MD) override {
760 First->Ifdef(Loc, MacroNameTok, MD);
761 Second->Ifdef(Loc, MacroNameTok, MD);
762 }
763
764 /// Hook called whenever an \#elifdef is taken.
765 void Elifdef(SourceLocation Loc, const Token &MacroNameTok,
766 const MacroDefinition &MD) override {
767 First->Elifdef(Loc, MacroNameTok, MD);
768 Second->Elifdef(Loc, MacroNameTok, MD);
769 }
770 /// Hook called whenever an \#elifdef is skipped.
771 void Elifdef(SourceLocation Loc, SourceRange ConditionRange,
772 SourceLocation IfLoc) override {
773 First->Elifdef(Loc, ConditionRange, IfLoc);
774 Second->Elifdef(Loc, ConditionRange, IfLoc);
775 }
776
777 /// Hook called whenever an \#ifndef is seen.
778 void Ifndef(SourceLocation Loc, const Token &MacroNameTok,
779 const MacroDefinition &MD) override {
780 First->Ifndef(Loc, MacroNameTok, MD);
781 Second->Ifndef(Loc, MacroNameTok, MD);
782 }
783
784 /// Hook called whenever an \#elifndef is taken.
785 void Elifndef(SourceLocation Loc, const Token &MacroNameTok,
786 const MacroDefinition &MD) override {
787 First->Elifndef(Loc, MacroNameTok, MD);
788 Second->Elifndef(Loc, MacroNameTok, MD);
789 }
790 /// Hook called whenever an \#elifndef is skipped.
791 void Elifndef(SourceLocation Loc, SourceRange ConditionRange,
792 SourceLocation IfLoc) override {
793 First->Elifndef(Loc, ConditionRange, IfLoc);
794 Second->Elifndef(Loc, ConditionRange, IfLoc);
795 }
796
797 /// Hook called whenever an \#else is seen.
798 void Else(SourceLocation Loc, SourceLocation IfLoc) override {
799 First->Else(Loc, IfLoc);
800 Second->Else(Loc, IfLoc);
801 }
802
803 /// Hook called whenever an \#endif is seen.
804 void Endif(SourceLocation Loc, SourceLocation IfLoc) override {
805 First->Endif(Loc, IfLoc);
806 Second->Endif(Loc, IfLoc);
807 }
808
810 llvm::function_ref<bool(PPCallbacks *)> Pred,
811 SmallVectorImpl<PPCallbacks *> &Released) override {
812 releaseIfPreserved(First, Pred, Released);
813 releaseIfPreserved(Second, Pred, Released);
814 }
815};
816
817} // end namespace clang
818
819#endif
Defines the Diagnostic IDs-related interfaces.
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
llvm::MachO::FileType FileType
Definition MachO.h:46
Defines the clang::SourceLocation class and associated facilities.
Defines the SourceManager interface.
Represents a byte-granular source range.
A reference to a FileEntry that includes the name of the file as it was accessed by the FileManager's...
Definition FileEntry.h:57
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
One of these records is kept for each identifier that is lexed.
MacroArgs - An instance of this class captures information about the formal arguments specified to a ...
Definition MacroArgs.h:30
A description of the current definition of a macro.
Definition MacroInfo.h:596
Encapsulates changes to the "macros namespace" (the location where the macro name became active,...
Definition MacroInfo.h:314
Describes a module or submodule.
Definition Module.h:340
This interface provides a way to observe the actions of the preprocessor as it does its thing.
Definition PPCallbacks.h:37
virtual void HasEmbed(SourceLocation Loc, StringRef FileName, bool IsAngled, OptionalFileEntryRef File)
Hook called when a '__has_embed' directive is read.
virtual void PragmaExecCharsetPop(SourceLocation Loc)
Callback invoked when a #pragma execution_character_set(pop) directive is read.
virtual void PragmaDirective(SourceLocation Loc, PragmaIntroducerKind Introducer)
Callback invoked when start reading any pragma directive.
virtual void Defined(const Token &MacroNameTok, const MacroDefinition &MD, SourceRange Range)
Hook called whenever the 'defined' operator is seen.
virtual void PragmaDiagnosticPush(SourceLocation Loc, StringRef Namespace)
Callback invoked when a #pragma gcc diagnostic push directive is read.
virtual void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind, StringRef Str)
Callback invoked when a #pragma comment directive is read.
virtual void Elifndef(SourceLocation Loc, SourceRange ConditionRange, SourceLocation IfLoc)
Hook called whenever an #elifndef is skipped.
virtual void PragmaWarning(SourceLocation Loc, PragmaWarningSpecifier WarningSpec, ArrayRef< int > Ids)
virtual void MacroExpands(const Token &MacroNameTok, const MacroDefinition &MD, SourceRange Range, const MacroArgs *Args)
Called by Preprocessor::HandleMacroExpandedIdentifier when a macro invocation is found.
virtual void Elifndef(SourceLocation Loc, const Token &MacroNameTok, const MacroDefinition &MD)
Hook called whenever an #elifndef branch is taken.
virtual void releasePreservedDescendants(llvm::function_ref< bool(PPCallbacks *)> Pred, SmallVectorImpl< PPCallbacks * > &Released)
Walk owned descendants.
virtual ~PPCallbacks()
virtual void EnteredSubmodule(Module *M, SourceLocation ImportLoc, bool ForPragma)
Callback invoked whenever a submodule was entered.
static void releaseIfPreserved(std::unique_ptr< PPCallbacks > &CB, llvm::function_ref< bool(PPCallbacks *)> Pred, SmallVectorImpl< PPCallbacks * > &Released)
Walk the subtree rooted at CB (recursing into descendants first), then check CB itself.
virtual void Elif(SourceLocation Loc, SourceRange ConditionRange, ConditionValueKind ConditionValue, SourceLocation IfLoc)
Hook called whenever an #elif is seen.
virtual void PragmaDebug(SourceLocation Loc, StringRef DebugType)
Callback invoked when a #pragma clang __debug directive is read.
virtual void PragmaSetPPState(SourceLocation Loc, IdentifierInfo *MacroName, std::uint64_t Value)
Callback invoked when a #pragma clang __set_pp_state directive is read.
virtual void EndOfMainFile()
Callback invoked when the end of the main file is reached.
virtual void moduleLoadSkipped(Module *Skipped)
Callback invoked whenever a module load was skipped due to enabled single-module-parse-mode.
virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason, SrcMgr::CharacteristicKind FileType, FileID PrevFID=FileID())
Callback invoked whenever a source file is entered or exited.
Definition PPCallbacks.h:50
virtual void Ifndef(SourceLocation Loc, const Token &MacroNameTok, const MacroDefinition &MD)
Hook called whenever an #ifndef is seen.
virtual void If(SourceLocation Loc, SourceRange ConditionRange, ConditionValueKind ConditionValue)
Hook called whenever an #if is seen.
virtual void FileSkipped(const FileEntryRef &SkippedFile, const Token &FilenameTok, SrcMgr::CharacteristicKind FileType)
Callback invoked whenever a source file is skipped as the result of header guard optimization.
Definition PPCallbacks.h:84
virtual void MacroUndefined(const Token &MacroNameTok, const MacroDefinition &MD, const MacroDirective *Undef)
Hook called whenever a macro #undef is seen.
virtual void MacroDefined(const Token &MacroNameTok, const MacroDirective *MD)
Hook called whenever a macro definition is seen.
virtual void PragmaDiagnostic(SourceLocation Loc, StringRef Namespace, diag::Severity mapping, StringRef Str)
Callback invoked when a #pragma gcc diagnostic directive is read.
virtual void Ifdef(SourceLocation Loc, const Token &MacroNameTok, const MacroDefinition &MD)
Hook called whenever an #ifdef is seen.
virtual void PragmaOpenCLExtension(SourceLocation NameLoc, const IdentifierInfo *Name, SourceLocation StateLoc, unsigned State)
Called when an OpenCL extension is either disabled or enabled with a pragma.
PragmaWarningSpecifier
Callback invoked when a #pragma warning directive is read.
virtual void PragmaDetectMismatch(SourceLocation Loc, StringRef Name, StringRef Value)
Callback invoked when a #pragma detect_mismatch directive is read.
virtual void PragmaAssumeNonNullEnd(SourceLocation Loc)
Callback invoked when a #pragma clang assume_nonnull end directive is read.
virtual void PragmaAssumeNonNullBegin(SourceLocation Loc)
Callback invoked when a #pragma clang assume_nonnull begin directive is read.
virtual void PragmaMark(SourceLocation Loc, StringRef Trivia)
Callback invoked when a #pragma mark comment is read.
virtual void EmbedDirective(SourceLocation HashLoc, StringRef FileName, bool IsAngled, OptionalFileEntryRef File, const LexEmbedParametersResult &Params)
Callback invoked whenever an embed directive has been processed, regardless of whether the embed will...
virtual void Ident(SourceLocation Loc, StringRef str)
Callback invoked when a #ident or #sccs directive is read.
virtual void HasInclude(SourceLocation Loc, StringRef FileName, bool IsAngled, OptionalFileEntryRef File, SrcMgr::CharacteristicKind FileType)
Hook called when a '__has_include' or '__has_include_next' directive is read.
virtual void PragmaMessage(SourceLocation Loc, StringRef Namespace, PragmaMessageKind Kind, StringRef Str)
Callback invoked when a #pragma message directive is read.
virtual void Elifdef(SourceLocation Loc, SourceRange ConditionRange, SourceLocation IfLoc)
Hook called whenever an #elifdef is skipped.
virtual void SourceRangeSkipped(SourceRange Range, SourceLocation EndifLoc)
Hook called when a source range is skipped.
virtual void PragmaExecCharsetPush(SourceLocation Loc, StringRef Str)
Callback invoked when a #pragma execution_character_set(push) directive is read.
virtual void PragmaDiagnosticPop(SourceLocation Loc, StringRef Namespace)
Callback invoked when a #pragma gcc diagnostic pop directive is read.
virtual void PragmaWarningPop(SourceLocation Loc)
Callback invoked when a #pragma warning(pop) directive is read.
virtual void Elifdef(SourceLocation Loc, const Token &MacroNameTok, const MacroDefinition &MD)
Hook called whenever an #elifdef branch is taken.
virtual void LexedFileChanged(FileID FID, LexedFileChangeReason Reason, SrcMgr::CharacteristicKind FileType, FileID PrevFID, SourceLocation Loc)
Callback invoked whenever the Lexer moves to a different file for lexing.
Definition PPCallbacks.h:72
virtual void LeftSubmodule(Module *M, SourceLocation ImportLoc, bool ForPragma)
Callback invoked whenever a submodule was left.
virtual void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName, bool IsAngled, CharSourceRange FilenameRange, OptionalFileEntryRef File, StringRef SearchPath, StringRef RelativePath, const Module *SuggestedModule, bool ModuleImported, SrcMgr::CharacteristicKind FileType)
Callback invoked whenever an inclusion directive of any kind (#include, #import, etc....
virtual void Else(SourceLocation Loc, SourceLocation IfLoc)
Hook called whenever an #else is seen.
PragmaMessageKind
Determines the kind of #pragma invoking a call to PragmaMessage.
@ PMK_Warning
#pragma GCC warning has been invoked.
@ PMK_Error
#pragma GCC error has been invoked.
@ PMK_Message
#pragma message has been invoked.
virtual bool FileNotFound(StringRef FileName)
Callback invoked whenever the preprocessor cannot find a file for an inclusion directive.
virtual void PragmaWarningPush(SourceLocation Loc, int Level)
Callback invoked when a #pragma warning(push) directive is read.
virtual void moduleImport(SourceLocation ImportLoc, ModuleIdPath Path, const Module *Imported)
Callback invoked whenever there was an explicit module-import syntax.
virtual bool EmbedFileNotFound(StringRef FileName)
Callback invoked whenever the preprocessor cannot find a file for an embed directive.
Definition PPCallbacks.h:96
virtual void Endif(SourceLocation Loc, SourceLocation IfLoc)
Hook called whenever an #endif is seen.
void MacroUndefined(const Token &MacroNameTok, const MacroDefinition &MD, const MacroDirective *Undef) override
Hook called whenever a macro #undef is seen.
void EnteredSubmodule(Module *M, SourceLocation ImportLoc, bool ForPragma) override
Callback invoked whenever a submodule was entered.
void MacroExpands(const Token &MacroNameTok, const MacroDefinition &MD, SourceRange Range, const MacroArgs *Args) override
Called by Preprocessor::HandleMacroExpandedIdentifier when a macro invocation is found.
void If(SourceLocation Loc, SourceRange ConditionRange, ConditionValueKind ConditionValue) override
Hook called whenever an #if is seen.
void FileChanged(SourceLocation Loc, FileChangeReason Reason, SrcMgr::CharacteristicKind FileType, FileID PrevFID) override
Callback invoked whenever a source file is entered or exited.
void Endif(SourceLocation Loc, SourceLocation IfLoc) override
Hook called whenever an #endif is seen.
bool EmbedFileNotFound(StringRef FileName) override
Callback invoked whenever the preprocessor cannot find a file for an embed directive.
void PragmaExecCharsetPush(SourceLocation Loc, StringRef Str) override
Callback invoked when a #pragma execution_character_set(push) directive is read.
void Elifndef(SourceLocation Loc, const Token &MacroNameTok, const MacroDefinition &MD) override
Hook called whenever an #elifndef is taken.
void HasInclude(SourceLocation Loc, StringRef FileName, bool IsAngled, OptionalFileEntryRef File, SrcMgr::CharacteristicKind FileType) override
Hook called when a '__has_include' or '__has_include_next' directive is read.
void PragmaAssumeNonNullEnd(SourceLocation Loc) override
Callback invoked when a #pragma clang assume_nonnull end directive is read.
void PragmaWarningPop(SourceLocation Loc) override
Callback invoked when a #pragma warning(pop) directive is read.
void EmbedDirective(SourceLocation HashLoc, StringRef FileName, bool IsAngled, OptionalFileEntryRef File, const LexEmbedParametersResult &Params) override
Callback invoked whenever an embed directive has been processed, regardless of whether the embed will...
void Elifndef(SourceLocation Loc, SourceRange ConditionRange, SourceLocation IfLoc) override
Hook called whenever an #elifndef is skipped.
void SourceRangeSkipped(SourceRange Range, SourceLocation EndifLoc) override
Hook called when a source range is skipped.
void LeftSubmodule(Module *M, SourceLocation ImportLoc, bool ForPragma) override
Callback invoked whenever a submodule was left.
void PragmaWarningPush(SourceLocation Loc, int Level) override
Callback invoked when a #pragma warning(push) directive is read.
void PragmaDetectMismatch(SourceLocation Loc, StringRef Name, StringRef Value) override
Callback invoked when a #pragma detect_mismatch directive is read.
void PragmaDebug(SourceLocation Loc, StringRef DebugType) override
Callback invoked when a #pragma clang __debug directive is read.
void Defined(const Token &MacroNameTok, const MacroDefinition &MD, SourceRange Range) override
Hook called whenever the 'defined' operator is seen.
void PragmaDiagnostic(SourceLocation Loc, StringRef Namespace, diag::Severity mapping, StringRef Str) override
Callback invoked when a #pragma gcc diagnostic directive is read.
void PragmaDirective(SourceLocation Loc, PragmaIntroducerKind Introducer) override
Callback invoked when start reading any pragma directive.
void PragmaAssumeNonNullBegin(SourceLocation Loc) override
Callback invoked when a #pragma clang assume_nonnull begin directive is read.
void Else(SourceLocation Loc, SourceLocation IfLoc) override
Hook called whenever an #else is seen.
void Ident(SourceLocation Loc, StringRef str) override
Callback invoked when a #ident or #sccs directive is read.
void HasEmbed(SourceLocation Loc, StringRef FileName, bool IsAngled, OptionalFileEntryRef File) override
Hook called when a '__has_embed' directive is read.
void Ifdef(SourceLocation Loc, const Token &MacroNameTok, const MacroDefinition &MD) override
Hook called whenever an #ifdef is seen.
void Elifdef(SourceLocation Loc, SourceRange ConditionRange, SourceLocation IfLoc) override
Hook called whenever an #elifdef is skipped.
void PragmaDiagnosticPush(SourceLocation Loc, StringRef Namespace) override
Callback invoked when a #pragma gcc diagnostic push directive is read.
void EndOfMainFile() override
Callback invoked when the end of the main file is reached.
void PragmaExecCharsetPop(SourceLocation Loc) override
Callback invoked when a #pragma execution_character_set(pop) directive is read.
bool FileNotFound(StringRef FileName) override
Callback invoked whenever the preprocessor cannot find a file for an inclusion directive.
void LexedFileChanged(FileID FID, LexedFileChangeReason Reason, SrcMgr::CharacteristicKind FileType, FileID PrevFID, SourceLocation Loc) override
Callback invoked whenever the Lexer moves to a different file for lexing.
void PragmaMark(SourceLocation Loc, StringRef Trivia) override
Callback invoked when a #pragma mark comment is read.
void PragmaOpenCLExtension(SourceLocation NameLoc, const IdentifierInfo *Name, SourceLocation StateLoc, unsigned State) override
Called when an OpenCL extension is either disabled or enabled with a pragma.
PPChainedCallbacks(std::unique_ptr< PPCallbacks > _First, std::unique_ptr< PPCallbacks > _Second)
void Elifdef(SourceLocation Loc, const Token &MacroNameTok, const MacroDefinition &MD) override
Hook called whenever an #elifdef is taken.
void releasePreservedDescendants(llvm::function_ref< bool(PPCallbacks *)> Pred, SmallVectorImpl< PPCallbacks * > &Released) override
Walk owned descendants.
void PragmaSetPPState(SourceLocation Loc, IdentifierInfo *MacroName, std::uint64_t Value) override
Callback invoked when a #pragma clang __set_pp_state directive is read.
void moduleLoadSkipped(Module *Skipped) override
Callback invoked whenever a module load was skipped due to enabled single-module-parse-mode.
void PragmaMessage(SourceLocation Loc, StringRef Namespace, PragmaMessageKind Kind, StringRef Str) override
Callback invoked when a #pragma message directive is read.
void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind, StringRef Str) override
Callback invoked when a #pragma comment directive is read.
void PragmaDiagnosticPop(SourceLocation Loc, StringRef Namespace) override
Callback invoked when a #pragma gcc diagnostic pop directive is read.
void moduleImport(SourceLocation ImportLoc, ModuleIdPath Path, const Module *Imported) override
Callback invoked whenever there was an explicit module-import syntax.
void PragmaWarning(SourceLocation Loc, PragmaWarningSpecifier WarningSpec, ArrayRef< int > Ids) override
void Ifndef(SourceLocation Loc, const Token &MacroNameTok, const MacroDefinition &MD) override
Hook called whenever an #ifndef is seen.
void FileSkipped(const FileEntryRef &SkippedFile, const Token &FilenameTok, SrcMgr::CharacteristicKind FileType) override
Callback invoked whenever a source file is skipped as the result of header guard optimization.
void Elif(SourceLocation Loc, SourceRange ConditionRange, ConditionValueKind ConditionValue, SourceLocation IfLoc) override
Hook called whenever an #elif is seen.
void MacroDefined(const Token &MacroNameTok, const MacroDirective *MD) override
Hook called whenever a macro definition is seen.
void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName, bool IsAngled, CharSourceRange FilenameRange, OptionalFileEntryRef File, StringRef SearchPath, StringRef RelativePath, const Module *SuggestedModule, bool ModuleImported, SrcMgr::CharacteristicKind FileType) override
Callback invoked whenever an inclusion directive of any kind (#include, #import, etc....
Encodes a location in the source.
A trivial tuple used to represent a source range.
Token - This structure provides full information about a lexed token.
Definition Token.h:36
CharacteristicKind
Indicates whether a file or directory holds normal user code, system code, or system code which is im...
Severity
Enum values that allow the client to map NOTEs, WARNINGs, and EXTENSIONs to either Ignore (nothing),...
The JSON file list parser is used to communicate input to InstallAPI.
CustomizableOptional< FileEntryRef > OptionalFileEntryRef
Definition FileEntry.h:196
ArrayRef< IdentifierLoc > ModuleIdPath
A sequence of identifier/location pairs used to describe a particular module or submodule,...
PragmaIntroducerKind
Describes how the pragma was introduced, e.g., with #pragma, _Pragma, or __pragma.
Definition Pragma.h:32