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