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