10b57cec5SDimitry Andric //===--- PPCallbacks.h - Callbacks for Preprocessor actions -----*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric ///
90b57cec5SDimitry Andric /// \file
100b57cec5SDimitry Andric /// Defines the PPCallbacks interface.
110b57cec5SDimitry Andric ///
120b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
130b57cec5SDimitry Andric 
140b57cec5SDimitry Andric #ifndef LLVM_CLANG_LEX_PPCALLBACKS_H
150b57cec5SDimitry Andric #define LLVM_CLANG_LEX_PPCALLBACKS_H
160b57cec5SDimitry Andric 
170b57cec5SDimitry Andric #include "clang/Basic/DiagnosticIDs.h"
180b57cec5SDimitry Andric #include "clang/Basic/SourceLocation.h"
190b57cec5SDimitry Andric #include "clang/Basic/SourceManager.h"
200b57cec5SDimitry Andric #include "clang/Lex/ModuleLoader.h"
210b57cec5SDimitry Andric #include "clang/Lex/Pragma.h"
220b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
230b57cec5SDimitry Andric 
240b57cec5SDimitry Andric namespace clang {
250b57cec5SDimitry Andric class Token;
260b57cec5SDimitry Andric class IdentifierInfo;
270b57cec5SDimitry Andric class MacroDefinition;
280b57cec5SDimitry Andric class MacroDirective;
290b57cec5SDimitry Andric class MacroArgs;
300b57cec5SDimitry Andric 
310b57cec5SDimitry Andric /// This interface provides a way to observe the actions of the
320b57cec5SDimitry Andric /// preprocessor as it does its thing.
330b57cec5SDimitry Andric ///
340b57cec5SDimitry Andric /// Clients can define their hooks here to implement preprocessor level tools.
350b57cec5SDimitry Andric class PPCallbacks {
360b57cec5SDimitry Andric public:
370b57cec5SDimitry Andric   virtual ~PPCallbacks();
380b57cec5SDimitry Andric 
390b57cec5SDimitry Andric   enum FileChangeReason {
400b57cec5SDimitry Andric     EnterFile, ExitFile, SystemHeaderPragma, RenameFile
410b57cec5SDimitry Andric   };
420b57cec5SDimitry Andric 
430b57cec5SDimitry Andric   /// Callback invoked whenever a source file is entered or exited.
440b57cec5SDimitry Andric   ///
450b57cec5SDimitry Andric   /// \param Loc Indicates the new location.
4681ad6265SDimitry Andric   /// \param PrevFID the file that was exited if \p Reason is ExitFile or the
4781ad6265SDimitry Andric   /// the file before the new one entered for \p Reason EnterFile.
480b57cec5SDimitry Andric   virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason,
490b57cec5SDimitry Andric                            SrcMgr::CharacteristicKind FileType,
500b57cec5SDimitry Andric                            FileID PrevFID = FileID()) {
510b57cec5SDimitry Andric   }
520b57cec5SDimitry Andric 
5381ad6265SDimitry Andric   enum class LexedFileChangeReason { EnterFile, ExitFile };
5481ad6265SDimitry Andric 
5581ad6265SDimitry Andric   /// Callback invoked whenever the \p Lexer moves to a different file for
5681ad6265SDimitry Andric   /// lexing. Unlike \p FileChanged line number directives and other related
5781ad6265SDimitry Andric   /// pragmas do not trigger callbacks to \p LexedFileChanged.
5881ad6265SDimitry Andric   ///
5981ad6265SDimitry Andric   /// \param FID The \p FileID that the \p Lexer moved to.
6081ad6265SDimitry Andric   ///
6181ad6265SDimitry Andric   /// \param Reason Whether the \p Lexer entered a new file or exited one.
6281ad6265SDimitry Andric   ///
6381ad6265SDimitry Andric   /// \param FileType The \p CharacteristicKind of the file the \p Lexer moved
6481ad6265SDimitry Andric   /// to.
6581ad6265SDimitry Andric   ///
6681ad6265SDimitry Andric   /// \param PrevFID The \p FileID the \p Lexer was using before the change.
6781ad6265SDimitry Andric   ///
6881ad6265SDimitry Andric   /// \param Loc The location where the \p Lexer entered a new file from or the
6981ad6265SDimitry Andric   /// location that the \p Lexer moved into after exiting a file.
LexedFileChanged(FileID FID,LexedFileChangeReason Reason,SrcMgr::CharacteristicKind FileType,FileID PrevFID,SourceLocation Loc)7081ad6265SDimitry Andric   virtual void LexedFileChanged(FileID FID, LexedFileChangeReason Reason,
7181ad6265SDimitry Andric                                 SrcMgr::CharacteristicKind FileType,
7281ad6265SDimitry Andric                                 FileID PrevFID, SourceLocation Loc) {}
7381ad6265SDimitry Andric 
740b57cec5SDimitry Andric   /// Callback invoked whenever a source file is skipped as the result
750b57cec5SDimitry Andric   /// of header guard optimization.
760b57cec5SDimitry Andric   ///
770b57cec5SDimitry Andric   /// \param SkippedFile The file that is skipped instead of entering \#include
780b57cec5SDimitry Andric   ///
790b57cec5SDimitry Andric   /// \param FilenameTok The file name token in \#include "FileName" directive
800b57cec5SDimitry Andric   /// or macro expanded file name token from \#include MACRO(PARAMS) directive.
810b57cec5SDimitry Andric   /// Note that FilenameTok contains corresponding quotes/angles symbols.
FileSkipped(const FileEntryRef & SkippedFile,const Token & FilenameTok,SrcMgr::CharacteristicKind FileType)82a7dea167SDimitry Andric   virtual void FileSkipped(const FileEntryRef &SkippedFile,
830b57cec5SDimitry Andric                            const Token &FilenameTok,
84a7dea167SDimitry Andric                            SrcMgr::CharacteristicKind FileType) {}
850b57cec5SDimitry Andric 
86bdd1243dSDimitry Andric   /// Callback invoked whenever the preprocessor cannot find a file for an
87bdd1243dSDimitry Andric   /// inclusion directive.
88bdd1243dSDimitry Andric   ///
89bdd1243dSDimitry Andric   /// \param FileName The name of the file being included, as written in the
90bdd1243dSDimitry Andric   /// source code.
91bdd1243dSDimitry Andric   ///
92bdd1243dSDimitry Andric   /// \returns true to indicate that the preprocessor should skip this file
93bdd1243dSDimitry Andric   /// and not issue any diagnostic.
FileNotFound(StringRef FileName)94bdd1243dSDimitry Andric   virtual bool FileNotFound(StringRef FileName) { return false; }
95bdd1243dSDimitry Andric 
960b57cec5SDimitry Andric   /// Callback invoked whenever an inclusion directive of
970b57cec5SDimitry Andric   /// any kind (\c \#include, \c \#import, etc.) has been processed, regardless
980b57cec5SDimitry Andric   /// of whether the inclusion will actually result in an inclusion.
990b57cec5SDimitry Andric   ///
1000b57cec5SDimitry Andric   /// \param HashLoc The location of the '#' that starts the inclusion
1010b57cec5SDimitry Andric   /// directive.
1020b57cec5SDimitry Andric   ///
1030b57cec5SDimitry Andric   /// \param IncludeTok The token that indicates the kind of inclusion
1040b57cec5SDimitry Andric   /// directive, e.g., 'include' or 'import'.
1050b57cec5SDimitry Andric   ///
1060b57cec5SDimitry Andric   /// \param FileName The name of the file being included, as written in the
1070b57cec5SDimitry Andric   /// source code.
1080b57cec5SDimitry Andric   ///
1090b57cec5SDimitry Andric   /// \param IsAngled Whether the file name was enclosed in angle brackets;
1100b57cec5SDimitry Andric   /// otherwise, it was enclosed in quotes.
1110b57cec5SDimitry Andric   ///
1120b57cec5SDimitry Andric   /// \param FilenameRange The character range of the quotes or angle brackets
1130b57cec5SDimitry Andric   /// for the written file name.
1140b57cec5SDimitry Andric   ///
1150b57cec5SDimitry Andric   /// \param File The actual file that may be included by this inclusion
1160b57cec5SDimitry Andric   /// directive.
1170b57cec5SDimitry Andric   ///
1180b57cec5SDimitry Andric   /// \param SearchPath Contains the search path which was used to find the file
1190b57cec5SDimitry Andric   /// in the file system. If the file was found via an absolute include path,
1200b57cec5SDimitry Andric   /// SearchPath will be empty. For framework includes, the SearchPath and
1210b57cec5SDimitry Andric   /// RelativePath will be split up. For example, if an include of "Some/Some.h"
1220b57cec5SDimitry Andric   /// is found via the framework path
1230b57cec5SDimitry Andric   /// "path/to/Frameworks/Some.framework/Headers/Some.h", SearchPath will be
1240b57cec5SDimitry Andric   /// "path/to/Frameworks/Some.framework/Headers" and RelativePath will be
1250b57cec5SDimitry Andric   /// "Some.h".
1260b57cec5SDimitry Andric   ///
1270b57cec5SDimitry Andric   /// \param RelativePath The path relative to SearchPath, at which the include
1280b57cec5SDimitry Andric   /// file was found. This is equal to FileName except for framework includes.
1290b57cec5SDimitry Andric   ///
1300b57cec5SDimitry Andric   /// \param Imported The module, whenever an inclusion directive was
1310b57cec5SDimitry Andric   /// automatically turned into a module import or null otherwise.
1320b57cec5SDimitry Andric   ///
1330b57cec5SDimitry Andric   /// \param FileType The characteristic kind, indicates whether a file or
1340b57cec5SDimitry Andric   /// directory holds normal user code, system code, or system code which is
1350b57cec5SDimitry Andric   /// implicitly 'extern "C"' in C++ mode.
1360b57cec5SDimitry Andric   ///
InclusionDirective(SourceLocation HashLoc,const Token & IncludeTok,StringRef FileName,bool IsAngled,CharSourceRange FilenameRange,OptionalFileEntryRef File,StringRef SearchPath,StringRef RelativePath,const Module * Imported,SrcMgr::CharacteristicKind FileType)1370b57cec5SDimitry Andric   virtual void InclusionDirective(SourceLocation HashLoc,
138bdd1243dSDimitry Andric                                   const Token &IncludeTok, StringRef FileName,
139bdd1243dSDimitry Andric                                   bool IsAngled, CharSourceRange FilenameRange,
140bdd1243dSDimitry Andric                                   OptionalFileEntryRef File,
141bdd1243dSDimitry Andric                                   StringRef SearchPath, StringRef RelativePath,
1420b57cec5SDimitry Andric                                   const Module *Imported,
143bdd1243dSDimitry Andric                                   SrcMgr::CharacteristicKind FileType) {}
1440b57cec5SDimitry Andric 
1450b57cec5SDimitry Andric   /// Callback invoked whenever a submodule was entered.
1460b57cec5SDimitry Andric   ///
1470b57cec5SDimitry Andric   /// \param M The submodule we have entered.
1480b57cec5SDimitry Andric   ///
1490b57cec5SDimitry Andric   /// \param ImportLoc The location of import directive token.
1500b57cec5SDimitry Andric   ///
1510b57cec5SDimitry Andric   /// \param ForPragma If entering from pragma directive.
1520b57cec5SDimitry Andric   ///
EnteredSubmodule(Module * M,SourceLocation ImportLoc,bool ForPragma)1530b57cec5SDimitry Andric   virtual void EnteredSubmodule(Module *M, SourceLocation ImportLoc,
1540b57cec5SDimitry Andric                                 bool ForPragma) { }
1550b57cec5SDimitry Andric 
1560b57cec5SDimitry Andric   /// Callback invoked whenever a submodule was left.
1570b57cec5SDimitry Andric   ///
1580b57cec5SDimitry Andric   /// \param M The submodule we have left.
1590b57cec5SDimitry Andric   ///
1600b57cec5SDimitry Andric   /// \param ImportLoc The location of import directive token.
1610b57cec5SDimitry Andric   ///
1620b57cec5SDimitry Andric   /// \param ForPragma If entering from pragma directive.
1630b57cec5SDimitry Andric   ///
LeftSubmodule(Module * M,SourceLocation ImportLoc,bool ForPragma)1640b57cec5SDimitry Andric   virtual void LeftSubmodule(Module *M, SourceLocation ImportLoc,
1650b57cec5SDimitry Andric                              bool ForPragma) { }
1660b57cec5SDimitry Andric 
1670b57cec5SDimitry Andric   /// Callback invoked whenever there was an explicit module-import
1680b57cec5SDimitry Andric   /// syntax.
1690b57cec5SDimitry Andric   ///
1700b57cec5SDimitry Andric   /// \param ImportLoc The location of import directive token.
1710b57cec5SDimitry Andric   ///
1720b57cec5SDimitry Andric   /// \param Path The identifiers (and their locations) of the module
1730b57cec5SDimitry Andric   /// "path", e.g., "std.vector" would be split into "std" and "vector".
1740b57cec5SDimitry Andric   ///
1750b57cec5SDimitry Andric   /// \param Imported The imported module; can be null if importing failed.
1760b57cec5SDimitry Andric   ///
moduleImport(SourceLocation ImportLoc,ModuleIdPath Path,const Module * Imported)1770b57cec5SDimitry Andric   virtual void moduleImport(SourceLocation ImportLoc,
1780b57cec5SDimitry Andric                             ModuleIdPath Path,
1790b57cec5SDimitry Andric                             const Module *Imported) {
1800b57cec5SDimitry Andric   }
1810b57cec5SDimitry Andric 
1820b57cec5SDimitry Andric   /// Callback invoked when the end of the main file is reached.
1830b57cec5SDimitry Andric   ///
1840b57cec5SDimitry Andric   /// No subsequent callbacks will be made.
EndOfMainFile()1850b57cec5SDimitry Andric   virtual void EndOfMainFile() {
1860b57cec5SDimitry Andric   }
1870b57cec5SDimitry Andric 
1880b57cec5SDimitry Andric   /// Callback invoked when a \#ident or \#sccs directive is read.
1890b57cec5SDimitry Andric   /// \param Loc The location of the directive.
1900b57cec5SDimitry Andric   /// \param str The text of the directive.
1910b57cec5SDimitry Andric   ///
Ident(SourceLocation Loc,StringRef str)1920b57cec5SDimitry Andric   virtual void Ident(SourceLocation Loc, StringRef str) {
1930b57cec5SDimitry Andric   }
1940b57cec5SDimitry Andric 
1950b57cec5SDimitry Andric   /// Callback invoked when start reading any pragma directive.
PragmaDirective(SourceLocation Loc,PragmaIntroducerKind Introducer)1960b57cec5SDimitry Andric   virtual void PragmaDirective(SourceLocation Loc,
1970b57cec5SDimitry Andric                                PragmaIntroducerKind Introducer) {
1980b57cec5SDimitry Andric   }
1990b57cec5SDimitry Andric 
2000b57cec5SDimitry Andric   /// Callback invoked when a \#pragma comment directive is read.
PragmaComment(SourceLocation Loc,const IdentifierInfo * Kind,StringRef Str)2010b57cec5SDimitry Andric   virtual void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind,
2020b57cec5SDimitry Andric                              StringRef Str) {
2030b57cec5SDimitry Andric   }
2040b57cec5SDimitry Andric 
205fe6060f1SDimitry Andric   /// Callback invoked when a \#pragma mark comment is read.
PragmaMark(SourceLocation Loc,StringRef Trivia)206fe6060f1SDimitry Andric   virtual void PragmaMark(SourceLocation Loc, StringRef Trivia) {
207fe6060f1SDimitry Andric   }
208fe6060f1SDimitry Andric 
2090b57cec5SDimitry Andric   /// Callback invoked when a \#pragma detect_mismatch directive is
2100b57cec5SDimitry Andric   /// read.
PragmaDetectMismatch(SourceLocation Loc,StringRef Name,StringRef Value)2110b57cec5SDimitry Andric   virtual void PragmaDetectMismatch(SourceLocation Loc, StringRef Name,
2120b57cec5SDimitry Andric                                     StringRef Value) {
2130b57cec5SDimitry Andric   }
2140b57cec5SDimitry Andric 
2150b57cec5SDimitry Andric   /// Callback invoked when a \#pragma clang __debug directive is read.
2160b57cec5SDimitry Andric   /// \param Loc The location of the debug directive.
2170b57cec5SDimitry Andric   /// \param DebugType The identifier following __debug.
PragmaDebug(SourceLocation Loc,StringRef DebugType)2180b57cec5SDimitry Andric   virtual void PragmaDebug(SourceLocation Loc, StringRef DebugType) {
2190b57cec5SDimitry Andric   }
2200b57cec5SDimitry Andric 
2210b57cec5SDimitry Andric   /// Determines the kind of \#pragma invoking a call to PragmaMessage.
2220b57cec5SDimitry Andric   enum PragmaMessageKind {
2230b57cec5SDimitry Andric     /// \#pragma message has been invoked.
2240b57cec5SDimitry Andric     PMK_Message,
2250b57cec5SDimitry Andric 
2260b57cec5SDimitry Andric     /// \#pragma GCC warning has been invoked.
2270b57cec5SDimitry Andric     PMK_Warning,
2280b57cec5SDimitry Andric 
2290b57cec5SDimitry Andric     /// \#pragma GCC error has been invoked.
2300b57cec5SDimitry Andric     PMK_Error
2310b57cec5SDimitry Andric   };
2320b57cec5SDimitry Andric 
2330b57cec5SDimitry Andric   /// Callback invoked when a \#pragma message directive is read.
2340b57cec5SDimitry Andric   /// \param Loc The location of the message directive.
2350b57cec5SDimitry Andric   /// \param Namespace The namespace of the message directive.
2360b57cec5SDimitry Andric   /// \param Kind The type of the message directive.
2370b57cec5SDimitry Andric   /// \param Str The text of the message directive.
PragmaMessage(SourceLocation Loc,StringRef Namespace,PragmaMessageKind Kind,StringRef Str)2380b57cec5SDimitry Andric   virtual void PragmaMessage(SourceLocation Loc, StringRef Namespace,
2390b57cec5SDimitry Andric                              PragmaMessageKind Kind, StringRef Str) {
2400b57cec5SDimitry Andric   }
2410b57cec5SDimitry Andric 
2420b57cec5SDimitry Andric   /// Callback invoked when a \#pragma gcc diagnostic push directive
2430b57cec5SDimitry Andric   /// is read.
PragmaDiagnosticPush(SourceLocation Loc,StringRef Namespace)2440b57cec5SDimitry Andric   virtual void PragmaDiagnosticPush(SourceLocation Loc,
2450b57cec5SDimitry Andric                                     StringRef Namespace) {
2460b57cec5SDimitry Andric   }
2470b57cec5SDimitry Andric 
2480b57cec5SDimitry Andric   /// Callback invoked when a \#pragma gcc diagnostic pop directive
2490b57cec5SDimitry Andric   /// is read.
PragmaDiagnosticPop(SourceLocation Loc,StringRef Namespace)2500b57cec5SDimitry Andric   virtual void PragmaDiagnosticPop(SourceLocation Loc,
2510b57cec5SDimitry Andric                                    StringRef Namespace) {
2520b57cec5SDimitry Andric   }
2530b57cec5SDimitry Andric 
2540b57cec5SDimitry Andric   /// Callback invoked when a \#pragma gcc diagnostic directive is read.
PragmaDiagnostic(SourceLocation Loc,StringRef Namespace,diag::Severity mapping,StringRef Str)2550b57cec5SDimitry Andric   virtual void PragmaDiagnostic(SourceLocation Loc, StringRef Namespace,
2560b57cec5SDimitry Andric                                 diag::Severity mapping, StringRef Str) {}
2570b57cec5SDimitry Andric 
2580b57cec5SDimitry Andric   /// Called when an OpenCL extension is either disabled or
2590b57cec5SDimitry Andric   /// enabled with a pragma.
PragmaOpenCLExtension(SourceLocation NameLoc,const IdentifierInfo * Name,SourceLocation StateLoc,unsigned State)2600b57cec5SDimitry Andric   virtual void PragmaOpenCLExtension(SourceLocation NameLoc,
2610b57cec5SDimitry Andric                                      const IdentifierInfo *Name,
2620b57cec5SDimitry Andric                                      SourceLocation StateLoc, unsigned State) {
2630b57cec5SDimitry Andric   }
2640b57cec5SDimitry Andric 
2650b57cec5SDimitry Andric   /// Callback invoked when a \#pragma warning directive is read.
266349cc55cSDimitry Andric   enum PragmaWarningSpecifier {
267349cc55cSDimitry Andric     PWS_Default,
268349cc55cSDimitry Andric     PWS_Disable,
269349cc55cSDimitry Andric     PWS_Error,
270349cc55cSDimitry Andric     PWS_Once,
271349cc55cSDimitry Andric     PWS_Suppress,
272349cc55cSDimitry Andric     PWS_Level1,
273349cc55cSDimitry Andric     PWS_Level2,
274349cc55cSDimitry Andric     PWS_Level3,
275349cc55cSDimitry Andric     PWS_Level4,
276349cc55cSDimitry Andric   };
PragmaWarning(SourceLocation Loc,PragmaWarningSpecifier WarningSpec,ArrayRef<int> Ids)277349cc55cSDimitry Andric   virtual void PragmaWarning(SourceLocation Loc,
278349cc55cSDimitry Andric                              PragmaWarningSpecifier WarningSpec,
279349cc55cSDimitry Andric                              ArrayRef<int> Ids) {}
2800b57cec5SDimitry Andric 
2810b57cec5SDimitry Andric   /// Callback invoked when a \#pragma warning(push) directive is read.
PragmaWarningPush(SourceLocation Loc,int Level)2820b57cec5SDimitry Andric   virtual void PragmaWarningPush(SourceLocation Loc, int Level) {
2830b57cec5SDimitry Andric   }
2840b57cec5SDimitry Andric 
2850b57cec5SDimitry Andric   /// Callback invoked when a \#pragma warning(pop) directive is read.
PragmaWarningPop(SourceLocation Loc)2860b57cec5SDimitry Andric   virtual void PragmaWarningPop(SourceLocation Loc) {
2870b57cec5SDimitry Andric   }
2880b57cec5SDimitry Andric 
2890b57cec5SDimitry Andric   /// Callback invoked when a \#pragma execution_character_set(push) directive
2900b57cec5SDimitry Andric   /// is read.
PragmaExecCharsetPush(SourceLocation Loc,StringRef Str)2910b57cec5SDimitry Andric   virtual void PragmaExecCharsetPush(SourceLocation Loc, StringRef Str) {}
2920b57cec5SDimitry Andric 
2930b57cec5SDimitry Andric   /// Callback invoked when a \#pragma execution_character_set(pop) directive
2940b57cec5SDimitry Andric   /// is read.
PragmaExecCharsetPop(SourceLocation Loc)2950b57cec5SDimitry Andric   virtual void PragmaExecCharsetPop(SourceLocation Loc) {}
2960b57cec5SDimitry Andric 
2970b57cec5SDimitry Andric   /// Callback invoked when a \#pragma clang assume_nonnull begin directive
2980b57cec5SDimitry Andric   /// is read.
PragmaAssumeNonNullBegin(SourceLocation Loc)2990b57cec5SDimitry Andric   virtual void PragmaAssumeNonNullBegin(SourceLocation Loc) {}
3000b57cec5SDimitry Andric 
3010b57cec5SDimitry Andric   /// Callback invoked when a \#pragma clang assume_nonnull end directive
3020b57cec5SDimitry Andric   /// is read.
PragmaAssumeNonNullEnd(SourceLocation Loc)3030b57cec5SDimitry Andric   virtual void PragmaAssumeNonNullEnd(SourceLocation Loc) {}
3040b57cec5SDimitry Andric 
3050b57cec5SDimitry Andric   /// Called by Preprocessor::HandleMacroExpandedIdentifier when a
3060b57cec5SDimitry Andric   /// macro invocation is found.
MacroExpands(const Token & MacroNameTok,const MacroDefinition & MD,SourceRange Range,const MacroArgs * Args)3070b57cec5SDimitry Andric   virtual void MacroExpands(const Token &MacroNameTok,
3080b57cec5SDimitry Andric                             const MacroDefinition &MD, SourceRange Range,
3090b57cec5SDimitry Andric                             const MacroArgs *Args) {}
3100b57cec5SDimitry Andric 
3110b57cec5SDimitry Andric   /// Hook called whenever a macro definition is seen.
MacroDefined(const Token & MacroNameTok,const MacroDirective * MD)3120b57cec5SDimitry Andric   virtual void MacroDefined(const Token &MacroNameTok,
3130b57cec5SDimitry Andric                             const MacroDirective *MD) {
3140b57cec5SDimitry Andric   }
3150b57cec5SDimitry Andric 
3160b57cec5SDimitry Andric   /// Hook called whenever a macro \#undef is seen.
3170b57cec5SDimitry Andric   /// \param MacroNameTok The active Token
3180b57cec5SDimitry Andric   /// \param MD A MacroDefinition for the named macro.
3190b57cec5SDimitry Andric   /// \param Undef New MacroDirective if the macro was defined, null otherwise.
3200b57cec5SDimitry Andric   ///
3210b57cec5SDimitry Andric   /// MD is released immediately following this callback.
MacroUndefined(const Token & MacroNameTok,const MacroDefinition & MD,const MacroDirective * Undef)3220b57cec5SDimitry Andric   virtual void MacroUndefined(const Token &MacroNameTok,
3230b57cec5SDimitry Andric                               const MacroDefinition &MD,
3240b57cec5SDimitry Andric                               const MacroDirective *Undef) {
3250b57cec5SDimitry Andric   }
3260b57cec5SDimitry Andric 
3270b57cec5SDimitry Andric   /// Hook called whenever the 'defined' operator is seen.
3280b57cec5SDimitry Andric   /// \param MD The MacroDirective if the name was a macro, null otherwise.
Defined(const Token & MacroNameTok,const MacroDefinition & MD,SourceRange Range)3290b57cec5SDimitry Andric   virtual void Defined(const Token &MacroNameTok, const MacroDefinition &MD,
3300b57cec5SDimitry Andric                        SourceRange Range) {
3310b57cec5SDimitry Andric   }
3320b57cec5SDimitry Andric 
3330b57cec5SDimitry Andric   /// Hook called when a '__has_include' or '__has_include_next' directive is
3340b57cec5SDimitry Andric   /// read.
3350b57cec5SDimitry Andric   virtual void HasInclude(SourceLocation Loc, StringRef FileName, bool IsAngled,
336bdd1243dSDimitry Andric                           OptionalFileEntryRef File,
3375ffd83dbSDimitry Andric                           SrcMgr::CharacteristicKind FileType);
3380b57cec5SDimitry Andric 
3390b57cec5SDimitry Andric   /// Hook called when a source range is skipped.
3400b57cec5SDimitry Andric   /// \param Range The SourceRange that was skipped. The range begins at the
3410b57cec5SDimitry Andric   /// \#if/\#else directive and ends after the \#endif/\#else directive.
3420b57cec5SDimitry Andric   /// \param EndifLoc The end location of the 'endif' token, which may precede
3430b57cec5SDimitry Andric   /// the range skipped by the directive (e.g excluding comments after an
3440b57cec5SDimitry Andric   /// 'endif').
SourceRangeSkipped(SourceRange Range,SourceLocation EndifLoc)3450b57cec5SDimitry Andric   virtual void SourceRangeSkipped(SourceRange Range, SourceLocation EndifLoc) {
3460b57cec5SDimitry Andric   }
3470b57cec5SDimitry Andric 
3480b57cec5SDimitry Andric   enum ConditionValueKind {
3490b57cec5SDimitry Andric     CVK_NotEvaluated, CVK_False, CVK_True
3500b57cec5SDimitry Andric   };
3510b57cec5SDimitry Andric 
3520b57cec5SDimitry Andric   /// Hook called whenever an \#if is seen.
3530b57cec5SDimitry Andric   /// \param Loc the source location of the directive.
3540b57cec5SDimitry Andric   /// \param ConditionRange The SourceRange of the expression being tested.
3550b57cec5SDimitry Andric   /// \param ConditionValue The evaluated value of the condition.
3560b57cec5SDimitry Andric   ///
3570b57cec5SDimitry Andric   // FIXME: better to pass in a list (or tree!) of Tokens.
If(SourceLocation Loc,SourceRange ConditionRange,ConditionValueKind ConditionValue)3580b57cec5SDimitry Andric   virtual void If(SourceLocation Loc, SourceRange ConditionRange,
3590b57cec5SDimitry Andric                   ConditionValueKind ConditionValue) {
3600b57cec5SDimitry Andric   }
3610b57cec5SDimitry Andric 
3620b57cec5SDimitry Andric   /// Hook called whenever an \#elif is seen.
3630b57cec5SDimitry Andric   /// \param Loc the source location of the directive.
3640b57cec5SDimitry Andric   /// \param ConditionRange The SourceRange of the expression being tested.
3650b57cec5SDimitry Andric   /// \param ConditionValue The evaluated value of the condition.
3660b57cec5SDimitry Andric   /// \param IfLoc the source location of the \#if/\#ifdef/\#ifndef directive.
3670b57cec5SDimitry Andric   // FIXME: better to pass in a list (or tree!) of Tokens.
Elif(SourceLocation Loc,SourceRange ConditionRange,ConditionValueKind ConditionValue,SourceLocation IfLoc)3680b57cec5SDimitry Andric   virtual void Elif(SourceLocation Loc, SourceRange ConditionRange,
3690b57cec5SDimitry Andric                     ConditionValueKind ConditionValue, SourceLocation IfLoc) {
3700b57cec5SDimitry Andric   }
3710b57cec5SDimitry Andric 
3720b57cec5SDimitry Andric   /// Hook called whenever an \#ifdef is seen.
3730b57cec5SDimitry Andric   /// \param Loc the source location of the directive.
3740b57cec5SDimitry Andric   /// \param MacroNameTok Information on the token being tested.
3750b57cec5SDimitry Andric   /// \param MD The MacroDefinition if the name was a macro, null otherwise.
Ifdef(SourceLocation Loc,const Token & MacroNameTok,const MacroDefinition & MD)3760b57cec5SDimitry Andric   virtual void Ifdef(SourceLocation Loc, const Token &MacroNameTok,
3770b57cec5SDimitry Andric                      const MacroDefinition &MD) {
3780b57cec5SDimitry Andric   }
3790b57cec5SDimitry Andric 
380fe6060f1SDimitry Andric   /// Hook called whenever an \#elifdef branch is taken.
381fe6060f1SDimitry Andric   /// \param Loc the source location of the directive.
382fe6060f1SDimitry Andric   /// \param MacroNameTok Information on the token being tested.
383fe6060f1SDimitry Andric   /// \param MD The MacroDefinition if the name was a macro, null otherwise.
Elifdef(SourceLocation Loc,const Token & MacroNameTok,const MacroDefinition & MD)384fe6060f1SDimitry Andric   virtual void Elifdef(SourceLocation Loc, const Token &MacroNameTok,
385fe6060f1SDimitry Andric                        const MacroDefinition &MD) {
386fe6060f1SDimitry Andric   }
387fe6060f1SDimitry Andric   /// Hook called whenever an \#elifdef is skipped.
388fe6060f1SDimitry Andric   /// \param Loc the source location of the directive.
389fe6060f1SDimitry Andric   /// \param ConditionRange The SourceRange of the expression being tested.
390fe6060f1SDimitry Andric   /// \param IfLoc the source location of the \#if/\#ifdef/\#ifndef directive.
391fe6060f1SDimitry Andric   // FIXME: better to pass in a list (or tree!) of Tokens.
Elifdef(SourceLocation Loc,SourceRange ConditionRange,SourceLocation IfLoc)392fe6060f1SDimitry Andric   virtual void Elifdef(SourceLocation Loc, SourceRange ConditionRange,
393fe6060f1SDimitry Andric                        SourceLocation IfLoc) {
394fe6060f1SDimitry Andric   }
395fe6060f1SDimitry Andric 
3960b57cec5SDimitry Andric   /// Hook called whenever an \#ifndef is seen.
3970b57cec5SDimitry Andric   /// \param Loc the source location of the directive.
3980b57cec5SDimitry Andric   /// \param MacroNameTok Information on the token being tested.
3990b57cec5SDimitry Andric   /// \param MD The MacroDefiniton if the name was a macro, null otherwise.
Ifndef(SourceLocation Loc,const Token & MacroNameTok,const MacroDefinition & MD)4000b57cec5SDimitry Andric   virtual void Ifndef(SourceLocation Loc, const Token &MacroNameTok,
4010b57cec5SDimitry Andric                       const MacroDefinition &MD) {
4020b57cec5SDimitry Andric   }
4030b57cec5SDimitry Andric 
404fe6060f1SDimitry Andric   /// Hook called whenever an \#elifndef branch is taken.
405fe6060f1SDimitry Andric   /// \param Loc the source location of the directive.
406fe6060f1SDimitry Andric   /// \param MacroNameTok Information on the token being tested.
407fe6060f1SDimitry Andric   /// \param MD The MacroDefinition if the name was a macro, null otherwise.
Elifndef(SourceLocation Loc,const Token & MacroNameTok,const MacroDefinition & MD)408fe6060f1SDimitry Andric   virtual void Elifndef(SourceLocation Loc, const Token &MacroNameTok,
409fe6060f1SDimitry Andric                         const MacroDefinition &MD) {
410fe6060f1SDimitry Andric   }
411fe6060f1SDimitry Andric   /// Hook called whenever an \#elifndef is skipped.
412fe6060f1SDimitry Andric   /// \param Loc the source location of the directive.
413fe6060f1SDimitry Andric   /// \param ConditionRange The SourceRange of the expression being tested.
414fe6060f1SDimitry Andric   /// \param IfLoc the source location of the \#if/\#ifdef/\#ifndef directive.
415fe6060f1SDimitry Andric   // FIXME: better to pass in a list (or tree!) of Tokens.
Elifndef(SourceLocation Loc,SourceRange ConditionRange,SourceLocation IfLoc)416fe6060f1SDimitry Andric   virtual void Elifndef(SourceLocation Loc, SourceRange ConditionRange,
417fe6060f1SDimitry Andric                         SourceLocation IfLoc) {
418fe6060f1SDimitry Andric   }
419fe6060f1SDimitry Andric 
4200b57cec5SDimitry Andric   /// Hook called whenever an \#else is seen.
4210b57cec5SDimitry Andric   /// \param Loc the source location of the directive.
4220b57cec5SDimitry Andric   /// \param IfLoc the source location of the \#if/\#ifdef/\#ifndef directive.
Else(SourceLocation Loc,SourceLocation IfLoc)4230b57cec5SDimitry Andric   virtual void Else(SourceLocation Loc, SourceLocation IfLoc) {
4240b57cec5SDimitry Andric   }
4250b57cec5SDimitry Andric 
4260b57cec5SDimitry Andric   /// Hook called whenever an \#endif is seen.
4270b57cec5SDimitry Andric   /// \param Loc the source location of the directive.
4280b57cec5SDimitry Andric   /// \param IfLoc the source location of the \#if/\#ifdef/\#ifndef directive.
Endif(SourceLocation Loc,SourceLocation IfLoc)4290b57cec5SDimitry Andric   virtual void Endif(SourceLocation Loc, SourceLocation IfLoc) {
4300b57cec5SDimitry Andric   }
4310b57cec5SDimitry Andric };
4320b57cec5SDimitry Andric 
4330b57cec5SDimitry Andric /// Simple wrapper class for chaining callbacks.
4340b57cec5SDimitry Andric class PPChainedCallbacks : public PPCallbacks {
4350b57cec5SDimitry Andric   std::unique_ptr<PPCallbacks> First, Second;
4360b57cec5SDimitry Andric 
4370b57cec5SDimitry Andric public:
PPChainedCallbacks(std::unique_ptr<PPCallbacks> _First,std::unique_ptr<PPCallbacks> _Second)4380b57cec5SDimitry Andric   PPChainedCallbacks(std::unique_ptr<PPCallbacks> _First,
4390b57cec5SDimitry Andric                      std::unique_ptr<PPCallbacks> _Second)
4400b57cec5SDimitry Andric     : First(std::move(_First)), Second(std::move(_Second)) {}
4410b57cec5SDimitry Andric 
4425ffd83dbSDimitry Andric   ~PPChainedCallbacks() override;
4435ffd83dbSDimitry Andric 
FileChanged(SourceLocation Loc,FileChangeReason Reason,SrcMgr::CharacteristicKind FileType,FileID PrevFID)4440b57cec5SDimitry Andric   void FileChanged(SourceLocation Loc, FileChangeReason Reason,
4450b57cec5SDimitry Andric                    SrcMgr::CharacteristicKind FileType,
4460b57cec5SDimitry Andric                    FileID PrevFID) override {
4470b57cec5SDimitry Andric     First->FileChanged(Loc, Reason, FileType, PrevFID);
4480b57cec5SDimitry Andric     Second->FileChanged(Loc, Reason, FileType, PrevFID);
4490b57cec5SDimitry Andric   }
4500b57cec5SDimitry Andric 
LexedFileChanged(FileID FID,LexedFileChangeReason Reason,SrcMgr::CharacteristicKind FileType,FileID PrevFID,SourceLocation Loc)45181ad6265SDimitry Andric   void LexedFileChanged(FileID FID, LexedFileChangeReason Reason,
45281ad6265SDimitry Andric                         SrcMgr::CharacteristicKind FileType, FileID PrevFID,
45381ad6265SDimitry Andric                         SourceLocation Loc) override {
45481ad6265SDimitry Andric     First->LexedFileChanged(FID, Reason, FileType, PrevFID, Loc);
45581ad6265SDimitry Andric     Second->LexedFileChanged(FID, Reason, FileType, PrevFID, Loc);
45681ad6265SDimitry Andric   }
45781ad6265SDimitry Andric 
FileSkipped(const FileEntryRef & SkippedFile,const Token & FilenameTok,SrcMgr::CharacteristicKind FileType)458a7dea167SDimitry Andric   void FileSkipped(const FileEntryRef &SkippedFile, const Token &FilenameTok,
4590b57cec5SDimitry Andric                    SrcMgr::CharacteristicKind FileType) override {
4600b57cec5SDimitry Andric     First->FileSkipped(SkippedFile, FilenameTok, FileType);
4610b57cec5SDimitry Andric     Second->FileSkipped(SkippedFile, FilenameTok, FileType);
4620b57cec5SDimitry Andric   }
4630b57cec5SDimitry Andric 
FileNotFound(StringRef FileName)464bdd1243dSDimitry Andric   bool FileNotFound(StringRef FileName) override {
465bdd1243dSDimitry Andric     bool Skip = First->FileNotFound(FileName);
466bdd1243dSDimitry Andric     // Make sure to invoke the second callback, no matter if the first already
467bdd1243dSDimitry Andric     // returned true to skip the file.
468bdd1243dSDimitry Andric     Skip |= Second->FileNotFound(FileName);
469bdd1243dSDimitry Andric     return Skip;
470bdd1243dSDimitry Andric   }
471bdd1243dSDimitry Andric 
InclusionDirective(SourceLocation HashLoc,const Token & IncludeTok,StringRef FileName,bool IsAngled,CharSourceRange FilenameRange,OptionalFileEntryRef File,StringRef SearchPath,StringRef RelativePath,const Module * Imported,SrcMgr::CharacteristicKind FileType)4720b57cec5SDimitry Andric   void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
4730b57cec5SDimitry Andric                           StringRef FileName, bool IsAngled,
47481ad6265SDimitry Andric                           CharSourceRange FilenameRange,
475bdd1243dSDimitry Andric                           OptionalFileEntryRef File, StringRef SearchPath,
47681ad6265SDimitry Andric                           StringRef RelativePath, const Module *Imported,
4770b57cec5SDimitry Andric                           SrcMgr::CharacteristicKind FileType) override {
4780b57cec5SDimitry Andric     First->InclusionDirective(HashLoc, IncludeTok, FileName, IsAngled,
4790b57cec5SDimitry Andric                               FilenameRange, File, SearchPath, RelativePath,
4800b57cec5SDimitry Andric                               Imported, FileType);
4810b57cec5SDimitry Andric     Second->InclusionDirective(HashLoc, IncludeTok, FileName, IsAngled,
4820b57cec5SDimitry Andric                                FilenameRange, File, SearchPath, RelativePath,
4830b57cec5SDimitry Andric                                Imported, FileType);
4840b57cec5SDimitry Andric   }
4850b57cec5SDimitry Andric 
EnteredSubmodule(Module * M,SourceLocation ImportLoc,bool ForPragma)4860b57cec5SDimitry Andric   void EnteredSubmodule(Module *M, SourceLocation ImportLoc,
4870b57cec5SDimitry Andric                         bool ForPragma) override {
4880b57cec5SDimitry Andric     First->EnteredSubmodule(M, ImportLoc, ForPragma);
4890b57cec5SDimitry Andric     Second->EnteredSubmodule(M, ImportLoc, ForPragma);
4900b57cec5SDimitry Andric   }
4910b57cec5SDimitry Andric 
LeftSubmodule(Module * M,SourceLocation ImportLoc,bool ForPragma)4920b57cec5SDimitry Andric   void LeftSubmodule(Module *M, SourceLocation ImportLoc,
4930b57cec5SDimitry Andric                      bool ForPragma) override {
4940b57cec5SDimitry Andric     First->LeftSubmodule(M, ImportLoc, ForPragma);
4950b57cec5SDimitry Andric     Second->LeftSubmodule(M, ImportLoc, ForPragma);
4960b57cec5SDimitry Andric   }
4970b57cec5SDimitry Andric 
moduleImport(SourceLocation ImportLoc,ModuleIdPath Path,const Module * Imported)4980b57cec5SDimitry Andric   void moduleImport(SourceLocation ImportLoc, ModuleIdPath Path,
4990b57cec5SDimitry Andric                     const Module *Imported) override {
5000b57cec5SDimitry Andric     First->moduleImport(ImportLoc, Path, Imported);
5010b57cec5SDimitry Andric     Second->moduleImport(ImportLoc, Path, Imported);
5020b57cec5SDimitry Andric   }
5030b57cec5SDimitry Andric 
EndOfMainFile()5040b57cec5SDimitry Andric   void EndOfMainFile() override {
5050b57cec5SDimitry Andric     First->EndOfMainFile();
5060b57cec5SDimitry Andric     Second->EndOfMainFile();
5070b57cec5SDimitry Andric   }
5080b57cec5SDimitry Andric 
Ident(SourceLocation Loc,StringRef str)5090b57cec5SDimitry Andric   void Ident(SourceLocation Loc, StringRef str) override {
5100b57cec5SDimitry Andric     First->Ident(Loc, str);
5110b57cec5SDimitry Andric     Second->Ident(Loc, str);
5120b57cec5SDimitry Andric   }
5130b57cec5SDimitry Andric 
PragmaDirective(SourceLocation Loc,PragmaIntroducerKind Introducer)5140b57cec5SDimitry Andric   void PragmaDirective(SourceLocation Loc,
5150b57cec5SDimitry Andric                        PragmaIntroducerKind Introducer) override {
5160b57cec5SDimitry Andric     First->PragmaDirective(Loc, Introducer);
5170b57cec5SDimitry Andric     Second->PragmaDirective(Loc, Introducer);
5180b57cec5SDimitry Andric   }
5190b57cec5SDimitry Andric 
PragmaComment(SourceLocation Loc,const IdentifierInfo * Kind,StringRef Str)5200b57cec5SDimitry Andric   void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind,
5210b57cec5SDimitry Andric                      StringRef Str) override {
5220b57cec5SDimitry Andric     First->PragmaComment(Loc, Kind, Str);
5230b57cec5SDimitry Andric     Second->PragmaComment(Loc, Kind, Str);
5240b57cec5SDimitry Andric   }
5250b57cec5SDimitry Andric 
PragmaMark(SourceLocation Loc,StringRef Trivia)526349cc55cSDimitry Andric   void PragmaMark(SourceLocation Loc, StringRef Trivia) override {
527349cc55cSDimitry Andric     First->PragmaMark(Loc, Trivia);
528349cc55cSDimitry Andric     Second->PragmaMark(Loc, Trivia);
529349cc55cSDimitry Andric   }
530349cc55cSDimitry Andric 
PragmaDetectMismatch(SourceLocation Loc,StringRef Name,StringRef Value)5310b57cec5SDimitry Andric   void PragmaDetectMismatch(SourceLocation Loc, StringRef Name,
5320b57cec5SDimitry Andric                             StringRef Value) override {
5330b57cec5SDimitry Andric     First->PragmaDetectMismatch(Loc, Name, Value);
5340b57cec5SDimitry Andric     Second->PragmaDetectMismatch(Loc, Name, Value);
5350b57cec5SDimitry Andric   }
5360b57cec5SDimitry Andric 
PragmaDebug(SourceLocation Loc,StringRef DebugType)5370b57cec5SDimitry Andric   void PragmaDebug(SourceLocation Loc, StringRef DebugType) override {
5380b57cec5SDimitry Andric     First->PragmaDebug(Loc, DebugType);
5390b57cec5SDimitry Andric     Second->PragmaDebug(Loc, DebugType);
5400b57cec5SDimitry Andric   }
5410b57cec5SDimitry Andric 
PragmaMessage(SourceLocation Loc,StringRef Namespace,PragmaMessageKind Kind,StringRef Str)5420b57cec5SDimitry Andric   void PragmaMessage(SourceLocation Loc, StringRef Namespace,
5430b57cec5SDimitry Andric                      PragmaMessageKind Kind, StringRef Str) override {
5440b57cec5SDimitry Andric     First->PragmaMessage(Loc, Namespace, Kind, Str);
5450b57cec5SDimitry Andric     Second->PragmaMessage(Loc, Namespace, Kind, Str);
5460b57cec5SDimitry Andric   }
5470b57cec5SDimitry Andric 
PragmaDiagnosticPush(SourceLocation Loc,StringRef Namespace)5480b57cec5SDimitry Andric   void PragmaDiagnosticPush(SourceLocation Loc, StringRef Namespace) override {
5490b57cec5SDimitry Andric     First->PragmaDiagnosticPush(Loc, Namespace);
5500b57cec5SDimitry Andric     Second->PragmaDiagnosticPush(Loc, Namespace);
5510b57cec5SDimitry Andric   }
5520b57cec5SDimitry Andric 
PragmaDiagnosticPop(SourceLocation Loc,StringRef Namespace)5530b57cec5SDimitry Andric   void PragmaDiagnosticPop(SourceLocation Loc, StringRef Namespace) override {
5540b57cec5SDimitry Andric     First->PragmaDiagnosticPop(Loc, Namespace);
5550b57cec5SDimitry Andric     Second->PragmaDiagnosticPop(Loc, Namespace);
5560b57cec5SDimitry Andric   }
5570b57cec5SDimitry Andric 
PragmaDiagnostic(SourceLocation Loc,StringRef Namespace,diag::Severity mapping,StringRef Str)5580b57cec5SDimitry Andric   void PragmaDiagnostic(SourceLocation Loc, StringRef Namespace,
5590b57cec5SDimitry Andric                         diag::Severity mapping, StringRef Str) override {
5600b57cec5SDimitry Andric     First->PragmaDiagnostic(Loc, Namespace, mapping, Str);
5610b57cec5SDimitry Andric     Second->PragmaDiagnostic(Loc, Namespace, mapping, Str);
5620b57cec5SDimitry Andric   }
5630b57cec5SDimitry Andric 
5640b57cec5SDimitry Andric   void HasInclude(SourceLocation Loc, StringRef FileName, bool IsAngled,
565bdd1243dSDimitry Andric                   OptionalFileEntryRef File,
5665ffd83dbSDimitry Andric                   SrcMgr::CharacteristicKind FileType) override;
5670b57cec5SDimitry Andric 
PragmaOpenCLExtension(SourceLocation NameLoc,const IdentifierInfo * Name,SourceLocation StateLoc,unsigned State)5680b57cec5SDimitry Andric   void PragmaOpenCLExtension(SourceLocation NameLoc, const IdentifierInfo *Name,
5690b57cec5SDimitry Andric                              SourceLocation StateLoc, unsigned State) override {
5700b57cec5SDimitry Andric     First->PragmaOpenCLExtension(NameLoc, Name, StateLoc, State);
5710b57cec5SDimitry Andric     Second->PragmaOpenCLExtension(NameLoc, Name, StateLoc, State);
5720b57cec5SDimitry Andric   }
5730b57cec5SDimitry Andric 
PragmaWarning(SourceLocation Loc,PragmaWarningSpecifier WarningSpec,ArrayRef<int> Ids)574349cc55cSDimitry Andric   void PragmaWarning(SourceLocation Loc, PragmaWarningSpecifier WarningSpec,
5750b57cec5SDimitry Andric                      ArrayRef<int> Ids) override {
5760b57cec5SDimitry Andric     First->PragmaWarning(Loc, WarningSpec, Ids);
5770b57cec5SDimitry Andric     Second->PragmaWarning(Loc, WarningSpec, Ids);
5780b57cec5SDimitry Andric   }
5790b57cec5SDimitry Andric 
PragmaWarningPush(SourceLocation Loc,int Level)5800b57cec5SDimitry Andric   void PragmaWarningPush(SourceLocation Loc, int Level) override {
5810b57cec5SDimitry Andric     First->PragmaWarningPush(Loc, Level);
5820b57cec5SDimitry Andric     Second->PragmaWarningPush(Loc, Level);
5830b57cec5SDimitry Andric   }
5840b57cec5SDimitry Andric 
PragmaWarningPop(SourceLocation Loc)5850b57cec5SDimitry Andric   void PragmaWarningPop(SourceLocation Loc) override {
5860b57cec5SDimitry Andric     First->PragmaWarningPop(Loc);
5870b57cec5SDimitry Andric     Second->PragmaWarningPop(Loc);
5880b57cec5SDimitry Andric   }
5890b57cec5SDimitry Andric 
PragmaExecCharsetPush(SourceLocation Loc,StringRef Str)5900b57cec5SDimitry Andric   void PragmaExecCharsetPush(SourceLocation Loc, StringRef Str) override {
5910b57cec5SDimitry Andric     First->PragmaExecCharsetPush(Loc, Str);
5920b57cec5SDimitry Andric     Second->PragmaExecCharsetPush(Loc, Str);
5930b57cec5SDimitry Andric   }
5940b57cec5SDimitry Andric 
PragmaExecCharsetPop(SourceLocation Loc)5950b57cec5SDimitry Andric   void PragmaExecCharsetPop(SourceLocation Loc) override {
5960b57cec5SDimitry Andric     First->PragmaExecCharsetPop(Loc);
5970b57cec5SDimitry Andric     Second->PragmaExecCharsetPop(Loc);
5980b57cec5SDimitry Andric   }
5990b57cec5SDimitry Andric 
PragmaAssumeNonNullBegin(SourceLocation Loc)6000b57cec5SDimitry Andric   void PragmaAssumeNonNullBegin(SourceLocation Loc) override {
6010b57cec5SDimitry Andric     First->PragmaAssumeNonNullBegin(Loc);
6020b57cec5SDimitry Andric     Second->PragmaAssumeNonNullBegin(Loc);
6030b57cec5SDimitry Andric   }
6040b57cec5SDimitry Andric 
PragmaAssumeNonNullEnd(SourceLocation Loc)6050b57cec5SDimitry Andric   void PragmaAssumeNonNullEnd(SourceLocation Loc) override {
6060b57cec5SDimitry Andric     First->PragmaAssumeNonNullEnd(Loc);
6070b57cec5SDimitry Andric     Second->PragmaAssumeNonNullEnd(Loc);
6080b57cec5SDimitry Andric   }
6090b57cec5SDimitry Andric 
MacroExpands(const Token & MacroNameTok,const MacroDefinition & MD,SourceRange Range,const MacroArgs * Args)6100b57cec5SDimitry Andric   void MacroExpands(const Token &MacroNameTok, const MacroDefinition &MD,
6110b57cec5SDimitry Andric                     SourceRange Range, const MacroArgs *Args) override {
6120b57cec5SDimitry Andric     First->MacroExpands(MacroNameTok, MD, Range, Args);
6130b57cec5SDimitry Andric     Second->MacroExpands(MacroNameTok, MD, Range, Args);
6140b57cec5SDimitry Andric   }
6150b57cec5SDimitry Andric 
MacroDefined(const Token & MacroNameTok,const MacroDirective * MD)6160b57cec5SDimitry Andric   void MacroDefined(const Token &MacroNameTok,
6170b57cec5SDimitry Andric                     const MacroDirective *MD) override {
6180b57cec5SDimitry Andric     First->MacroDefined(MacroNameTok, MD);
6190b57cec5SDimitry Andric     Second->MacroDefined(MacroNameTok, MD);
6200b57cec5SDimitry Andric   }
6210b57cec5SDimitry Andric 
MacroUndefined(const Token & MacroNameTok,const MacroDefinition & MD,const MacroDirective * Undef)6220b57cec5SDimitry Andric   void MacroUndefined(const Token &MacroNameTok,
6230b57cec5SDimitry Andric                       const MacroDefinition &MD,
6240b57cec5SDimitry Andric                       const MacroDirective *Undef) override {
6250b57cec5SDimitry Andric     First->MacroUndefined(MacroNameTok, MD, Undef);
6260b57cec5SDimitry Andric     Second->MacroUndefined(MacroNameTok, MD, Undef);
6270b57cec5SDimitry Andric   }
6280b57cec5SDimitry Andric 
Defined(const Token & MacroNameTok,const MacroDefinition & MD,SourceRange Range)6290b57cec5SDimitry Andric   void Defined(const Token &MacroNameTok, const MacroDefinition &MD,
6300b57cec5SDimitry Andric                SourceRange Range) override {
6310b57cec5SDimitry Andric     First->Defined(MacroNameTok, MD, Range);
6320b57cec5SDimitry Andric     Second->Defined(MacroNameTok, MD, Range);
6330b57cec5SDimitry Andric   }
6340b57cec5SDimitry Andric 
SourceRangeSkipped(SourceRange Range,SourceLocation EndifLoc)6350b57cec5SDimitry Andric   void SourceRangeSkipped(SourceRange Range, SourceLocation EndifLoc) override {
6360b57cec5SDimitry Andric     First->SourceRangeSkipped(Range, EndifLoc);
6370b57cec5SDimitry Andric     Second->SourceRangeSkipped(Range, EndifLoc);
6380b57cec5SDimitry Andric   }
6390b57cec5SDimitry Andric 
6400b57cec5SDimitry Andric   /// Hook called whenever an \#if is seen.
If(SourceLocation Loc,SourceRange ConditionRange,ConditionValueKind ConditionValue)6410b57cec5SDimitry Andric   void If(SourceLocation Loc, SourceRange ConditionRange,
6420b57cec5SDimitry Andric           ConditionValueKind ConditionValue) override {
6430b57cec5SDimitry Andric     First->If(Loc, ConditionRange, ConditionValue);
6440b57cec5SDimitry Andric     Second->If(Loc, ConditionRange, ConditionValue);
6450b57cec5SDimitry Andric   }
6460b57cec5SDimitry Andric 
6470b57cec5SDimitry Andric   /// Hook called whenever an \#elif is seen.
Elif(SourceLocation Loc,SourceRange ConditionRange,ConditionValueKind ConditionValue,SourceLocation IfLoc)6480b57cec5SDimitry Andric   void Elif(SourceLocation Loc, SourceRange ConditionRange,
6490b57cec5SDimitry Andric             ConditionValueKind ConditionValue, SourceLocation IfLoc) override {
6500b57cec5SDimitry Andric     First->Elif(Loc, ConditionRange, ConditionValue, IfLoc);
6510b57cec5SDimitry Andric     Second->Elif(Loc, ConditionRange, ConditionValue, IfLoc);
6520b57cec5SDimitry Andric   }
6530b57cec5SDimitry Andric 
6540b57cec5SDimitry Andric   /// Hook called whenever an \#ifdef is seen.
Ifdef(SourceLocation Loc,const Token & MacroNameTok,const MacroDefinition & MD)6550b57cec5SDimitry Andric   void Ifdef(SourceLocation Loc, const Token &MacroNameTok,
6560b57cec5SDimitry Andric              const MacroDefinition &MD) override {
6570b57cec5SDimitry Andric     First->Ifdef(Loc, MacroNameTok, MD);
6580b57cec5SDimitry Andric     Second->Ifdef(Loc, MacroNameTok, MD);
6590b57cec5SDimitry Andric   }
6600b57cec5SDimitry Andric 
661fe6060f1SDimitry Andric   /// Hook called whenever an \#elifdef is taken.
Elifdef(SourceLocation Loc,const Token & MacroNameTok,const MacroDefinition & MD)662fe6060f1SDimitry Andric   void Elifdef(SourceLocation Loc, const Token &MacroNameTok,
663fe6060f1SDimitry Andric                const MacroDefinition &MD) override {
664fe6060f1SDimitry Andric     First->Elifdef(Loc, MacroNameTok, MD);
665fe6060f1SDimitry Andric     Second->Elifdef(Loc, MacroNameTok, MD);
666fe6060f1SDimitry Andric   }
667fe6060f1SDimitry Andric   /// Hook called whenever an \#elifdef is skipped.
Elifdef(SourceLocation Loc,SourceRange ConditionRange,SourceLocation IfLoc)668fe6060f1SDimitry Andric   void Elifdef(SourceLocation Loc, SourceRange ConditionRange,
669fe6060f1SDimitry Andric                SourceLocation IfLoc) override {
670fe6060f1SDimitry Andric     First->Elifdef(Loc, ConditionRange, IfLoc);
671fe6060f1SDimitry Andric     Second->Elifdef(Loc, ConditionRange, IfLoc);
672fe6060f1SDimitry Andric   }
673fe6060f1SDimitry Andric 
6740b57cec5SDimitry Andric   /// Hook called whenever an \#ifndef is seen.
Ifndef(SourceLocation Loc,const Token & MacroNameTok,const MacroDefinition & MD)6750b57cec5SDimitry Andric   void Ifndef(SourceLocation Loc, const Token &MacroNameTok,
6760b57cec5SDimitry Andric               const MacroDefinition &MD) override {
6770b57cec5SDimitry Andric     First->Ifndef(Loc, MacroNameTok, MD);
6780b57cec5SDimitry Andric     Second->Ifndef(Loc, MacroNameTok, MD);
6790b57cec5SDimitry Andric   }
6800b57cec5SDimitry Andric 
681fe6060f1SDimitry Andric   /// Hook called whenever an \#elifndef is taken.
Elifndef(SourceLocation Loc,const Token & MacroNameTok,const MacroDefinition & MD)682fe6060f1SDimitry Andric   void Elifndef(SourceLocation Loc, const Token &MacroNameTok,
683fe6060f1SDimitry Andric                 const MacroDefinition &MD) override {
684fe6060f1SDimitry Andric     First->Elifndef(Loc, MacroNameTok, MD);
685fe6060f1SDimitry Andric     Second->Elifndef(Loc, MacroNameTok, MD);
686fe6060f1SDimitry Andric   }
687fe6060f1SDimitry Andric   /// Hook called whenever an \#elifndef is skipped.
Elifndef(SourceLocation Loc,SourceRange ConditionRange,SourceLocation IfLoc)688fe6060f1SDimitry Andric   void Elifndef(SourceLocation Loc, SourceRange ConditionRange,
689fe6060f1SDimitry Andric                SourceLocation IfLoc) override {
690fe6060f1SDimitry Andric     First->Elifndef(Loc, ConditionRange, IfLoc);
691fe6060f1SDimitry Andric     Second->Elifndef(Loc, ConditionRange, IfLoc);
692fe6060f1SDimitry Andric   }
693fe6060f1SDimitry Andric 
6940b57cec5SDimitry Andric   /// Hook called whenever an \#else is seen.
Else(SourceLocation Loc,SourceLocation IfLoc)6950b57cec5SDimitry Andric   void Else(SourceLocation Loc, SourceLocation IfLoc) override {
6960b57cec5SDimitry Andric     First->Else(Loc, IfLoc);
6970b57cec5SDimitry Andric     Second->Else(Loc, IfLoc);
6980b57cec5SDimitry Andric   }
6990b57cec5SDimitry Andric 
7000b57cec5SDimitry Andric   /// Hook called whenever an \#endif is seen.
Endif(SourceLocation Loc,SourceLocation IfLoc)7010b57cec5SDimitry Andric   void Endif(SourceLocation Loc, SourceLocation IfLoc) override {
7020b57cec5SDimitry Andric     First->Endif(Loc, IfLoc);
7030b57cec5SDimitry Andric     Second->Endif(Loc, IfLoc);
7040b57cec5SDimitry Andric   }
7050b57cec5SDimitry Andric };
7060b57cec5SDimitry Andric 
7070b57cec5SDimitry Andric }  // end namespace clang
7080b57cec5SDimitry Andric 
7090b57cec5SDimitry Andric #endif
710