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. LexedFileChanged(FileID FID,LexedFileChangeReason Reason,SrcMgr::CharacteristicKind FileType,FileID PrevFID,SourceLocation Loc)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. FileSkipped(const FileEntryRef & SkippedFile,const Token & FilenameTok,SrcMgr::CharacteristicKind FileType)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. FileNotFound(StringRef FileName)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 /// InclusionDirective(SourceLocation HashLoc,const Token & IncludeTok,StringRef FileName,bool IsAngled,CharSourceRange FilenameRange,OptionalFileEntryRef File,StringRef SearchPath,StringRef RelativePath,const Module * Imported,SrcMgr::CharacteristicKind FileType)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 /// EnteredSubmodule(Module * M,SourceLocation ImportLoc,bool ForPragma)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 /// LeftSubmodule(Module * M,SourceLocation ImportLoc,bool ForPragma)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 /// moduleImport(SourceLocation ImportLoc,ModuleIdPath Path,const Module * Imported)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. EndOfMainFile()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 /// Ident(SourceLocation Loc,StringRef str)192 virtual void Ident(SourceLocation Loc, StringRef str) { 193 } 194 195 /// Callback invoked when start reading any pragma directive. PragmaDirective(SourceLocation Loc,PragmaIntroducerKind Introducer)196 virtual void PragmaDirective(SourceLocation Loc, 197 PragmaIntroducerKind Introducer) { 198 } 199 200 /// Callback invoked when a \#pragma comment directive is read. PragmaComment(SourceLocation Loc,const IdentifierInfo * Kind,StringRef Str)201 virtual void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind, 202 StringRef Str) { 203 } 204 205 /// Callback invoked when a \#pragma mark comment is read. PragmaMark(SourceLocation Loc,StringRef Trivia)206 virtual void PragmaMark(SourceLocation Loc, StringRef Trivia) { 207 } 208 209 /// Callback invoked when a \#pragma detect_mismatch directive is 210 /// read. PragmaDetectMismatch(SourceLocation Loc,StringRef Name,StringRef Value)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. PragmaDebug(SourceLocation Loc,StringRef DebugType)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. PragmaMessage(SourceLocation Loc,StringRef Namespace,PragmaMessageKind Kind,StringRef Str)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. PragmaDiagnosticPush(SourceLocation Loc,StringRef Namespace)244 virtual void PragmaDiagnosticPush(SourceLocation Loc, 245 StringRef Namespace) { 246 } 247 248 /// Callback invoked when a \#pragma gcc diagnostic pop directive 249 /// is read. PragmaDiagnosticPop(SourceLocation Loc,StringRef Namespace)250 virtual void PragmaDiagnosticPop(SourceLocation Loc, 251 StringRef Namespace) { 252 } 253 254 /// Callback invoked when a \#pragma gcc diagnostic directive is read. PragmaDiagnostic(SourceLocation Loc,StringRef Namespace,diag::Severity mapping,StringRef Str)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. PragmaOpenCLExtension(SourceLocation NameLoc,const IdentifierInfo * Name,SourceLocation StateLoc,unsigned State)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 }; PragmaWarning(SourceLocation Loc,PragmaWarningSpecifier WarningSpec,ArrayRef<int> Ids)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. PragmaWarningPush(SourceLocation Loc,int Level)282 virtual void PragmaWarningPush(SourceLocation Loc, int Level) { 283 } 284 285 /// Callback invoked when a \#pragma warning(pop) directive is read. PragmaWarningPop(SourceLocation Loc)286 virtual void PragmaWarningPop(SourceLocation Loc) { 287 } 288 289 /// Callback invoked when a \#pragma execution_character_set(push) directive 290 /// is read. PragmaExecCharsetPush(SourceLocation Loc,StringRef Str)291 virtual void PragmaExecCharsetPush(SourceLocation Loc, StringRef Str) {} 292 293 /// Callback invoked when a \#pragma execution_character_set(pop) directive 294 /// is read. PragmaExecCharsetPop(SourceLocation Loc)295 virtual void PragmaExecCharsetPop(SourceLocation Loc) {} 296 297 /// Callback invoked when a \#pragma clang assume_nonnull begin directive 298 /// is read. PragmaAssumeNonNullBegin(SourceLocation Loc)299 virtual void PragmaAssumeNonNullBegin(SourceLocation Loc) {} 300 301 /// Callback invoked when a \#pragma clang assume_nonnull end directive 302 /// is read. PragmaAssumeNonNullEnd(SourceLocation Loc)303 virtual void PragmaAssumeNonNullEnd(SourceLocation Loc) {} 304 305 /// Called by Preprocessor::HandleMacroExpandedIdentifier when a 306 /// macro invocation is found. MacroExpands(const Token & MacroNameTok,const MacroDefinition & MD,SourceRange Range,const MacroArgs * Args)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. MacroDefined(const Token & MacroNameTok,const MacroDirective * MD)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. MacroUndefined(const Token & MacroNameTok,const MacroDefinition & MD,const MacroDirective * Undef)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. Defined(const Token & MacroNameTok,const MacroDefinition & MD,SourceRange Range)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'). SourceRangeSkipped(SourceRange Range,SourceLocation EndifLoc)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. If(SourceLocation Loc,SourceRange ConditionRange,ConditionValueKind ConditionValue)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. Elif(SourceLocation Loc,SourceRange ConditionRange,ConditionValueKind ConditionValue,SourceLocation IfLoc)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. Ifdef(SourceLocation Loc,const Token & MacroNameTok,const MacroDefinition & MD)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. Elifdef(SourceLocation Loc,const Token & MacroNameTok,const MacroDefinition & MD)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. Elifdef(SourceLocation Loc,SourceRange ConditionRange,SourceLocation IfLoc)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. Ifndef(SourceLocation Loc,const Token & MacroNameTok,const MacroDefinition & MD)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. Elifndef(SourceLocation Loc,const Token & MacroNameTok,const MacroDefinition & MD)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. Elifndef(SourceLocation Loc,SourceRange ConditionRange,SourceLocation IfLoc)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. Else(SourceLocation Loc,SourceLocation IfLoc)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. Endif(SourceLocation Loc,SourceLocation IfLoc)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: PPChainedCallbacks(std::unique_ptr<PPCallbacks> _First,std::unique_ptr<PPCallbacks> _Second)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 FileChanged(SourceLocation Loc,FileChangeReason Reason,SrcMgr::CharacteristicKind FileType,FileID PrevFID)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 LexedFileChanged(FileID FID,LexedFileChangeReason Reason,SrcMgr::CharacteristicKind FileType,FileID PrevFID,SourceLocation Loc)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 FileSkipped(const FileEntryRef & SkippedFile,const Token & FilenameTok,SrcMgr::CharacteristicKind FileType)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 FileNotFound(StringRef FileName)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 InclusionDirective(SourceLocation HashLoc,const Token & IncludeTok,StringRef FileName,bool IsAngled,CharSourceRange FilenameRange,OptionalFileEntryRef File,StringRef SearchPath,StringRef RelativePath,const Module * Imported,SrcMgr::CharacteristicKind FileType)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 EnteredSubmodule(Module * M,SourceLocation ImportLoc,bool ForPragma)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 LeftSubmodule(Module * M,SourceLocation ImportLoc,bool ForPragma)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 moduleImport(SourceLocation ImportLoc,ModuleIdPath Path,const Module * Imported)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 EndOfMainFile()504 void EndOfMainFile() override { 505 First->EndOfMainFile(); 506 Second->EndOfMainFile(); 507 } 508 Ident(SourceLocation Loc,StringRef str)509 void Ident(SourceLocation Loc, StringRef str) override { 510 First->Ident(Loc, str); 511 Second->Ident(Loc, str); 512 } 513 PragmaDirective(SourceLocation Loc,PragmaIntroducerKind Introducer)514 void PragmaDirective(SourceLocation Loc, 515 PragmaIntroducerKind Introducer) override { 516 First->PragmaDirective(Loc, Introducer); 517 Second->PragmaDirective(Loc, Introducer); 518 } 519 PragmaComment(SourceLocation Loc,const IdentifierInfo * Kind,StringRef Str)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 PragmaMark(SourceLocation Loc,StringRef Trivia)526 void PragmaMark(SourceLocation Loc, StringRef Trivia) override { 527 First->PragmaMark(Loc, Trivia); 528 Second->PragmaMark(Loc, Trivia); 529 } 530 PragmaDetectMismatch(SourceLocation Loc,StringRef Name,StringRef Value)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 PragmaDebug(SourceLocation Loc,StringRef DebugType)537 void PragmaDebug(SourceLocation Loc, StringRef DebugType) override { 538 First->PragmaDebug(Loc, DebugType); 539 Second->PragmaDebug(Loc, DebugType); 540 } 541 PragmaMessage(SourceLocation Loc,StringRef Namespace,PragmaMessageKind Kind,StringRef Str)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 PragmaDiagnosticPush(SourceLocation Loc,StringRef Namespace)548 void PragmaDiagnosticPush(SourceLocation Loc, StringRef Namespace) override { 549 First->PragmaDiagnosticPush(Loc, Namespace); 550 Second->PragmaDiagnosticPush(Loc, Namespace); 551 } 552 PragmaDiagnosticPop(SourceLocation Loc,StringRef Namespace)553 void PragmaDiagnosticPop(SourceLocation Loc, StringRef Namespace) override { 554 First->PragmaDiagnosticPop(Loc, Namespace); 555 Second->PragmaDiagnosticPop(Loc, Namespace); 556 } 557 PragmaDiagnostic(SourceLocation Loc,StringRef Namespace,diag::Severity mapping,StringRef Str)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 PragmaOpenCLExtension(SourceLocation NameLoc,const IdentifierInfo * Name,SourceLocation StateLoc,unsigned State)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 PragmaWarning(SourceLocation Loc,PragmaWarningSpecifier WarningSpec,ArrayRef<int> Ids)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 PragmaWarningPush(SourceLocation Loc,int Level)580 void PragmaWarningPush(SourceLocation Loc, int Level) override { 581 First->PragmaWarningPush(Loc, Level); 582 Second->PragmaWarningPush(Loc, Level); 583 } 584 PragmaWarningPop(SourceLocation Loc)585 void PragmaWarningPop(SourceLocation Loc) override { 586 First->PragmaWarningPop(Loc); 587 Second->PragmaWarningPop(Loc); 588 } 589 PragmaExecCharsetPush(SourceLocation Loc,StringRef Str)590 void PragmaExecCharsetPush(SourceLocation Loc, StringRef Str) override { 591 First->PragmaExecCharsetPush(Loc, Str); 592 Second->PragmaExecCharsetPush(Loc, Str); 593 } 594 PragmaExecCharsetPop(SourceLocation Loc)595 void PragmaExecCharsetPop(SourceLocation Loc) override { 596 First->PragmaExecCharsetPop(Loc); 597 Second->PragmaExecCharsetPop(Loc); 598 } 599 PragmaAssumeNonNullBegin(SourceLocation Loc)600 void PragmaAssumeNonNullBegin(SourceLocation Loc) override { 601 First->PragmaAssumeNonNullBegin(Loc); 602 Second->PragmaAssumeNonNullBegin(Loc); 603 } 604 PragmaAssumeNonNullEnd(SourceLocation Loc)605 void PragmaAssumeNonNullEnd(SourceLocation Loc) override { 606 First->PragmaAssumeNonNullEnd(Loc); 607 Second->PragmaAssumeNonNullEnd(Loc); 608 } 609 MacroExpands(const Token & MacroNameTok,const MacroDefinition & MD,SourceRange Range,const MacroArgs * Args)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 MacroDefined(const Token & MacroNameTok,const MacroDirective * MD)616 void MacroDefined(const Token &MacroNameTok, 617 const MacroDirective *MD) override { 618 First->MacroDefined(MacroNameTok, MD); 619 Second->MacroDefined(MacroNameTok, MD); 620 } 621 MacroUndefined(const Token & MacroNameTok,const MacroDefinition & MD,const MacroDirective * Undef)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 Defined(const Token & MacroNameTok,const MacroDefinition & MD,SourceRange Range)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 SourceRangeSkipped(SourceRange Range,SourceLocation EndifLoc)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. If(SourceLocation Loc,SourceRange ConditionRange,ConditionValueKind ConditionValue)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. Elif(SourceLocation Loc,SourceRange ConditionRange,ConditionValueKind ConditionValue,SourceLocation IfLoc)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. Ifdef(SourceLocation Loc,const Token & MacroNameTok,const MacroDefinition & MD)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. Elifdef(SourceLocation Loc,const Token & MacroNameTok,const MacroDefinition & MD)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. Elifdef(SourceLocation Loc,SourceRange ConditionRange,SourceLocation IfLoc)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. Ifndef(SourceLocation Loc,const Token & MacroNameTok,const MacroDefinition & MD)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. Elifndef(SourceLocation Loc,const Token & MacroNameTok,const MacroDefinition & MD)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. Elifndef(SourceLocation Loc,SourceRange ConditionRange,SourceLocation IfLoc)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. Else(SourceLocation Loc,SourceLocation IfLoc)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. Endif(SourceLocation Loc,SourceLocation IfLoc)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