Coverage Report

Created: 2022-01-18 06:27

/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.
47
  virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason,
48
                           SrcMgr::CharacteristicKind FileType,
49
207k
                           FileID PrevFID = FileID()) {
50
207k
  }
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.
60
  virtual void FileSkipped(const FileEntryRef &SkippedFile,
61
                           const Token &FilenameTok,
62
1.05M
                           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.
76
  virtual bool FileNotFound(StringRef FileName,
77
167
                            SmallVectorImpl<char> &RecoveryPath) {
78
167
    return false;
79
167
  }
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
  ///
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
1.67M
                                  SrcMgr::CharacteristicKind FileType) {
132
1.67M
  }
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
  ///
142
  virtual void EnteredSubmodule(Module *M, SourceLocation ImportLoc,
143
80.6k
                                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
  ///
153
  virtual void LeftSubmodule(Module *M, SourceLocation ImportLoc,
154
80.6k
                             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
  ///
166
  virtual void moduleImport(SourceLocation ImportLoc,
167
                            ModuleIdPath Path,
168
2.61k
                            const Module *Imported) {
169
2.61k
  }
170
171
  /// Callback invoked when the end of the main file is reached.
172
  ///
173
  /// No subsequent callbacks will be made.
174
100k
  virtual void EndOfMainFile() {
175
100k
  }
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
  ///
181
1
  virtual void Ident(SourceLocation Loc, StringRef str) {
182
1
  }
183
184
  /// Callback invoked when start reading any pragma directive.
185
  virtual void PragmaDirective(SourceLocation Loc,
186
2.01M
                               PragmaIntroducerKind Introducer) {
187
2.01M
  }
188
189
  /// Callback invoked when a \#pragma comment directive is read.
190
  virtual void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind,
191
64
                             StringRef Str) {
192
64
  }
193
194
  /// Callback invoked when a \#pragma mark comment is read.
195
73.0k
  virtual void PragmaMark(SourceLocation Loc, StringRef Trivia) {
196
73.0k
  }
197
198
  /// Callback invoked when a \#pragma detect_mismatch directive is
199
  /// read.
200
  virtual void PragmaDetectMismatch(SourceLocation Loc, StringRef Name,
201
18
                                    StringRef Value) {
202
18
  }
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.
207
179
  virtual void PragmaDebug(SourceLocation Loc, StringRef DebugType) {
208
179
  }
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.
227
  virtual void PragmaMessage(SourceLocation Loc, StringRef Namespace,
228
44
                             PragmaMessageKind Kind, StringRef Str) {
229
44
  }
230
231
  /// Callback invoked when a \#pragma gcc diagnostic push directive
232
  /// is read.
233
  virtual void PragmaDiagnosticPush(SourceLocation Loc,
234
59.4k
                                    StringRef Namespace) {
235
59.4k
  }
236
237
  /// Callback invoked when a \#pragma gcc diagnostic pop directive
238
  /// is read.
239
  virtual void PragmaDiagnosticPop(SourceLocation Loc,
240
59.4k
                                   StringRef Namespace) {
241
59.4k
  }
242
243
  /// Callback invoked when a \#pragma gcc diagnostic directive is read.
244
  virtual void PragmaDiagnostic(SourceLocation Loc, StringRef Namespace,
245
110k
                                diag::Severity mapping, StringRef Str) {}
246
247
  /// Called when an OpenCL extension is either disabled or
248
  /// enabled with a pragma.
249
  virtual void PragmaOpenCLExtension(SourceLocation NameLoc,
250
                                     const IdentifierInfo *Name,
251
2.30k
                                     SourceLocation StateLoc, unsigned State) {
252
2.30k
  }
253
254
  /// Callback invoked when a \#pragma warning directive is read.
255
  enum PragmaWarningSpecifier {
256
    PWS_Default,
257
    PWS_Disable,
258
    PWS_Error,
259
    PWS_Once,
260
    PWS_Suppress,
261
    PWS_Level1,
262
    PWS_Level2,
263
    PWS_Level3,
264
    PWS_Level4,
265
  };
266
  virtual void PragmaWarning(SourceLocation Loc,
267
                             PragmaWarningSpecifier WarningSpec,
268
31
                             ArrayRef<int> Ids) {}
269
270
  /// Callback invoked when a \#pragma warning(push) directive is read.
271
20
  virtual void PragmaWarningPush(SourceLocation Loc, int Level) {
272
20
  }
273
274
  /// Callback invoked when a \#pragma warning(pop) directive is read.
275
14
  virtual void PragmaWarningPop(SourceLocation Loc) {
276
14
  }
277
278
  /// Callback invoked when a \#pragma execution_character_set(push) directive
279
  /// is read.
280
8
  virtual void PragmaExecCharsetPush(SourceLocation Loc, StringRef Str) {}
281
282
  /// Callback invoked when a \#pragma execution_character_set(pop) directive
283
  /// is read.
284
6
  virtual void PragmaExecCharsetPop(SourceLocation Loc) {}
285
286
  /// Callback invoked when a \#pragma clang assume_nonnull begin directive
287
  /// is read.
288
140k
  virtual void PragmaAssumeNonNullBegin(SourceLocation Loc) {}
289
290
  /// Callback invoked when a \#pragma clang assume_nonnull end directive
291
  /// is read.
292
140k
  virtual void PragmaAssumeNonNullEnd(SourceLocation Loc) {}
293
294
  /// Called by Preprocessor::HandleMacroExpandedIdentifier when a
295
  /// macro invocation is found.
296
  virtual void MacroExpands(const Token &MacroNameTok,
297
                            const MacroDefinition &MD, SourceRange Range,
298
97.0M
                            const MacroArgs *Args) {}
299
300
  /// Hook called whenever a macro definition is seen.
301
  virtual void MacroDefined(const Token &MacroNameTok,
302
62.3M
                            const MacroDirective *MD) {
303
62.3M
  }
304
305
  /// Hook called whenever a macro \#undef is seen.
306
  /// \param MacroNameTok The active Token
307
  /// \param MD A MacroDefinition for the named macro.
308
  /// \param Undef New MacroDirective if the macro was defined, null otherwise.
309
  ///
310
  /// MD is released immediately following this callback.
311
  virtual void MacroUndefined(const Token &MacroNameTok,
312
                              const MacroDefinition &MD,
313
199k
                              const MacroDirective *Undef) {
314
199k
  }
315
316
  /// Hook called whenever the 'defined' operator is seen.
317
  /// \param MD The MacroDirective if the name was a macro, null otherwise.
318
  virtual void Defined(const Token &MacroNameTok, const MacroDefinition &MD,
319
2.61M
                       SourceRange Range) {
320
2.61M
  }
321
322
  /// Hook called when a '__has_include' or '__has_include_next' directive is
323
  /// read.
324
  virtual void HasInclude(SourceLocation Loc, StringRef FileName, bool IsAngled,
325
                          Optional<FileEntryRef> File,
326
                          SrcMgr::CharacteristicKind FileType);
327
328
  /// Hook called when a source range is skipped.
329
  /// \param Range The SourceRange that was skipped. The range begins at the
330
  /// \#if/\#else directive and ends after the \#endif/\#else directive.
331
  /// \param EndifLoc The end location of the 'endif' token, which may precede
332
  /// the range skipped by the directive (e.g excluding comments after an
333
  /// 'endif').
334
4.75M
  virtual void SourceRangeSkipped(SourceRange Range, SourceLocation EndifLoc) {
335
4.75M
  }
336
337
  enum ConditionValueKind {
338
    CVK_NotEvaluated, CVK_False, CVK_True
339
  };
340
341
  /// Hook called whenever an \#if is seen.
342
  /// \param Loc the source location of the directive.
343
  /// \param ConditionRange The SourceRange of the expression being tested.
344
  /// \param ConditionValue The evaluated value of the condition.
345
  ///
346
  // FIXME: better to pass in a list (or tree!) of Tokens.
347
  virtual void If(SourceLocation Loc, SourceRange ConditionRange,
348
4.12M
                  ConditionValueKind ConditionValue) {
349
4.12M
  }
350
351
  /// Hook called whenever an \#elif is seen.
352
  /// \param Loc the source location of the directive.
353
  /// \param ConditionRange The SourceRange of the expression being tested.
354
  /// \param ConditionValue The evaluated value of the condition.
355
  /// \param IfLoc the source location of the \#if/\#ifdef/\#ifndef directive.
356
  // FIXME: better to pass in a list (or tree!) of Tokens.
357
  virtual void Elif(SourceLocation Loc, SourceRange ConditionRange,
358
339k
                    ConditionValueKind ConditionValue, SourceLocation IfLoc) {
359
339k
  }
360
361
  /// Hook called whenever an \#ifdef is seen.
362
  /// \param Loc the source location of the directive.
363
  /// \param MacroNameTok Information on the token being tested.
364
  /// \param MD The MacroDefinition if the name was a macro, null otherwise.
365
  virtual void Ifdef(SourceLocation Loc, const Token &MacroNameTok,
366
1.82M
                     const MacroDefinition &MD) {
367
1.82M
  }
368
369
  /// Hook called whenever an \#elifdef branch is taken.
370
  /// \param Loc the source location of the directive.
371
  /// \param MacroNameTok Information on the token being tested.
372
  /// \param MD The MacroDefinition if the name was a macro, null otherwise.
373
  virtual void Elifdef(SourceLocation Loc, const Token &MacroNameTok,
374
16
                       const MacroDefinition &MD) {
375
16
  }
376
  /// Hook called whenever an \#elifdef is skipped.
377
  /// \param Loc the source location of the directive.
378
  /// \param ConditionRange The SourceRange of the expression being tested.
379
  /// \param IfLoc the source location of the \#if/\#ifdef/\#ifndef directive.
380
  // FIXME: better to pass in a list (or tree!) of Tokens.
381
  virtual void Elifdef(SourceLocation Loc, SourceRange ConditionRange,
382
6
                       SourceLocation IfLoc) {
383
6
  }
384
385
  /// Hook called whenever an \#ifndef is seen.
386
  /// \param Loc the source location of the directive.
387
  /// \param MacroNameTok Information on the token being tested.
388
  /// \param MD The MacroDefiniton if the name was a macro, null otherwise.
389
  virtual void Ifndef(SourceLocation Loc, const Token &MacroNameTok,
390
9.49M
                      const MacroDefinition &MD) {
391
9.49M
  }
392
393
  /// Hook called whenever an \#elifndef branch is taken.
394
  /// \param Loc the source location of the directive.
395
  /// \param MacroNameTok Information on the token being tested.
396
  /// \param MD The MacroDefinition if the name was a macro, null otherwise.
397
  virtual void Elifndef(SourceLocation Loc, const Token &MacroNameTok,
398
9
                        const MacroDefinition &MD) {
399
9
  }
400
  /// Hook called whenever an \#elifndef is skipped.
401
  /// \param Loc the source location of the directive.
402
  /// \param ConditionRange The SourceRange of the expression being tested.
403
  /// \param IfLoc the source location of the \#if/\#ifdef/\#ifndef directive.
404
  // FIXME: better to pass in a list (or tree!) of Tokens.
405
  virtual void Elifndef(SourceLocation Loc, SourceRange ConditionRange,
406
5
                        SourceLocation IfLoc) {
407
5
  }
408
409
  /// Hook called whenever an \#else is seen.
410
  /// \param Loc the source location of the directive.
411
  /// \param IfLoc the source location of the \#if/\#ifdef/\#ifndef directive.
412
2.70M
  virtual void Else(SourceLocation Loc, SourceLocation IfLoc) {
413
2.70M
  }
414
415
  /// Hook called whenever an \#endif is seen.
416
  /// \param Loc the source location of the directive.
417
  /// \param IfLoc the source location of the \#if/\#ifdef/\#ifndef directive.
418
15.4M
  virtual void Endif(SourceLocation Loc, SourceLocation IfLoc) {
419
15.4M
  }
420
};
421
422
/// Simple wrapper class for chaining callbacks.
423
class PPChainedCallbacks : public PPCallbacks {
424
  std::unique_ptr<PPCallbacks> First, Second;
425
426
public:
427
  PPChainedCallbacks(std::unique_ptr<PPCallbacks> _First,
428
                     std::unique_ptr<PPCallbacks> _Second)
429
49.8k
    : First(std::move(_First)), Second(std::move(_Second)) {}
430
431
  ~PPChainedCallbacks() override;
432
433
  void FileChanged(SourceLocation Loc, FileChangeReason Reason,
434
                   SrcMgr::CharacteristicKind FileType,
435
1.34M
                   FileID PrevFID) override {
436
1.34M
    First->FileChanged(Loc, Reason, FileType, PrevFID);
437
1.34M
    Second->FileChanged(Loc, Reason, FileType, PrevFID);
438
1.34M
  }
439
440
  void FileSkipped(const FileEntryRef &SkippedFile, const Token &FilenameTok,
441
1.04M
                   SrcMgr::CharacteristicKind FileType) override {
442
1.04M
    First->FileSkipped(SkippedFile, FilenameTok, FileType);
443
1.04M
    Second->FileSkipped(SkippedFile, FilenameTok, FileType);
444
1.04M
  }
445
446
  bool FileNotFound(StringRef FileName,
447
65
                    SmallVectorImpl<char> &RecoveryPath) override {
448
65
    return First->FileNotFound(FileName, RecoveryPath) ||
449
65
           Second->FileNotFound(FileName, RecoveryPath);
450
65
  }
451
452
  void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
453
                          StringRef FileName, bool IsAngled,
454
                          CharSourceRange FilenameRange, const FileEntry *File,
455
                          StringRef SearchPath, StringRef RelativePath,
456
                          const Module *Imported,
457
1.49M
                          SrcMgr::CharacteristicKind FileType) override {
458
1.49M
    First->InclusionDirective(HashLoc, IncludeTok, FileName, IsAngled,
459
1.49M
                              FilenameRange, File, SearchPath, RelativePath,
460
1.49M
                              Imported, FileType);
461
1.49M
    Second->InclusionDirective(HashLoc, IncludeTok, FileName, IsAngled,
462
1.49M
                               FilenameRange, File, SearchPath, RelativePath,
463
1.49M
                               Imported, FileType);
464
1.49M
  }
465
466
  void EnteredSubmodule(Module *M, SourceLocation ImportLoc,
467
297
                        bool ForPragma) override {
468
297
    First->EnteredSubmodule(M, ImportLoc, ForPragma);
469
297
    Second->EnteredSubmodule(M, ImportLoc, ForPragma);
470
297
  }
471
472
  void LeftSubmodule(Module *M, SourceLocation ImportLoc,
473
295
                     bool ForPragma) override {
474
295
    First->LeftSubmodule(M, ImportLoc, ForPragma);
475
295
    Second->LeftSubmodule(M, ImportLoc, ForPragma);
476
295
  }
477
478
  void moduleImport(SourceLocation ImportLoc, ModuleIdPath Path,
479
1.51k
                    const Module *Imported) override {
480
1.51k
    First->moduleImport(ImportLoc, Path, Imported);
481
1.51k
    Second->moduleImport(ImportLoc, Path, Imported);
482
1.51k
  }
483
484
34.4k
  void EndOfMainFile() override {
485
34.4k
    First->EndOfMainFile();
486
34.4k
    Second->EndOfMainFile();
487
34.4k
  }
488
489
0
  void Ident(SourceLocation Loc, StringRef str) override {
490
0
    First->Ident(Loc, str);
491
0
    Second->Ident(Loc, str);
492
0
  }
493
494
  void PragmaDirective(SourceLocation Loc,
495
967k
                       PragmaIntroducerKind Introducer) override {
496
967k
    First->PragmaDirective(Loc, Introducer);
497
967k
    Second->PragmaDirective(Loc, Introducer);
498
967k
  }
499
500
  void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind,
501
10
                     StringRef Str) override {
502
10
    First->PragmaComment(Loc, Kind, Str);
503
10
    Second->PragmaComment(Loc, Kind, Str);
504
10
  }
505
506
35.4k
  void PragmaMark(SourceLocation Loc, StringRef Trivia) override {
507
35.4k
    First->PragmaMark(Loc, Trivia);
508
35.4k
    Second->PragmaMark(Loc, Trivia);
509
35.4k
  }
510
511
  void PragmaDetectMismatch(SourceLocation Loc, StringRef Name,
512
2
                            StringRef Value) override {
513
2
    First->PragmaDetectMismatch(Loc, Name, Value);
514
2
    Second->PragmaDetectMismatch(Loc, Name, Value);
515
2
  }
516
517
69
  void PragmaDebug(SourceLocation Loc, StringRef DebugType) override {
518
69
    First->PragmaDebug(Loc, DebugType);
519
69
    Second->PragmaDebug(Loc, DebugType);
520
69
  }
521
522
  void PragmaMessage(SourceLocation Loc, StringRef Namespace,
523
22
                     PragmaMessageKind Kind, StringRef Str) override {
524
22
    First->PragmaMessage(Loc, Namespace, Kind, Str);
525
22
    Second->PragmaMessage(Loc, Namespace, Kind, Str);
526
22
  }
527
528
28.6k
  void PragmaDiagnosticPush(SourceLocation Loc, StringRef Namespace) override {
529
28.6k
    First->PragmaDiagnosticPush(Loc, Namespace);
530
28.6k
    Second->PragmaDiagnosticPush(Loc, Namespace);
531
28.6k
  }
532
533
28.6k
  void PragmaDiagnosticPop(SourceLocation Loc, StringRef Namespace) override {
534
28.6k
    First->PragmaDiagnosticPop(Loc, Namespace);
535
28.6k
    Second->PragmaDiagnosticPop(Loc, Namespace);
536
28.6k
  }
537
538
  void PragmaDiagnostic(SourceLocation Loc, StringRef Namespace,
539
53.3k
                        diag::Severity mapping, StringRef Str) override {
540
53.3k
    First->PragmaDiagnostic(Loc, Namespace, mapping, Str);
541
53.3k
    Second->PragmaDiagnostic(Loc, Namespace, mapping, Str);
542
53.3k
  }
543
544
  void HasInclude(SourceLocation Loc, StringRef FileName, bool IsAngled,
545
                  Optional<FileEntryRef> File,
546
                  SrcMgr::CharacteristicKind FileType) override;
547
548
  void PragmaOpenCLExtension(SourceLocation NameLoc, const IdentifierInfo *Name,
549
1.04k
                             SourceLocation StateLoc, unsigned State) override {
550
1.04k
    First->PragmaOpenCLExtension(NameLoc, Name, StateLoc, State);
551
1.04k
    Second->PragmaOpenCLExtension(NameLoc, Name, StateLoc, State);
552
1.04k
  }
553
554
  void PragmaWarning(SourceLocation Loc, PragmaWarningSpecifier WarningSpec,
555
15
                     ArrayRef<int> Ids) override {
556
15
    First->PragmaWarning(Loc, WarningSpec, Ids);
557
15
    Second->PragmaWarning(Loc, WarningSpec, Ids);
558
15
  }
559
560
10
  void PragmaWarningPush(SourceLocation Loc, int Level) override {
561
10
    First->PragmaWarningPush(Loc, Level);
562
10
    Second->PragmaWarningPush(Loc, Level);
563
10
  }
564
565
7
  void PragmaWarningPop(SourceLocation Loc) override {
566
7
    First->PragmaWarningPop(Loc);
567
7
    Second->PragmaWarningPop(Loc);
568
7
  }
569
570
4
  void PragmaExecCharsetPush(SourceLocation Loc, StringRef Str) override {
571
4
    First->PragmaExecCharsetPush(Loc, Str);
572
4
    Second->PragmaExecCharsetPush(Loc, Str);
573
4
  }
574
575
3
  void PragmaExecCharsetPop(SourceLocation Loc) override {
576
3
    First->PragmaExecCharsetPop(Loc);
577
3
    Second->PragmaExecCharsetPop(Loc);
578
3
  }
579
580
69.1k
  void PragmaAssumeNonNullBegin(SourceLocation Loc) override {
581
69.1k
    First->PragmaAssumeNonNullBegin(Loc);
582
69.1k
    Second->PragmaAssumeNonNullBegin(Loc);
583
69.1k
  }
584
585
69.1k
  void PragmaAssumeNonNullEnd(SourceLocation Loc) override {
586
69.1k
    First->PragmaAssumeNonNullEnd(Loc);
587
69.1k
    Second->PragmaAssumeNonNullEnd(Loc);
588
69.1k
  }
589
590
  void MacroExpands(const Token &MacroNameTok, const MacroDefinition &MD,
591
38.2M
                    SourceRange Range, const MacroArgs *Args) override {
592
38.2M
    First->MacroExpands(MacroNameTok, MD, Range, Args);
593
38.2M
    Second->MacroExpands(MacroNameTok, MD, Range, Args);
594
38.2M
  }
595
596
  void MacroDefined(const Token &MacroNameTok,
597
25.5M
                    const MacroDirective *MD) override {
598
25.5M
    First->MacroDefined(MacroNameTok, MD);
599
25.5M
    Second->MacroDefined(MacroNameTok, MD);
600
25.5M
  }
601
602
  void MacroUndefined(const Token &MacroNameTok,
603
                      const MacroDefinition &MD,
604
81.5k
                      const MacroDirective *Undef) override {
605
81.5k
    First->MacroUndefined(MacroNameTok, MD, Undef);
606
81.5k
    Second->MacroUndefined(MacroNameTok, MD, Undef);
607
81.5k
  }
608
609
  void Defined(const Token &MacroNameTok, const MacroDefinition &MD,
610
1.14M
               SourceRange Range) override {
611
1.14M
    First->Defined(MacroNameTok, MD, Range);
612
1.14M
    Second->Defined(MacroNameTok, MD, Range);
613
1.14M
  }
614
615
1.95M
  void SourceRangeSkipped(SourceRange Range, SourceLocation EndifLoc) override {
616
1.95M
    First->SourceRangeSkipped(Range, EndifLoc);
617
1.95M
    Second->SourceRangeSkipped(Range, EndifLoc);
618
1.95M
  }
619
620
  /// Hook called whenever an \#if is seen.
621
  void If(SourceLocation Loc, SourceRange ConditionRange,
622
1.91M
          ConditionValueKind ConditionValue) override {
623
1.91M
    First->If(Loc, ConditionRange, ConditionValue);
624
1.91M
    Second->If(Loc, ConditionRange, ConditionValue);
625
1.91M
  }
626
627
  /// Hook called whenever an \#elif is seen.
628
  void Elif(SourceLocation Loc, SourceRange ConditionRange,
629
162k
            ConditionValueKind ConditionValue, SourceLocation IfLoc) override {
630
162k
    First->Elif(Loc, ConditionRange, ConditionValue, IfLoc);
631
162k
    Second->Elif(Loc, ConditionRange, ConditionValue, IfLoc);
632
162k
  }
633
634
  /// Hook called whenever an \#ifdef is seen.
635
  void Ifdef(SourceLocation Loc, const Token &MacroNameTok,
636
590k
             const MacroDefinition &MD) override {
637
590k
    First->Ifdef(Loc, MacroNameTok, MD);
638
590k
    Second->Ifdef(Loc, MacroNameTok, MD);
639
590k
  }
640
641
  /// Hook called whenever an \#elifdef is taken.
642
  void Elifdef(SourceLocation Loc, const Token &MacroNameTok,
643
2
               const MacroDefinition &MD) override {
644
2
    First->Elifdef(Loc, MacroNameTok, MD);
645
2
    Second->Elifdef(Loc, MacroNameTok, MD);
646
2
  }
647
  /// Hook called whenever an \#elifdef is skipped.
648
  void Elifdef(SourceLocation Loc, SourceRange ConditionRange,
649
2
               SourceLocation IfLoc) override {
650
2
    First->Elifdef(Loc, ConditionRange, IfLoc);
651
2
    Second->Elifdef(Loc, ConditionRange, IfLoc);
652
2
  }
653
654
  /// Hook called whenever an \#ifndef is seen.
655
  void Ifndef(SourceLocation Loc, const Token &MacroNameTok,
656
4.65M
              const MacroDefinition &MD) override {
657
4.65M
    First->Ifndef(Loc, MacroNameTok, MD);
658
4.65M
    Second->Ifndef(Loc, MacroNameTok, MD);
659
4.65M
  }
660
661
  /// Hook called whenever an \#elifndef is taken.
662
  void Elifndef(SourceLocation Loc, const Token &MacroNameTok,
663
2
                const MacroDefinition &MD) override {
664
2
    First->Elifndef(Loc, MacroNameTok, MD);
665
2
    Second->Elifndef(Loc, MacroNameTok, MD);
666
2
  }
667
  /// Hook called whenever an \#elifndef is skipped.
668
  void Elifndef(SourceLocation Loc, SourceRange ConditionRange,
669
2
               SourceLocation IfLoc) override {
670
2
    First->Elifndef(Loc, ConditionRange, IfLoc);
671
2
    Second->Elifndef(Loc, ConditionRange, IfLoc);
672
2
  }
673
674
  /// Hook called whenever an \#else is seen.
675
1.08M
  void Else(SourceLocation Loc, SourceLocation IfLoc) override {
676
1.08M
    First->Else(Loc, IfLoc);
677
1.08M
    Second->Else(Loc, IfLoc);
678
1.08M
  }
679
680
  /// Hook called whenever an \#endif is seen.
681
7.15M
  void Endif(SourceLocation Loc, SourceLocation IfLoc) override {
682
7.15M
    First->Endif(Loc, IfLoc);
683
7.15M
    Second->Endif(Loc, IfLoc);
684
7.15M
  }
685
};
686
687
}  // end namespace clang
688
689
#endif