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