Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

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