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