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