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