Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:36:57

0001 //===--- PPCallbacks.h - Callbacks for Preprocessor actions -----*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 ///
0009 /// \file
0010 /// Defines the PPCallbacks interface.
0011 ///
0012 //===----------------------------------------------------------------------===//
0013 
0014 #ifndef LLVM_CLANG_LEX_PPCALLBACKS_H
0015 #define LLVM_CLANG_LEX_PPCALLBACKS_H
0016 
0017 #include "clang/Basic/DiagnosticIDs.h"
0018 #include "clang/Basic/SourceLocation.h"
0019 #include "clang/Basic/SourceManager.h"
0020 #include "clang/Lex/ModuleLoader.h"
0021 #include "clang/Lex/Pragma.h"
0022 #include "llvm/ADT/StringRef.h"
0023 
0024 namespace clang {
0025 class Token;
0026 class IdentifierInfo;
0027 class MacroDefinition;
0028 class MacroDirective;
0029 class MacroArgs;
0030 struct LexEmbedParametersResult;
0031 
0032 /// This interface provides a way to observe the actions of the
0033 /// preprocessor as it does its thing.
0034 ///
0035 /// Clients can define their hooks here to implement preprocessor level tools.
0036 class PPCallbacks {
0037 public:
0038   virtual ~PPCallbacks();
0039 
0040   enum FileChangeReason {
0041     EnterFile, ExitFile, SystemHeaderPragma, RenameFile
0042   };
0043 
0044   /// Callback invoked whenever a source file is entered or exited.
0045   ///
0046   /// \param Loc Indicates the new location.
0047   /// \param PrevFID the file that was exited if \p Reason is ExitFile or the
0048   /// the file before the new one entered for \p Reason EnterFile.
0049   virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason,
0050                            SrcMgr::CharacteristicKind FileType,
0051                            FileID PrevFID = FileID()) {
0052   }
0053 
0054   enum class LexedFileChangeReason { EnterFile, ExitFile };
0055 
0056   /// Callback invoked whenever the \p Lexer moves to a different file for
0057   /// lexing. Unlike \p FileChanged line number directives and other related
0058   /// pragmas do not trigger callbacks to \p LexedFileChanged.
0059   ///
0060   /// \param FID The \p FileID that the \p Lexer moved to.
0061   ///
0062   /// \param Reason Whether the \p Lexer entered a new file or exited one.
0063   ///
0064   /// \param FileType The \p CharacteristicKind of the file the \p Lexer moved
0065   /// to.
0066   ///
0067   /// \param PrevFID The \p FileID the \p Lexer was using before the change.
0068   ///
0069   /// \param Loc The location where the \p Lexer entered a new file from or the
0070   /// location that the \p Lexer moved into after exiting a file.
0071   virtual void LexedFileChanged(FileID FID, LexedFileChangeReason Reason,
0072                                 SrcMgr::CharacteristicKind FileType,
0073                                 FileID PrevFID, SourceLocation Loc) {}
0074 
0075   /// Callback invoked whenever a source file is skipped as the result
0076   /// of header guard optimization.
0077   ///
0078   /// \param SkippedFile The file that is skipped instead of entering \#include
0079   ///
0080   /// \param FilenameTok The file name token in \#include "FileName" directive
0081   /// or macro expanded file name token from \#include MACRO(PARAMS) directive.
0082   /// Note that FilenameTok contains corresponding quotes/angles symbols.
0083   virtual void FileSkipped(const FileEntryRef &SkippedFile,
0084                            const Token &FilenameTok,
0085                            SrcMgr::CharacteristicKind FileType) {}
0086 
0087   /// Callback invoked whenever the preprocessor cannot find a file for an
0088   /// embed directive.
0089   ///
0090   /// \param FileName The name of the file being included, as written in the
0091   /// source code.
0092   ///
0093   /// \returns true to indicate that the preprocessor should skip this file
0094   /// and not issue any diagnostic.
0095   virtual bool EmbedFileNotFound(StringRef FileName) { return false; }
0096 
0097   /// Callback invoked whenever an embed directive has been processed,
0098   /// regardless of whether the embed will actually find a file.
0099   ///
0100   /// \param HashLoc The location of the '#' that starts the embed directive.
0101   ///
0102   /// \param FileName The name of the file being included, as written in the
0103   /// source code.
0104   ///
0105   /// \param IsAngled Whether the file name was enclosed in angle brackets;
0106   /// otherwise, it was enclosed in quotes.
0107   ///
0108   /// \param File The actual file that may be included by this embed directive.
0109   ///
0110   /// \param Params The parameters used by the directive.
0111   virtual void EmbedDirective(SourceLocation HashLoc, StringRef FileName,
0112                               bool IsAngled, OptionalFileEntryRef File,
0113                               const LexEmbedParametersResult &Params) {}
0114 
0115   /// Callback invoked whenever the preprocessor cannot find a file for an
0116   /// inclusion directive.
0117   ///
0118   /// \param FileName The name of the file being included, as written in the
0119   /// source code.
0120   ///
0121   /// \returns true to indicate that the preprocessor should skip this file
0122   /// and not issue any diagnostic.
0123   virtual bool FileNotFound(StringRef FileName) { return false; }
0124 
0125   /// Callback invoked whenever an inclusion directive of
0126   /// any kind (\c \#include, \c \#import, etc.) has been processed, regardless
0127   /// of whether the inclusion will actually result in an inclusion.
0128   ///
0129   /// \param HashLoc The location of the '#' that starts the inclusion
0130   /// directive.
0131   ///
0132   /// \param IncludeTok The token that indicates the kind of inclusion
0133   /// directive, e.g., 'include' or 'import'.
0134   ///
0135   /// \param FileName The name of the file being included, as written in the
0136   /// source code.
0137   ///
0138   /// \param IsAngled Whether the file name was enclosed in angle brackets;
0139   /// otherwise, it was enclosed in quotes.
0140   ///
0141   /// \param FilenameRange The character range of the quotes or angle brackets
0142   /// for the written file name.
0143   ///
0144   /// \param File The actual file that may be included by this inclusion
0145   /// directive.
0146   ///
0147   /// \param SearchPath Contains the search path which was used to find the file
0148   /// in the file system. If the file was found via an absolute include path,
0149   /// SearchPath will be empty. For framework includes, the SearchPath and
0150   /// RelativePath will be split up. For example, if an include of "Some/Some.h"
0151   /// is found via the framework path
0152   /// "path/to/Frameworks/Some.framework/Headers/Some.h", SearchPath will be
0153   /// "path/to/Frameworks/Some.framework/Headers" and RelativePath will be
0154   /// "Some.h".
0155   ///
0156   /// \param RelativePath The path relative to SearchPath, at which the include
0157   /// file was found. This is equal to FileName except for framework includes.
0158   ///
0159   /// \param SuggestedModule The module suggested for this header, if any.
0160   ///
0161   /// \param ModuleImported Whether this include was translated into import of
0162   /// \p SuggestedModule.
0163   ///
0164   /// \param FileType The characteristic kind, indicates whether a file or
0165   /// directory holds normal user code, system code, or system code which is
0166   /// implicitly 'extern "C"' in C++ mode.
0167   ///
0168   virtual void InclusionDirective(SourceLocation HashLoc,
0169                                   const Token &IncludeTok, StringRef FileName,
0170                                   bool IsAngled, CharSourceRange FilenameRange,
0171                                   OptionalFileEntryRef File,
0172                                   StringRef SearchPath, StringRef RelativePath,
0173                                   const Module *SuggestedModule,
0174                                   bool ModuleImported,
0175                                   SrcMgr::CharacteristicKind FileType) {}
0176 
0177   /// Callback invoked whenever a submodule was entered.
0178   ///
0179   /// \param M The submodule we have entered.
0180   ///
0181   /// \param ImportLoc The location of import directive token.
0182   ///
0183   /// \param ForPragma If entering from pragma directive.
0184   ///
0185   virtual void EnteredSubmodule(Module *M, SourceLocation ImportLoc,
0186                                 bool ForPragma) { }
0187 
0188   /// Callback invoked whenever a submodule was left.
0189   ///
0190   /// \param M The submodule we have left.
0191   ///
0192   /// \param ImportLoc The location of import directive token.
0193   ///
0194   /// \param ForPragma If entering from pragma directive.
0195   ///
0196   virtual void LeftSubmodule(Module *M, SourceLocation ImportLoc,
0197                              bool ForPragma) { }
0198 
0199   /// Callback invoked whenever there was an explicit module-import
0200   /// syntax.
0201   ///
0202   /// \param ImportLoc The location of import directive token.
0203   ///
0204   /// \param Path The identifiers (and their locations) of the module
0205   /// "path", e.g., "std.vector" would be split into "std" and "vector".
0206   ///
0207   /// \param Imported The imported module; can be null if importing failed.
0208   ///
0209   virtual void moduleImport(SourceLocation ImportLoc,
0210                             ModuleIdPath Path,
0211                             const Module *Imported) {
0212   }
0213 
0214   /// Callback invoked when the end of the main file is reached.
0215   ///
0216   /// No subsequent callbacks will be made.
0217   virtual void EndOfMainFile() {
0218   }
0219 
0220   /// Callback invoked when a \#ident or \#sccs directive is read.
0221   /// \param Loc The location of the directive.
0222   /// \param str The text of the directive.
0223   ///
0224   virtual void Ident(SourceLocation Loc, StringRef str) {
0225   }
0226 
0227   /// Callback invoked when start reading any pragma directive.
0228   virtual void PragmaDirective(SourceLocation Loc,
0229                                PragmaIntroducerKind Introducer) {
0230   }
0231 
0232   /// Callback invoked when a \#pragma comment directive is read.
0233   virtual void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind,
0234                              StringRef Str) {
0235   }
0236 
0237   /// Callback invoked when a \#pragma mark comment is read.
0238   virtual void PragmaMark(SourceLocation Loc, StringRef Trivia) {
0239   }
0240 
0241   /// Callback invoked when a \#pragma detect_mismatch directive is
0242   /// read.
0243   virtual void PragmaDetectMismatch(SourceLocation Loc, StringRef Name,
0244                                     StringRef Value) {
0245   }
0246 
0247   /// Callback invoked when a \#pragma clang __debug directive is read.
0248   /// \param Loc The location of the debug directive.
0249   /// \param DebugType The identifier following __debug.
0250   virtual void PragmaDebug(SourceLocation Loc, StringRef DebugType) {
0251   }
0252 
0253   /// Determines the kind of \#pragma invoking a call to PragmaMessage.
0254   enum PragmaMessageKind {
0255     /// \#pragma message has been invoked.
0256     PMK_Message,
0257 
0258     /// \#pragma GCC warning has been invoked.
0259     PMK_Warning,
0260 
0261     /// \#pragma GCC error has been invoked.
0262     PMK_Error
0263   };
0264 
0265   /// Callback invoked when a \#pragma message directive is read.
0266   /// \param Loc The location of the message directive.
0267   /// \param Namespace The namespace of the message directive.
0268   /// \param Kind The type of the message directive.
0269   /// \param Str The text of the message directive.
0270   virtual void PragmaMessage(SourceLocation Loc, StringRef Namespace,
0271                              PragmaMessageKind Kind, StringRef Str) {
0272   }
0273 
0274   /// Callback invoked when a \#pragma gcc diagnostic push directive
0275   /// is read.
0276   virtual void PragmaDiagnosticPush(SourceLocation Loc,
0277                                     StringRef Namespace) {
0278   }
0279 
0280   /// Callback invoked when a \#pragma gcc diagnostic pop directive
0281   /// is read.
0282   virtual void PragmaDiagnosticPop(SourceLocation Loc,
0283                                    StringRef Namespace) {
0284   }
0285 
0286   /// Callback invoked when a \#pragma gcc diagnostic directive is read.
0287   virtual void PragmaDiagnostic(SourceLocation Loc, StringRef Namespace,
0288                                 diag::Severity mapping, StringRef Str) {}
0289 
0290   /// Called when an OpenCL extension is either disabled or
0291   /// enabled with a pragma.
0292   virtual void PragmaOpenCLExtension(SourceLocation NameLoc,
0293                                      const IdentifierInfo *Name,
0294                                      SourceLocation StateLoc, unsigned State) {
0295   }
0296 
0297   /// Callback invoked when a \#pragma warning directive is read.
0298   enum PragmaWarningSpecifier {
0299     PWS_Default,
0300     PWS_Disable,
0301     PWS_Error,
0302     PWS_Once,
0303     PWS_Suppress,
0304     PWS_Level1,
0305     PWS_Level2,
0306     PWS_Level3,
0307     PWS_Level4,
0308   };
0309   virtual void PragmaWarning(SourceLocation Loc,
0310                              PragmaWarningSpecifier WarningSpec,
0311                              ArrayRef<int> Ids) {}
0312 
0313   /// Callback invoked when a \#pragma warning(push) directive is read.
0314   virtual void PragmaWarningPush(SourceLocation Loc, int Level) {
0315   }
0316 
0317   /// Callback invoked when a \#pragma warning(pop) directive is read.
0318   virtual void PragmaWarningPop(SourceLocation Loc) {
0319   }
0320 
0321   /// Callback invoked when a \#pragma execution_character_set(push) directive
0322   /// is read.
0323   virtual void PragmaExecCharsetPush(SourceLocation Loc, StringRef Str) {}
0324 
0325   /// Callback invoked when a \#pragma execution_character_set(pop) directive
0326   /// is read.
0327   virtual void PragmaExecCharsetPop(SourceLocation Loc) {}
0328 
0329   /// Callback invoked when a \#pragma clang assume_nonnull begin directive
0330   /// is read.
0331   virtual void PragmaAssumeNonNullBegin(SourceLocation Loc) {}
0332 
0333   /// Callback invoked when a \#pragma clang assume_nonnull end directive
0334   /// is read.
0335   virtual void PragmaAssumeNonNullEnd(SourceLocation Loc) {}
0336 
0337   /// Called by Preprocessor::HandleMacroExpandedIdentifier when a
0338   /// macro invocation is found.
0339   virtual void MacroExpands(const Token &MacroNameTok,
0340                             const MacroDefinition &MD, SourceRange Range,
0341                             const MacroArgs *Args) {}
0342 
0343   /// Hook called whenever a macro definition is seen.
0344   virtual void MacroDefined(const Token &MacroNameTok,
0345                             const MacroDirective *MD) {
0346   }
0347 
0348   /// Hook called whenever a macro \#undef is seen.
0349   /// \param MacroNameTok The active Token
0350   /// \param MD A MacroDefinition for the named macro.
0351   /// \param Undef New MacroDirective if the macro was defined, null otherwise.
0352   ///
0353   /// MD is released immediately following this callback.
0354   virtual void MacroUndefined(const Token &MacroNameTok,
0355                               const MacroDefinition &MD,
0356                               const MacroDirective *Undef) {
0357   }
0358 
0359   /// Hook called whenever the 'defined' operator is seen.
0360   /// \param MD The MacroDirective if the name was a macro, null otherwise.
0361   virtual void Defined(const Token &MacroNameTok, const MacroDefinition &MD,
0362                        SourceRange Range) {
0363   }
0364 
0365   /// Hook called when a '__has_embed' directive is read.
0366   virtual void HasEmbed(SourceLocation Loc, StringRef FileName, bool IsAngled,
0367                         OptionalFileEntryRef File) {}
0368 
0369   /// Hook called when a '__has_include' or '__has_include_next' directive is
0370   /// read.
0371   virtual void HasInclude(SourceLocation Loc, StringRef FileName, bool IsAngled,
0372                           OptionalFileEntryRef File,
0373                           SrcMgr::CharacteristicKind FileType);
0374 
0375   /// Hook called when a source range is skipped.
0376   /// \param Range The SourceRange that was skipped. The range begins at the
0377   /// \#if/\#else directive and ends after the \#endif/\#else directive.
0378   /// \param EndifLoc The end location of the 'endif' token, which may precede
0379   /// the range skipped by the directive (e.g excluding comments after an
0380   /// 'endif').
0381   virtual void SourceRangeSkipped(SourceRange Range, SourceLocation EndifLoc) {
0382   }
0383 
0384   enum ConditionValueKind {
0385     CVK_NotEvaluated, CVK_False, CVK_True
0386   };
0387 
0388   /// Hook called whenever an \#if is seen.
0389   /// \param Loc the source location of the directive.
0390   /// \param ConditionRange The SourceRange of the expression being tested.
0391   /// \param ConditionValue The evaluated value of the condition.
0392   ///
0393   // FIXME: better to pass in a list (or tree!) of Tokens.
0394   virtual void If(SourceLocation Loc, SourceRange ConditionRange,
0395                   ConditionValueKind ConditionValue) {
0396   }
0397 
0398   /// Hook called whenever an \#elif is seen.
0399   /// \param Loc the source location of the directive.
0400   /// \param ConditionRange The SourceRange of the expression being tested.
0401   /// \param ConditionValue The evaluated value of the condition.
0402   /// \param IfLoc the source location of the \#if/\#ifdef/\#ifndef directive.
0403   // FIXME: better to pass in a list (or tree!) of Tokens.
0404   virtual void Elif(SourceLocation Loc, SourceRange ConditionRange,
0405                     ConditionValueKind ConditionValue, SourceLocation IfLoc) {
0406   }
0407 
0408   /// Hook called whenever an \#ifdef is seen.
0409   /// \param Loc the source location of the directive.
0410   /// \param MacroNameTok Information on the token being tested.
0411   /// \param MD The MacroDefinition if the name was a macro, null otherwise.
0412   virtual void Ifdef(SourceLocation Loc, const Token &MacroNameTok,
0413                      const MacroDefinition &MD) {
0414   }
0415 
0416   /// Hook called whenever an \#elifdef branch is taken.
0417   /// \param Loc the source location of the directive.
0418   /// \param MacroNameTok Information on the token being tested.
0419   /// \param MD The MacroDefinition if the name was a macro, null otherwise.
0420   virtual void Elifdef(SourceLocation Loc, const Token &MacroNameTok,
0421                        const MacroDefinition &MD) {
0422   }
0423   /// Hook called whenever an \#elifdef is skipped.
0424   /// \param Loc the source location of the directive.
0425   /// \param ConditionRange The SourceRange of the expression being tested.
0426   /// \param IfLoc the source location of the \#if/\#ifdef/\#ifndef directive.
0427   // FIXME: better to pass in a list (or tree!) of Tokens.
0428   virtual void Elifdef(SourceLocation Loc, SourceRange ConditionRange,
0429                        SourceLocation IfLoc) {
0430   }
0431 
0432   /// Hook called whenever an \#ifndef is seen.
0433   /// \param Loc the source location of the directive.
0434   /// \param MacroNameTok Information on the token being tested.
0435   /// \param MD The MacroDefiniton if the name was a macro, null otherwise.
0436   virtual void Ifndef(SourceLocation Loc, const Token &MacroNameTok,
0437                       const MacroDefinition &MD) {
0438   }
0439 
0440   /// Hook called whenever an \#elifndef branch is taken.
0441   /// \param Loc the source location of the directive.
0442   /// \param MacroNameTok Information on the token being tested.
0443   /// \param MD The MacroDefinition if the name was a macro, null otherwise.
0444   virtual void Elifndef(SourceLocation Loc, const Token &MacroNameTok,
0445                         const MacroDefinition &MD) {
0446   }
0447   /// Hook called whenever an \#elifndef is skipped.
0448   /// \param Loc the source location of the directive.
0449   /// \param ConditionRange The SourceRange of the expression being tested.
0450   /// \param IfLoc the source location of the \#if/\#ifdef/\#ifndef directive.
0451   // FIXME: better to pass in a list (or tree!) of Tokens.
0452   virtual void Elifndef(SourceLocation Loc, SourceRange ConditionRange,
0453                         SourceLocation IfLoc) {
0454   }
0455 
0456   /// Hook called whenever an \#else is seen.
0457   /// \param Loc the source location of the directive.
0458   /// \param IfLoc the source location of the \#if/\#ifdef/\#ifndef directive.
0459   virtual void Else(SourceLocation Loc, SourceLocation IfLoc) {
0460   }
0461 
0462   /// Hook called whenever an \#endif is seen.
0463   /// \param Loc the source location of the directive.
0464   /// \param IfLoc the source location of the \#if/\#ifdef/\#ifndef directive.
0465   virtual void Endif(SourceLocation Loc, SourceLocation IfLoc) {
0466   }
0467 };
0468 
0469 /// Simple wrapper class for chaining callbacks.
0470 class PPChainedCallbacks : public PPCallbacks {
0471   std::unique_ptr<PPCallbacks> First, Second;
0472 
0473 public:
0474   PPChainedCallbacks(std::unique_ptr<PPCallbacks> _First,
0475                      std::unique_ptr<PPCallbacks> _Second)
0476     : First(std::move(_First)), Second(std::move(_Second)) {}
0477 
0478   ~PPChainedCallbacks() override;
0479 
0480   void FileChanged(SourceLocation Loc, FileChangeReason Reason,
0481                    SrcMgr::CharacteristicKind FileType,
0482                    FileID PrevFID) override {
0483     First->FileChanged(Loc, Reason, FileType, PrevFID);
0484     Second->FileChanged(Loc, Reason, FileType, PrevFID);
0485   }
0486 
0487   void LexedFileChanged(FileID FID, LexedFileChangeReason Reason,
0488                         SrcMgr::CharacteristicKind FileType, FileID PrevFID,
0489                         SourceLocation Loc) override {
0490     First->LexedFileChanged(FID, Reason, FileType, PrevFID, Loc);
0491     Second->LexedFileChanged(FID, Reason, FileType, PrevFID, Loc);
0492   }
0493 
0494   void FileSkipped(const FileEntryRef &SkippedFile, const Token &FilenameTok,
0495                    SrcMgr::CharacteristicKind FileType) override {
0496     First->FileSkipped(SkippedFile, FilenameTok, FileType);
0497     Second->FileSkipped(SkippedFile, FilenameTok, FileType);
0498   }
0499 
0500   bool EmbedFileNotFound(StringRef FileName) override {
0501     bool Skip = First->FileNotFound(FileName);
0502     // Make sure to invoke the second callback, no matter if the first already
0503     // returned true to skip the file.
0504     Skip |= Second->FileNotFound(FileName);
0505     return Skip;
0506   }
0507 
0508   void EmbedDirective(SourceLocation HashLoc, StringRef FileName, bool IsAngled,
0509                       OptionalFileEntryRef File,
0510                       const LexEmbedParametersResult &Params) override {
0511     First->EmbedDirective(HashLoc, FileName, IsAngled, File, Params);
0512     Second->EmbedDirective(HashLoc, FileName, IsAngled, File, Params);
0513   }
0514 
0515   bool FileNotFound(StringRef FileName) override {
0516     bool Skip = First->FileNotFound(FileName);
0517     // Make sure to invoke the second callback, no matter if the first already
0518     // returned true to skip the file.
0519     Skip |= Second->FileNotFound(FileName);
0520     return Skip;
0521   }
0522 
0523   void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
0524                           StringRef FileName, bool IsAngled,
0525                           CharSourceRange FilenameRange,
0526                           OptionalFileEntryRef File, StringRef SearchPath,
0527                           StringRef RelativePath, const Module *SuggestedModule,
0528                           bool ModuleImported,
0529                           SrcMgr::CharacteristicKind FileType) override {
0530     First->InclusionDirective(HashLoc, IncludeTok, FileName, IsAngled,
0531                               FilenameRange, File, SearchPath, RelativePath,
0532                               SuggestedModule, ModuleImported, FileType);
0533     Second->InclusionDirective(HashLoc, IncludeTok, FileName, IsAngled,
0534                                FilenameRange, File, SearchPath, RelativePath,
0535                                SuggestedModule, ModuleImported, FileType);
0536   }
0537 
0538   void EnteredSubmodule(Module *M, SourceLocation ImportLoc,
0539                         bool ForPragma) override {
0540     First->EnteredSubmodule(M, ImportLoc, ForPragma);
0541     Second->EnteredSubmodule(M, ImportLoc, ForPragma);
0542   }
0543 
0544   void LeftSubmodule(Module *M, SourceLocation ImportLoc,
0545                      bool ForPragma) override {
0546     First->LeftSubmodule(M, ImportLoc, ForPragma);
0547     Second->LeftSubmodule(M, ImportLoc, ForPragma);
0548   }
0549 
0550   void moduleImport(SourceLocation ImportLoc, ModuleIdPath Path,
0551                     const Module *Imported) override {
0552     First->moduleImport(ImportLoc, Path, Imported);
0553     Second->moduleImport(ImportLoc, Path, Imported);
0554   }
0555 
0556   void EndOfMainFile() override {
0557     First->EndOfMainFile();
0558     Second->EndOfMainFile();
0559   }
0560 
0561   void Ident(SourceLocation Loc, StringRef str) override {
0562     First->Ident(Loc, str);
0563     Second->Ident(Loc, str);
0564   }
0565 
0566   void PragmaDirective(SourceLocation Loc,
0567                        PragmaIntroducerKind Introducer) override {
0568     First->PragmaDirective(Loc, Introducer);
0569     Second->PragmaDirective(Loc, Introducer);
0570   }
0571 
0572   void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind,
0573                      StringRef Str) override {
0574     First->PragmaComment(Loc, Kind, Str);
0575     Second->PragmaComment(Loc, Kind, Str);
0576   }
0577 
0578   void PragmaMark(SourceLocation Loc, StringRef Trivia) override {
0579     First->PragmaMark(Loc, Trivia);
0580     Second->PragmaMark(Loc, Trivia);
0581   }
0582 
0583   void PragmaDetectMismatch(SourceLocation Loc, StringRef Name,
0584                             StringRef Value) override {
0585     First->PragmaDetectMismatch(Loc, Name, Value);
0586     Second->PragmaDetectMismatch(Loc, Name, Value);
0587   }
0588 
0589   void PragmaDebug(SourceLocation Loc, StringRef DebugType) override {
0590     First->PragmaDebug(Loc, DebugType);
0591     Second->PragmaDebug(Loc, DebugType);
0592   }
0593 
0594   void PragmaMessage(SourceLocation Loc, StringRef Namespace,
0595                      PragmaMessageKind Kind, StringRef Str) override {
0596     First->PragmaMessage(Loc, Namespace, Kind, Str);
0597     Second->PragmaMessage(Loc, Namespace, Kind, Str);
0598   }
0599 
0600   void PragmaDiagnosticPush(SourceLocation Loc, StringRef Namespace) override {
0601     First->PragmaDiagnosticPush(Loc, Namespace);
0602     Second->PragmaDiagnosticPush(Loc, Namespace);
0603   }
0604 
0605   void PragmaDiagnosticPop(SourceLocation Loc, StringRef Namespace) override {
0606     First->PragmaDiagnosticPop(Loc, Namespace);
0607     Second->PragmaDiagnosticPop(Loc, Namespace);
0608   }
0609 
0610   void PragmaDiagnostic(SourceLocation Loc, StringRef Namespace,
0611                         diag::Severity mapping, StringRef Str) override {
0612     First->PragmaDiagnostic(Loc, Namespace, mapping, Str);
0613     Second->PragmaDiagnostic(Loc, Namespace, mapping, Str);
0614   }
0615 
0616   void HasEmbed(SourceLocation Loc, StringRef FileName, bool IsAngled,
0617                 OptionalFileEntryRef File) override {
0618     First->HasEmbed(Loc, FileName, IsAngled, File);
0619     Second->HasEmbed(Loc, FileName, IsAngled, File);
0620   }
0621 
0622   void HasInclude(SourceLocation Loc, StringRef FileName, bool IsAngled,
0623                   OptionalFileEntryRef File,
0624                   SrcMgr::CharacteristicKind FileType) override;
0625 
0626   void PragmaOpenCLExtension(SourceLocation NameLoc, const IdentifierInfo *Name,
0627                              SourceLocation StateLoc, unsigned State) override {
0628     First->PragmaOpenCLExtension(NameLoc, Name, StateLoc, State);
0629     Second->PragmaOpenCLExtension(NameLoc, Name, StateLoc, State);
0630   }
0631 
0632   void PragmaWarning(SourceLocation Loc, PragmaWarningSpecifier WarningSpec,
0633                      ArrayRef<int> Ids) override {
0634     First->PragmaWarning(Loc, WarningSpec, Ids);
0635     Second->PragmaWarning(Loc, WarningSpec, Ids);
0636   }
0637 
0638   void PragmaWarningPush(SourceLocation Loc, int Level) override {
0639     First->PragmaWarningPush(Loc, Level);
0640     Second->PragmaWarningPush(Loc, Level);
0641   }
0642 
0643   void PragmaWarningPop(SourceLocation Loc) override {
0644     First->PragmaWarningPop(Loc);
0645     Second->PragmaWarningPop(Loc);
0646   }
0647 
0648   void PragmaExecCharsetPush(SourceLocation Loc, StringRef Str) override {
0649     First->PragmaExecCharsetPush(Loc, Str);
0650     Second->PragmaExecCharsetPush(Loc, Str);
0651   }
0652 
0653   void PragmaExecCharsetPop(SourceLocation Loc) override {
0654     First->PragmaExecCharsetPop(Loc);
0655     Second->PragmaExecCharsetPop(Loc);
0656   }
0657 
0658   void PragmaAssumeNonNullBegin(SourceLocation Loc) override {
0659     First->PragmaAssumeNonNullBegin(Loc);
0660     Second->PragmaAssumeNonNullBegin(Loc);
0661   }
0662 
0663   void PragmaAssumeNonNullEnd(SourceLocation Loc) override {
0664     First->PragmaAssumeNonNullEnd(Loc);
0665     Second->PragmaAssumeNonNullEnd(Loc);
0666   }
0667 
0668   void MacroExpands(const Token &MacroNameTok, const MacroDefinition &MD,
0669                     SourceRange Range, const MacroArgs *Args) override {
0670     First->MacroExpands(MacroNameTok, MD, Range, Args);
0671     Second->MacroExpands(MacroNameTok, MD, Range, Args);
0672   }
0673 
0674   void MacroDefined(const Token &MacroNameTok,
0675                     const MacroDirective *MD) override {
0676     First->MacroDefined(MacroNameTok, MD);
0677     Second->MacroDefined(MacroNameTok, MD);
0678   }
0679 
0680   void MacroUndefined(const Token &MacroNameTok,
0681                       const MacroDefinition &MD,
0682                       const MacroDirective *Undef) override {
0683     First->MacroUndefined(MacroNameTok, MD, Undef);
0684     Second->MacroUndefined(MacroNameTok, MD, Undef);
0685   }
0686 
0687   void Defined(const Token &MacroNameTok, const MacroDefinition &MD,
0688                SourceRange Range) override {
0689     First->Defined(MacroNameTok, MD, Range);
0690     Second->Defined(MacroNameTok, MD, Range);
0691   }
0692 
0693   void SourceRangeSkipped(SourceRange Range, SourceLocation EndifLoc) override {
0694     First->SourceRangeSkipped(Range, EndifLoc);
0695     Second->SourceRangeSkipped(Range, EndifLoc);
0696   }
0697 
0698   /// Hook called whenever an \#if is seen.
0699   void If(SourceLocation Loc, SourceRange ConditionRange,
0700           ConditionValueKind ConditionValue) override {
0701     First->If(Loc, ConditionRange, ConditionValue);
0702     Second->If(Loc, ConditionRange, ConditionValue);
0703   }
0704 
0705   /// Hook called whenever an \#elif is seen.
0706   void Elif(SourceLocation Loc, SourceRange ConditionRange,
0707             ConditionValueKind ConditionValue, SourceLocation IfLoc) override {
0708     First->Elif(Loc, ConditionRange, ConditionValue, IfLoc);
0709     Second->Elif(Loc, ConditionRange, ConditionValue, IfLoc);
0710   }
0711 
0712   /// Hook called whenever an \#ifdef is seen.
0713   void Ifdef(SourceLocation Loc, const Token &MacroNameTok,
0714              const MacroDefinition &MD) override {
0715     First->Ifdef(Loc, MacroNameTok, MD);
0716     Second->Ifdef(Loc, MacroNameTok, MD);
0717   }
0718 
0719   /// Hook called whenever an \#elifdef is taken.
0720   void Elifdef(SourceLocation Loc, const Token &MacroNameTok,
0721                const MacroDefinition &MD) override {
0722     First->Elifdef(Loc, MacroNameTok, MD);
0723     Second->Elifdef(Loc, MacroNameTok, MD);
0724   }
0725   /// Hook called whenever an \#elifdef is skipped.
0726   void Elifdef(SourceLocation Loc, SourceRange ConditionRange,
0727                SourceLocation IfLoc) override {
0728     First->Elifdef(Loc, ConditionRange, IfLoc);
0729     Second->Elifdef(Loc, ConditionRange, IfLoc);
0730   }
0731 
0732   /// Hook called whenever an \#ifndef is seen.
0733   void Ifndef(SourceLocation Loc, const Token &MacroNameTok,
0734               const MacroDefinition &MD) override {
0735     First->Ifndef(Loc, MacroNameTok, MD);
0736     Second->Ifndef(Loc, MacroNameTok, MD);
0737   }
0738 
0739   /// Hook called whenever an \#elifndef is taken.
0740   void Elifndef(SourceLocation Loc, const Token &MacroNameTok,
0741                 const MacroDefinition &MD) override {
0742     First->Elifndef(Loc, MacroNameTok, MD);
0743     Second->Elifndef(Loc, MacroNameTok, MD);
0744   }
0745   /// Hook called whenever an \#elifndef is skipped.
0746   void Elifndef(SourceLocation Loc, SourceRange ConditionRange,
0747                SourceLocation IfLoc) override {
0748     First->Elifndef(Loc, ConditionRange, IfLoc);
0749     Second->Elifndef(Loc, ConditionRange, IfLoc);
0750   }
0751 
0752   /// Hook called whenever an \#else is seen.
0753   void Else(SourceLocation Loc, SourceLocation IfLoc) override {
0754     First->Else(Loc, IfLoc);
0755     Second->Else(Loc, IfLoc);
0756   }
0757 
0758   /// Hook called whenever an \#endif is seen.
0759   void Endif(SourceLocation Loc, SourceLocation IfLoc) override {
0760     First->Endif(Loc, IfLoc);
0761     Second->Endif(Loc, IfLoc);
0762   }
0763 };
0764 
0765 }  // end namespace clang
0766 
0767 #endif