Coverage Report

Created: 2022-07-16 07:03

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/include/clang/Lex/PPCallbacks.h
Line
Count
Source (jump to first uncovered line)
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
1.56M
                           FileID PrevFID = FileID()) {
51
1.56M
  }
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
1.88M
                                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
1.75M
                           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
2.52M
                                  SrcMgr::CharacteristicKind FileType) {
137
2.52M
  }
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
108k
                                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
108k
                             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
2.72k
                            const Module *Imported) {
174
2.72k
  }
175
176
  /// Callback invoked when the end of the main file is reached.
177
  ///
178
  /// No subsequent callbacks will be made.
179
103k
  virtual void EndOfMainFile() {
180
103k
  }
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
1
  virtual void Ident(SourceLocation Loc, StringRef str) {
187
1
  }
188
189
  /// Callback invoked when start reading any pragma directive.
190
  virtual void PragmaDirective(SourceLocation Loc,
191
2.45M
                               PragmaIntroducerKind Introducer) {
192
2.45M
  }
193
194
  /// Callback invoked when a \#pragma comment directive is read.
195
  virtual void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind,
196
82
                             StringRef Str) {
197
82
  }
198
199
  /// Callback invoked when a \#pragma mark comment is read.
200
73.9k
  virtual void PragmaMark(SourceLocation Loc, StringRef Trivia) {
201
73.9k
  }
202
203
  /// Callback invoked when a \#pragma detect_mismatch directive is
204
  /// read.
205
  virtual void PragmaDetectMismatch(SourceLocation Loc, StringRef Name,
206
18
                                    StringRef Value) {
207
18
  }
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
184
  virtual void PragmaDebug(SourceLocation Loc, StringRef DebugType) {
213
184
  }
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
44
                             PragmaMessageKind Kind, StringRef Str) {
234
44
  }
235
236
  /// Callback invoked when a \#pragma gcc diagnostic push directive
237
  /// is read.
238
  virtual void PragmaDiagnosticPush(SourceLocation Loc,
239
117k
                                    StringRef Namespace) {
240
117k
  }
241
242
  /// Callback invoked when a \#pragma gcc diagnostic pop directive
243
  /// is read.
244
  virtual void PragmaDiagnosticPop(SourceLocation Loc,
245
117k
                                   StringRef Namespace) {
246
117k
  }
247
248
  /// Callback invoked when a \#pragma gcc diagnostic directive is read.
249
  virtual void PragmaDiagnostic(SourceLocation Loc, StringRef Namespace,
250
141k
                                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
3.37k
                                     SourceLocation StateLoc, unsigned State) {
257
3.37k
  }
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
31
                             ArrayRef<int> Ids) {}
274
275
  /// Callback invoked when a \#pragma warning(push) directive is read.
276
20
  virtual void PragmaWarningPush(SourceLocation Loc, int Level) {
277
20
  }
278
279
  /// Callback invoked when a \#pragma warning(pop) directive is read.
280
14
  virtual void PragmaWarningPop(SourceLocation Loc) {
281
14
  }
282
283
  /// Callback invoked when a \#pragma execution_character_set(push) directive
284
  /// is read.
285
8
  virtual void PragmaExecCharsetPush(SourceLocation Loc, StringRef Str) {}
286
287
  /// Callback invoked when a \#pragma execution_character_set(pop) directive
288
  /// is read.
289
6
  virtual void PragmaExecCharsetPop(SourceLocation Loc) {}
290
291
  /// Callback invoked when a \#pragma clang assume_nonnull begin directive
292
  /// is read.
293
142k
  virtual void PragmaAssumeNonNullBegin(SourceLocation Loc) {}
294
295
  /// Callback invoked when a \#pragma clang assume_nonnull end directive
296
  /// is read.
297
142k
  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
104M
                            const MacroArgs *Args) {}
304
305
  /// Hook called whenever a macro definition is seen.
306
  virtual void MacroDefined(const Token &MacroNameTok,
307
65.6M
                            const MacroDirective *MD) {
308
65.6M
  }
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
210k
                              const MacroDirective *Undef) {
319
210k
  }
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
2.77M
                       SourceRange Range) {
325
2.77M
  }
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
4.95M
  virtual void SourceRangeSkipped(SourceRange Range, SourceLocation EndifLoc) {
340
4.95M
  }
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
4.44M
                  ConditionValueKind ConditionValue) {
354
4.44M
  }
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
343k
                    ConditionValueKind ConditionValue, SourceLocation IfLoc) {
364
343k
  }
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
1.84M
                     const MacroDefinition &MD) {
372
1.84M
  }
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
36
                       const MacroDefinition &MD) {
380
36
  }
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
26
                       SourceLocation IfLoc) {
388
26
  }
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
9.74M
                      const MacroDefinition &MD) {
396
9.74M
  }
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
29
                        const MacroDefinition &MD) {
404
29
  }
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
25
                        SourceLocation IfLoc) {
412
25
  }
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
2.76M
  virtual void Else(SourceLocation Loc, SourceLocation IfLoc) {
418
2.76M
  }
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
16.0M
  virtual void Endif(SourceLocation Loc, SourceLocation IfLoc) {
424
16.0M
  }
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
51.4k
    : 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
1.67M
                   FileID PrevFID) override {
441
1.67M
    First->FileChanged(Loc, Reason, FileType, PrevFID);
442
1.67M
    Second->FileChanged(Loc, Reason, FileType, PrevFID);
443
1.67M
  }
444
445
  void LexedFileChanged(FileID FID, LexedFileChangeReason Reason,
446
                        SrcMgr::CharacteristicKind FileType, FileID PrevFID,
447
1.26M
                        SourceLocation Loc) override {
448
1.26M
    First->LexedFileChanged(FID, Reason, FileType, PrevFID, Loc);
449
1.26M
    Second->LexedFileChanged(FID, Reason, FileType, PrevFID, Loc);
450
1.26M
  }
451
452
  void FileSkipped(const FileEntryRef &SkippedFile, const Token &FilenameTok,
453
1.73M
                   SrcMgr::CharacteristicKind FileType) override {
454
1.73M
    First->FileSkipped(SkippedFile, FilenameTok, FileType);
455
1.73M
    Second->FileSkipped(SkippedFile, FilenameTok, FileType);
456
1.73M
  }
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
2.29M
                          SrcMgr::CharacteristicKind FileType) override {
464
2.29M
    First->InclusionDirective(HashLoc, IncludeTok, FileName, IsAngled,
465
2.29M
                              FilenameRange, File, SearchPath, RelativePath,
466
2.29M
                              Imported, FileType);
467
2.29M
    Second->InclusionDirective(HashLoc, IncludeTok, FileName, IsAngled,
468
2.29M
                               FilenameRange, File, SearchPath, RelativePath,
469
2.29M
                               Imported, FileType);
470
2.29M
  }
471
472
  void EnteredSubmodule(Module *M, SourceLocation ImportLoc,
473
302
                        bool ForPragma) override {
474
302
    First->EnteredSubmodule(M, ImportLoc, ForPragma);
475
302
    Second->EnteredSubmodule(M, ImportLoc, ForPragma);
476
302
  }
477
478
  void LeftSubmodule(Module *M, SourceLocation ImportLoc,
479
300
                     bool ForPragma) override {
480
300
    First->LeftSubmodule(M, ImportLoc, ForPragma);
481
300
    Second->LeftSubmodule(M, ImportLoc, ForPragma);
482
300
  }
483
484
  void moduleImport(SourceLocation ImportLoc, ModuleIdPath Path,
485
1.56k
                    const Module *Imported) override {
486
1.56k
    First->moduleImport(ImportLoc, Path, Imported);
487
1.56k
    Second->moduleImport(ImportLoc, Path, Imported);
488
1.56k
  }
489
490
35.6k
  void EndOfMainFile() override {
491
35.6k
    First->EndOfMainFile();
492
35.6k
    Second->EndOfMainFile();
493
35.6k
  }
494
495
0
  void Ident(SourceLocation Loc, StringRef str) override {
496
0
    First->Ident(Loc, str);
497
0
    Second->Ident(Loc, str);
498
0
  }
499
500
  void PragmaDirective(SourceLocation Loc,
501
1.17M
                       PragmaIntroducerKind Introducer) override {
502
1.17M
    First->PragmaDirective(Loc, Introducer);
503
1.17M
    Second->PragmaDirective(Loc, Introducer);
504
1.17M
  }
505
506
  void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind,
507
16
                     StringRef Str) override {
508
16
    First->PragmaComment(Loc, Kind, Str);
509
16
    Second->PragmaComment(Loc, Kind, Str);
510
16
  }
511
512
35.8k
  void PragmaMark(SourceLocation Loc, StringRef Trivia) override {
513
35.8k
    First->PragmaMark(Loc, Trivia);
514
35.8k
    Second->PragmaMark(Loc, Trivia);
515
35.8k
  }
516
517
  void PragmaDetectMismatch(SourceLocation Loc, StringRef Name,
518
2
                            StringRef Value) override {
519
2
    First->PragmaDetectMismatch(Loc, Name, Value);
520
2
    Second->PragmaDetectMismatch(Loc, Name, Value);
521
2
  }
522
523
69
  void PragmaDebug(SourceLocation Loc, StringRef DebugType) override {
524
69
    First->PragmaDebug(Loc, DebugType);
525
69
    Second->PragmaDebug(Loc, DebugType);
526
69
  }
527
528
  void PragmaMessage(SourceLocation Loc, StringRef Namespace,
529
22
                     PragmaMessageKind Kind, StringRef Str) override {
530
22
    First->PragmaMessage(Loc, Namespace, Kind, Str);
531
22
    Second->PragmaMessage(Loc, Namespace, Kind, Str);
532
22
  }
533
534
56.1k
  void PragmaDiagnosticPush(SourceLocation Loc, StringRef Namespace) override {
535
56.1k
    First->PragmaDiagnosticPush(Loc, Namespace);
536
56.1k
    Second->PragmaDiagnosticPush(Loc, Namespace);
537
56.1k
  }
538
539
56.1k
  void PragmaDiagnosticPop(SourceLocation Loc, StringRef Namespace) override {
540
56.1k
    First->PragmaDiagnosticPop(Loc, Namespace);
541
56.1k
    Second->PragmaDiagnosticPop(Loc, Namespace);
542
56.1k
  }
543
544
  void PragmaDiagnostic(SourceLocation Loc, StringRef Namespace,
545
67.4k
                        diag::Severity mapping, StringRef Str) override {
546
67.4k
    First->PragmaDiagnostic(Loc, Namespace, mapping, Str);
547
67.4k
    Second->PragmaDiagnostic(Loc, Namespace, mapping, Str);
548
67.4k
  }
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
1.56k
                             SourceLocation StateLoc, unsigned State) override {
556
1.56k
    First->PragmaOpenCLExtension(NameLoc, Name, StateLoc, State);
557
1.56k
    Second->PragmaOpenCLExtension(NameLoc, Name, StateLoc, State);
558
1.56k
  }
559
560
  void PragmaWarning(SourceLocation Loc, PragmaWarningSpecifier WarningSpec,
561
15
                     ArrayRef<int> Ids) override {
562
15
    First->PragmaWarning(Loc, WarningSpec, Ids);
563
15
    Second->PragmaWarning(Loc, WarningSpec, Ids);
564
15
  }
565
566
10
  void PragmaWarningPush(SourceLocation Loc, int Level) override {
567
10
    First->PragmaWarningPush(Loc, Level);
568
10
    Second->PragmaWarningPush(Loc, Level);
569
10
  }
570
571
7
  void PragmaWarningPop(SourceLocation Loc) override {
572
7
    First->PragmaWarningPop(Loc);
573
7
    Second->PragmaWarningPop(Loc);
574
7
  }
575
576
4
  void PragmaExecCharsetPush(SourceLocation Loc, StringRef Str) override {
577
4
    First->PragmaExecCharsetPush(Loc, Str);
578
4
    Second->PragmaExecCharsetPush(Loc, Str);
579
4
  }
580
581
3
  void PragmaExecCharsetPop(SourceLocation Loc) override {
582
3
    First->PragmaExecCharsetPop(Loc);
583
3
    Second->PragmaExecCharsetPop(Loc);
584
3
  }
585
586
69.8k
  void PragmaAssumeNonNullBegin(SourceLocation Loc) override {
587
69.8k
    First->PragmaAssumeNonNullBegin(Loc);
588
69.8k
    Second->PragmaAssumeNonNullBegin(Loc);
589
69.8k
  }
590
591
69.8k
  void PragmaAssumeNonNullEnd(SourceLocation Loc) override {
592
69.8k
    First->PragmaAssumeNonNullEnd(Loc);
593
69.8k
    Second->PragmaAssumeNonNullEnd(Loc);
594
69.8k
  }
595
596
  void MacroExpands(const Token &MacroNameTok, const MacroDefinition &MD,
597
41.6M
                    SourceRange Range, const MacroArgs *Args) override {
598
41.6M
    First->MacroExpands(MacroNameTok, MD, Range, Args);
599
41.6M
    Second->MacroExpands(MacroNameTok, MD, Range, Args);
600
41.6M
  }
601
602
  void MacroDefined(const Token &MacroNameTok,
603
26.9M
                    const MacroDirective *MD) override {
604
26.9M
    First->MacroDefined(MacroNameTok, MD);
605
26.9M
    Second->MacroDefined(MacroNameTok, MD);
606
26.9M
  }
607
608
  void MacroUndefined(const Token &MacroNameTok,
609
                      const MacroDefinition &MD,
610
85.1k
                      const MacroDirective *Undef) override {
611
85.1k
    First->MacroUndefined(MacroNameTok, MD, Undef);
612
85.1k
    Second->MacroUndefined(MacroNameTok, MD, Undef);
613
85.1k
  }
614
615
  void Defined(const Token &MacroNameTok, const MacroDefinition &MD,
616
1.22M
               SourceRange Range) override {
617
1.22M
    First->Defined(MacroNameTok, MD, Range);
618
1.22M
    Second->Defined(MacroNameTok, MD, Range);
619
1.22M
  }
620
621
2.02M
  void SourceRangeSkipped(SourceRange Range, SourceLocation EndifLoc) override {
622
2.02M
    First->SourceRangeSkipped(Range, EndifLoc);
623
2.02M
    Second->SourceRangeSkipped(Range, EndifLoc);
624
2.02M
  }
625
626
  /// Hook called whenever an \#if is seen.
627
  void If(SourceLocation Loc, SourceRange ConditionRange,
628
2.06M
          ConditionValueKind ConditionValue) override {
629
2.06M
    First->If(Loc, ConditionRange, ConditionValue);
630
2.06M
    Second->If(Loc, ConditionRange, ConditionValue);
631
2.06M
  }
632
633
  /// Hook called whenever an \#elif is seen.
634
  void Elif(SourceLocation Loc, SourceRange ConditionRange,
635
164k
            ConditionValueKind ConditionValue, SourceLocation IfLoc) override {
636
164k
    First->Elif(Loc, ConditionRange, ConditionValue, IfLoc);
637
164k
    Second->Elif(Loc, ConditionRange, ConditionValue, IfLoc);
638
164k
  }
639
640
  /// Hook called whenever an \#ifdef is seen.
641
  void Ifdef(SourceLocation Loc, const Token &MacroNameTok,
642
595k
             const MacroDefinition &MD) override {
643
595k
    First->Ifdef(Loc, MacroNameTok, MD);
644
595k
    Second->Ifdef(Loc, MacroNameTok, MD);
645
595k
  }
646
647
  /// Hook called whenever an \#elifdef is taken.
648
  void Elifdef(SourceLocation Loc, const Token &MacroNameTok,
649
12
               const MacroDefinition &MD) override {
650
12
    First->Elifdef(Loc, MacroNameTok, MD);
651
12
    Second->Elifdef(Loc, MacroNameTok, MD);
652
12
  }
653
  /// Hook called whenever an \#elifdef is skipped.
654
  void Elifdef(SourceLocation Loc, SourceRange ConditionRange,
655
12
               SourceLocation IfLoc) override {
656
12
    First->Elifdef(Loc, ConditionRange, IfLoc);
657
12
    Second->Elifdef(Loc, ConditionRange, IfLoc);
658
12
  }
659
660
  /// Hook called whenever an \#ifndef is seen.
661
  void Ifndef(SourceLocation Loc, const Token &MacroNameTok,
662
4.76M
              const MacroDefinition &MD) override {
663
4.76M
    First->Ifndef(Loc, MacroNameTok, MD);
664
4.76M
    Second->Ifndef(Loc, MacroNameTok, MD);
665
4.76M
  }
666
667
  /// Hook called whenever an \#elifndef is taken.
668
  void Elifndef(SourceLocation Loc, const Token &MacroNameTok,
669
12
                const MacroDefinition &MD) override {
670
12
    First->Elifndef(Loc, MacroNameTok, MD);
671
12
    Second->Elifndef(Loc, MacroNameTok, MD);
672
12
  }
673
  /// Hook called whenever an \#elifndef is skipped.
674
  void Elifndef(SourceLocation Loc, SourceRange ConditionRange,
675
12
               SourceLocation IfLoc) override {
676
12
    First->Elifndef(Loc, ConditionRange, IfLoc);
677
12
    Second->Elifndef(Loc, ConditionRange, IfLoc);
678
12
  }
679
680
  /// Hook called whenever an \#else is seen.
681
1.10M
  void Else(SourceLocation Loc, SourceLocation IfLoc) override {
682
1.10M
    First->Else(Loc, IfLoc);
683
1.10M
    Second->Else(Loc, IfLoc);
684
1.10M
  }
685
686
  /// Hook called whenever an \#endif is seen.
687
7.41M
  void Endif(SourceLocation Loc, SourceLocation IfLoc) override {
688
7.41M
    First->Endif(Loc, IfLoc);
689
7.41M
    Second->Endif(Loc, IfLoc);
690
7.41M
  }
691
};
692
693
}  // end namespace clang
694
695
#endif