Coverage Report

Created: 2019-02-23 12:57

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/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
41.9k
                           FileID PrevFID = FileID()) {
50
41.9k
  }
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 FileEntry &SkippedFile,
61
                           const Token &FilenameTok,
62
509k
                           SrcMgr::CharacteristicKind FileType) {
63
509k
  }
64
65
  /// Callback invoked whenever an inclusion directive results in a
66
  /// file-not-found error.
67
  ///
68
  /// \param FileName The name of the file being included, as written in the
69
  /// source code.
70
  ///
71
  /// \param RecoveryPath If this client indicates that it can recover from
72
  /// this missing file, the client should set this as an additional header
73
  /// search patch.
74
  ///
75
  /// \returns true to indicate that the preprocessor should attempt to recover
76
  /// by adding \p RecoveryPath as a header search path.
77
  virtual bool FileNotFound(StringRef FileName,
78
115
                            SmallVectorImpl<char> &RecoveryPath) {
79
115
    return false;
80
115
  }
81
82
  /// Callback invoked whenever an inclusion directive of
83
  /// any kind (\c \#include, \c \#import, etc.) has been processed, regardless
84
  /// of whether the inclusion will actually result in an inclusion.
85
  ///
86
  /// \param HashLoc The location of the '#' that starts the inclusion
87
  /// directive.
88
  ///
89
  /// \param IncludeTok The token that indicates the kind of inclusion
90
  /// directive, e.g., 'include' or 'import'.
91
  ///
92
  /// \param FileName The name of the file being included, as written in the
93
  /// source code.
94
  ///
95
  /// \param IsAngled Whether the file name was enclosed in angle brackets;
96
  /// otherwise, it was enclosed in quotes.
97
  ///
98
  /// \param FilenameRange The character range of the quotes or angle brackets
99
  /// for the written file name.
100
  ///
101
  /// \param File The actual file that may be included by this inclusion
102
  /// directive.
103
  ///
104
  /// \param SearchPath Contains the search path which was used to find the file
105
  /// in the file system. If the file was found via an absolute include path,
106
  /// SearchPath will be empty. For framework includes, the SearchPath and
107
  /// RelativePath will be split up. For example, if an include of "Some/Some.h"
108
  /// is found via the framework path
109
  /// "path/to/Frameworks/Some.framework/Headers/Some.h", SearchPath will be
110
  /// "path/to/Frameworks/Some.framework/Headers" and RelativePath will be
111
  /// "Some.h".
112
  ///
113
  /// \param RelativePath The path relative to SearchPath, at which the include
114
  /// file was found. This is equal to FileName except for framework includes.
115
  ///
116
  /// \param Imported The module, whenever an inclusion directive was
117
  /// automatically turned into a module import or null otherwise.
118
  ///
119
  /// \param FileType The characteristic kind, indicates whether a file or
120
  /// directory holds normal user code, system code, or system code which is
121
  /// implicitly 'extern "C"' in C++ mode.
122
  ///
123
  virtual void InclusionDirective(SourceLocation HashLoc,
124
                                  const Token &IncludeTok,
125
                                  StringRef FileName,
126
                                  bool IsAngled,
127
                                  CharSourceRange FilenameRange,
128
                                  const FileEntry *File,
129
                                  StringRef SearchPath,
130
                                  StringRef RelativePath,
131
                                  const Module *Imported,
132
976k
                                  SrcMgr::CharacteristicKind FileType) {
133
976k
  }
134
135
  /// Callback invoked whenever there was an explicit module-import
136
  /// syntax.
137
  ///
138
  /// \param ImportLoc The location of import directive token.
139
  ///
140
  /// \param Path The identifiers (and their locations) of the module
141
  /// "path", e.g., "std.vector" would be split into "std" and "vector".
142
  ///
143
  /// \param Imported The imported module; can be null if importing failed.
144
  ///
145
  virtual void moduleImport(SourceLocation ImportLoc,
146
                            ModuleIdPath Path,
147
1.07k
                            const Module *Imported) {
148
1.07k
  }
149
150
  /// Callback invoked when the end of the main file is reached.
151
  ///
152
  /// No subsequent callbacks will be made.
153
47.1k
  virtual void EndOfMainFile() {
154
47.1k
  }
155
156
  /// Callback invoked when a \#ident or \#sccs directive is read.
157
  /// \param Loc The location of the directive.
158
  /// \param str The text of the directive.
159
  ///
160
1
  virtual void Ident(SourceLocation Loc, StringRef str) {
161
1
  }
162
163
  /// Callback invoked when start reading any pragma directive.
164
  virtual void PragmaDirective(SourceLocation Loc,
165
394k
                               PragmaIntroducerKind Introducer) {
166
394k
  }
167
168
  /// Callback invoked when a \#pragma comment directive is read.
169
  virtual void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind,
170
51
                             StringRef Str) {
171
51
  }
172
173
  /// Callback invoked when a \#pragma detect_mismatch directive is
174
  /// read.
175
  virtual void PragmaDetectMismatch(SourceLocation Loc, StringRef Name,
176
10
                                    StringRef Value) {
177
10
  }
178
179
  /// Callback invoked when a \#pragma clang __debug directive is read.
180
  /// \param Loc The location of the debug directive.
181
  /// \param DebugType The identifier following __debug.
182
93
  virtual void PragmaDebug(SourceLocation Loc, StringRef DebugType) {
183
93
  }
184
185
  /// Determines the kind of \#pragma invoking a call to PragmaMessage.
186
  enum PragmaMessageKind {
187
    /// \#pragma message has been invoked.
188
    PMK_Message,
189
190
    /// \#pragma GCC warning has been invoked.
191
    PMK_Warning,
192
193
    /// \#pragma GCC error has been invoked.
194
    PMK_Error
195
  };
196
197
  /// Callback invoked when a \#pragma message directive is read.
198
  /// \param Loc The location of the message directive.
199
  /// \param Namespace The namespace of the message directive.
200
  /// \param Kind The type of the message directive.
201
  /// \param Str The text of the message directive.
202
  virtual void PragmaMessage(SourceLocation Loc, StringRef Namespace,
203
15
                             PragmaMessageKind Kind, StringRef Str) {
204
15
  }
205
206
  /// Callback invoked when a \#pragma gcc diagnostic push directive
207
  /// is read.
208
  virtual void PragmaDiagnosticPush(SourceLocation Loc,
209
385
                                    StringRef Namespace) {
210
385
  }
211
212
  /// Callback invoked when a \#pragma gcc diagnostic pop directive
213
  /// is read.
214
  virtual void PragmaDiagnosticPop(SourceLocation Loc,
215
383
                                   StringRef Namespace) {
216
383
  }
217
218
  /// Callback invoked when a \#pragma gcc diagnostic directive is read.
219
  virtual void PragmaDiagnostic(SourceLocation Loc, StringRef Namespace,
220
465
                                diag::Severity mapping, StringRef Str) {}
221
222
  /// Called when an OpenCL extension is either disabled or
223
  /// enabled with a pragma.
224
  virtual void PragmaOpenCLExtension(SourceLocation NameLoc,
225
                                     const IdentifierInfo *Name,
226
2.13k
                                     SourceLocation StateLoc, unsigned State) {
227
2.13k
  }
228
229
  /// Callback invoked when a \#pragma warning directive is read.
230
  virtual void PragmaWarning(SourceLocation Loc, StringRef WarningSpec,
231
12
                             ArrayRef<int> Ids) {
232
12
  }
233
234
  /// Callback invoked when a \#pragma warning(push) directive is read.
235
7
  virtual void PragmaWarningPush(SourceLocation Loc, int Level) {
236
7
  }
237
238
  /// Callback invoked when a \#pragma warning(pop) directive is read.
239
4
  virtual void PragmaWarningPop(SourceLocation Loc) {
240
4
  }
241
242
  /// Callback invoked when a \#pragma clang assume_nonnull begin directive
243
  /// is read.
244
8.84k
  virtual void PragmaAssumeNonNullBegin(SourceLocation Loc) {}
245
246
  /// Callback invoked when a \#pragma clang assume_nonnull end directive
247
  /// is read.
248
8.83k
  virtual void PragmaAssumeNonNullEnd(SourceLocation Loc) {}
249
250
  /// Called by Preprocessor::HandleMacroExpandedIdentifier when a
251
  /// macro invocation is found.
252
  virtual void MacroExpands(const Token &MacroNameTok,
253
                            const MacroDefinition &MD, SourceRange Range,
254
34.1M
                            const MacroArgs *Args) {}
255
256
  /// Hook called whenever a macro definition is seen.
257
  virtual void MacroDefined(const Token &MacroNameTok,
258
34.8M
                            const MacroDirective *MD) {
259
34.8M
  }
260
261
  /// Hook called whenever a macro \#undef is seen.
262
  /// \param MacroNameTok The active Token
263
  /// \param MD A MacroDefinition for the named macro.
264
  /// \param Undef New MacroDirective if the macro was defined, null otherwise.
265
  ///
266
  /// MD is released immediately following this callback.
267
  virtual void MacroUndefined(const Token &MacroNameTok,
268
                              const MacroDefinition &MD,
269
528k
                              const MacroDirective *Undef) {
270
528k
  }
271
272
  /// Hook called whenever the 'defined' operator is seen.
273
  /// \param MD The MacroDirective if the name was a macro, null otherwise.
274
  virtual void Defined(const Token &MacroNameTok, const MacroDefinition &MD,
275
3.56M
                       SourceRange Range) {
276
3.56M
  }
277
278
  /// Hook called when a '__has_include' or '__has_include_next' directive is
279
  /// read.
280
  virtual void HasInclude(SourceLocation Loc, StringRef FileName, bool IsAngled,
281
                          const FileEntry *File,
282
22.7k
                          SrcMgr::CharacteristicKind FileType) {}
283
284
  /// Hook called when a source range is skipped.
285
  /// \param Range The SourceRange that was skipped. The range begins at the
286
  /// \#if/\#else directive and ends after the \#endif/\#else directive.
287
  /// \param EndifLoc The end location of the 'endif' token, which may precede
288
  /// the range skipped by the directive (e.g excluding comments after an
289
  /// 'endif').
290
7.85M
  virtual void SourceRangeSkipped(SourceRange Range, SourceLocation EndifLoc) {
291
7.85M
  }
292
293
  enum ConditionValueKind {
294
    CVK_NotEvaluated, CVK_False, CVK_True
295
  };
296
297
  /// Hook called whenever an \#if is seen.
298
  /// \param Loc the source location of the directive.
299
  /// \param ConditionRange The SourceRange of the expression being tested.
300
  /// \param ConditionValue The evaluated value of the condition.
301
  ///
302
  // FIXME: better to pass in a list (or tree!) of Tokens.
303
  virtual void If(SourceLocation Loc, SourceRange ConditionRange,
304
7.42M
                  ConditionValueKind ConditionValue) {
305
7.42M
  }
306
307
  /// Hook called whenever an \#elif is seen.
308
  /// \param Loc the source location of the directive.
309
  /// \param ConditionRange The SourceRange of the expression being tested.
310
  /// \param ConditionValue The evaluated value of the condition.
311
  /// \param IfLoc the source location of the \#if/\#ifdef/\#ifndef directive.
312
  // FIXME: better to pass in a list (or tree!) of Tokens.
313
  virtual void Elif(SourceLocation Loc, SourceRange ConditionRange,
314
351k
                    ConditionValueKind ConditionValue, SourceLocation IfLoc) {
315
351k
  }
316
317
  /// Hook called whenever an \#ifdef is seen.
318
  /// \param Loc the source location of the directive.
319
  /// \param MacroNameTok Information on the token being tested.
320
  /// \param MD The MacroDefinition if the name was a macro, null otherwise.
321
  virtual void Ifdef(SourceLocation Loc, const Token &MacroNameTok,
322
1.29M
                     const MacroDefinition &MD) {
323
1.29M
  }
324
325
  /// Hook called whenever an \#ifndef is seen.
326
  /// \param Loc the source location of the directive.
327
  /// \param MacroNameTok Information on the token being tested.
328
  /// \param MD The MacroDefiniton if the name was a macro, null otherwise.
329
  virtual void Ifndef(SourceLocation Loc, const Token &MacroNameTok,
330
1.94M
                      const MacroDefinition &MD) {
331
1.94M
  }
332
333
  /// Hook called whenever an \#else is seen.
334
  /// \param Loc the source location of the directive.
335
  /// \param IfLoc the source location of the \#if/\#ifdef/\#ifndef directive.
336
6.22M
  virtual void Else(SourceLocation Loc, SourceLocation IfLoc) {
337
6.22M
  }
338
339
  /// Hook called whenever an \#endif is seen.
340
  /// \param Loc the source location of the directive.
341
  /// \param IfLoc the source location of the \#if/\#ifdef/\#ifndef directive.
342
10.6M
  virtual void Endif(SourceLocation Loc, SourceLocation IfLoc) {
343
10.6M
  }
344
};
345
346
/// Simple wrapper class for chaining callbacks.
347
class PPChainedCallbacks : public PPCallbacks {
348
  virtual void anchor();
349
  std::unique_ptr<PPCallbacks> First, Second;
350
351
public:
352
  PPChainedCallbacks(std::unique_ptr<PPCallbacks> _First,
353
                     std::unique_ptr<PPCallbacks> _Second)
354
15.4k
    : First(std::move(_First)), Second(std::move(_Second)) {}
355
356
  void FileChanged(SourceLocation Loc, FileChangeReason Reason,
357
                   SrcMgr::CharacteristicKind FileType,
358
1.01M
                   FileID PrevFID) override {
359
1.01M
    First->FileChanged(Loc, Reason, FileType, PrevFID);
360
1.01M
    Second->FileChanged(Loc, Reason, FileType, PrevFID);
361
1.01M
  }
362
363
  void FileSkipped(const FileEntry &SkippedFile,
364
                   const Token &FilenameTok,
365
506k
                   SrcMgr::CharacteristicKind FileType) override {
366
506k
    First->FileSkipped(SkippedFile, FilenameTok, FileType);
367
506k
    Second->FileSkipped(SkippedFile, FilenameTok, FileType);
368
506k
  }
369
370
  bool FileNotFound(StringRef FileName,
371
40
                    SmallVectorImpl<char> &RecoveryPath) override {
372
40
    return First->FileNotFound(FileName, RecoveryPath) ||
373
40
           Second->FileNotFound(FileName, RecoveryPath);
374
40
  }
375
376
  void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
377
                          StringRef FileName, bool IsAngled,
378
                          CharSourceRange FilenameRange, const FileEntry *File,
379
                          StringRef SearchPath, StringRef RelativePath,
380
                          const Module *Imported,
381
954k
                          SrcMgr::CharacteristicKind FileType) override {
382
954k
    First->InclusionDirective(HashLoc, IncludeTok, FileName, IsAngled,
383
954k
                              FilenameRange, File, SearchPath, RelativePath,
384
954k
                              Imported, FileType);
385
954k
    Second->InclusionDirective(HashLoc, IncludeTok, FileName, IsAngled,
386
954k
                               FilenameRange, File, SearchPath, RelativePath,
387
954k
                               Imported, FileType);
388
954k
  }
389
390
  void moduleImport(SourceLocation ImportLoc, ModuleIdPath Path,
391
103
                    const Module *Imported) override {
392
103
    First->moduleImport(ImportLoc, Path, Imported);
393
103
    Second->moduleImport(ImportLoc, Path, Imported);
394
103
  }
395
396
15.3k
  void EndOfMainFile() override {
397
15.3k
    First->EndOfMainFile();
398
15.3k
    Second->EndOfMainFile();
399
15.3k
  }
400
401
0
  void Ident(SourceLocation Loc, StringRef str) override {
402
0
    First->Ident(Loc, str);
403
0
    Second->Ident(Loc, str);
404
0
  }
405
406
  void PragmaDirective(SourceLocation Loc,
407
135k
                       PragmaIntroducerKind Introducer) override {
408
135k
    First->PragmaDirective(Loc, Introducer);
409
135k
    Second->PragmaDirective(Loc, Introducer);
410
135k
  }
411
412
  void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind,
413
0
                     StringRef Str) override {
414
0
    First->PragmaComment(Loc, Kind, Str);
415
0
    Second->PragmaComment(Loc, Kind, Str);
416
0
  }
417
418
  void PragmaDetectMismatch(SourceLocation Loc, StringRef Name,
419
0
                            StringRef Value) override {
420
0
    First->PragmaDetectMismatch(Loc, Name, Value);
421
0
    Second->PragmaDetectMismatch(Loc, Name, Value);
422
0
  }
423
424
12
  void PragmaDebug(SourceLocation Loc, StringRef DebugType) override {
425
12
    First->PragmaDebug(Loc, DebugType);
426
12
    Second->PragmaDebug(Loc, DebugType);
427
12
  }
428
429
  void PragmaMessage(SourceLocation Loc, StringRef Namespace,
430
0
                     PragmaMessageKind Kind, StringRef Str) override {
431
0
    First->PragmaMessage(Loc, Namespace, Kind, Str);
432
0
    Second->PragmaMessage(Loc, Namespace, Kind, Str);
433
0
  }
434
435
155
  void PragmaDiagnosticPush(SourceLocation Loc, StringRef Namespace) override {
436
155
    First->PragmaDiagnosticPush(Loc, Namespace);
437
155
    Second->PragmaDiagnosticPush(Loc, Namespace);
438
155
  }
439
440
155
  void PragmaDiagnosticPop(SourceLocation Loc, StringRef Namespace) override {
441
155
    First->PragmaDiagnosticPop(Loc, Namespace);
442
155
    Second->PragmaDiagnosticPop(Loc, Namespace);
443
155
  }
444
445
  void PragmaDiagnostic(SourceLocation Loc, StringRef Namespace,
446
166
                        diag::Severity mapping, StringRef Str) override {
447
166
    First->PragmaDiagnostic(Loc, Namespace, mapping, Str);
448
166
    Second->PragmaDiagnostic(Loc, Namespace, mapping, Str);
449
166
  }
450
451
  void HasInclude(SourceLocation Loc, StringRef FileName, bool IsAngled,
452
                  const FileEntry *File,
453
22.3k
                  SrcMgr::CharacteristicKind FileType) override {
454
22.3k
    First->HasInclude(Loc, FileName, IsAngled, File, FileType);
455
22.3k
    Second->HasInclude(Loc, FileName, IsAngled, File, FileType);
456
22.3k
  }
457
458
  void PragmaOpenCLExtension(SourceLocation NameLoc, const IdentifierInfo *Name,
459
10
                             SourceLocation StateLoc, unsigned State) override {
460
10
    First->PragmaOpenCLExtension(NameLoc, Name, StateLoc, State);
461
10
    Second->PragmaOpenCLExtension(NameLoc, Name, StateLoc, State);
462
10
  }
463
464
  void PragmaWarning(SourceLocation Loc, StringRef WarningSpec,
465
0
                     ArrayRef<int> Ids) override {
466
0
    First->PragmaWarning(Loc, WarningSpec, Ids);
467
0
    Second->PragmaWarning(Loc, WarningSpec, Ids);
468
0
  }
469
470
0
  void PragmaWarningPush(SourceLocation Loc, int Level) override {
471
0
    First->PragmaWarningPush(Loc, Level);
472
0
    Second->PragmaWarningPush(Loc, Level);
473
0
  }
474
475
0
  void PragmaWarningPop(SourceLocation Loc) override {
476
0
    First->PragmaWarningPop(Loc);
477
0
    Second->PragmaWarningPop(Loc);
478
0
  }
479
480
4.42k
  void PragmaAssumeNonNullBegin(SourceLocation Loc) override {
481
4.42k
    First->PragmaAssumeNonNullBegin(Loc);
482
4.42k
    Second->PragmaAssumeNonNullBegin(Loc);
483
4.42k
  }
484
485
4.42k
  void PragmaAssumeNonNullEnd(SourceLocation Loc) override {
486
4.42k
    First->PragmaAssumeNonNullEnd(Loc);
487
4.42k
    Second->PragmaAssumeNonNullEnd(Loc);
488
4.42k
  }
489
490
  void MacroExpands(const Token &MacroNameTok, const MacroDefinition &MD,
491
15.9M
                    SourceRange Range, const MacroArgs *Args) override {
492
15.9M
    First->MacroExpands(MacroNameTok, MD, Range, Args);
493
15.9M
    Second->MacroExpands(MacroNameTok, MD, Range, Args);
494
15.9M
  }
495
496
  void MacroDefined(const Token &MacroNameTok,
497
14.3M
                    const MacroDirective *MD) override {
498
14.3M
    First->MacroDefined(MacroNameTok, MD);
499
14.3M
    Second->MacroDefined(MacroNameTok, MD);
500
14.3M
  }
501
502
  void MacroUndefined(const Token &MacroNameTok,
503
                      const MacroDefinition &MD,
504
254k
                      const MacroDirective *Undef) override {
505
254k
    First->MacroUndefined(MacroNameTok, MD, Undef);
506
254k
    Second->MacroUndefined(MacroNameTok, MD, Undef);
507
254k
  }
508
509
  void Defined(const Token &MacroNameTok, const MacroDefinition &MD,
510
1.74M
               SourceRange Range) override {
511
1.74M
    First->Defined(MacroNameTok, MD, Range);
512
1.74M
    Second->Defined(MacroNameTok, MD, Range);
513
1.74M
  }
514
515
3.71M
  void SourceRangeSkipped(SourceRange Range, SourceLocation EndifLoc) override {
516
3.71M
    First->SourceRangeSkipped(Range, EndifLoc);
517
3.71M
    Second->SourceRangeSkipped(Range, EndifLoc);
518
3.71M
  }
519
520
  /// Hook called whenever an \#if is seen.
521
  void If(SourceLocation Loc, SourceRange ConditionRange,
522
3.67M
          ConditionValueKind ConditionValue) override {
523
3.67M
    First->If(Loc, ConditionRange, ConditionValue);
524
3.67M
    Second->If(Loc, ConditionRange, ConditionValue);
525
3.67M
  }
526
527
  /// Hook called whenever an \#elif is seen.
528
  void Elif(SourceLocation Loc, SourceRange ConditionRange,
529
173k
            ConditionValueKind ConditionValue, SourceLocation IfLoc) override {
530
173k
    First->Elif(Loc, ConditionRange, ConditionValue, IfLoc);
531
173k
    Second->Elif(Loc, ConditionRange, ConditionValue, IfLoc);
532
173k
  }
533
534
  /// Hook called whenever an \#ifdef is seen.
535
  void Ifdef(SourceLocation Loc, const Token &MacroNameTok,
536
452k
             const MacroDefinition &MD) override {
537
452k
    First->Ifdef(Loc, MacroNameTok, MD);
538
452k
    Second->Ifdef(Loc, MacroNameTok, MD);
539
452k
  }
540
541
  /// Hook called whenever an \#ifndef is seen.
542
  void Ifndef(SourceLocation Loc, const Token &MacroNameTok,
543
951k
              const MacroDefinition &MD) override {
544
951k
    First->Ifndef(Loc, MacroNameTok, MD);
545
951k
    Second->Ifndef(Loc, MacroNameTok, MD);
546
951k
  }
547
548
  /// Hook called whenever an \#else is seen.
549
2.92M
  void Else(SourceLocation Loc, SourceLocation IfLoc) override {
550
2.92M
    First->Else(Loc, IfLoc);
551
2.92M
    Second->Else(Loc, IfLoc);
552
2.92M
  }
553
554
  /// Hook called whenever an \#endif is seen.
555
5.07M
  void Endif(SourceLocation Loc, SourceLocation IfLoc) override {
556
5.07M
    First->Endif(Loc, IfLoc);
557
5.07M
    Second->Endif(Loc, IfLoc);
558
5.07M
  }
559
};
560
561
}  // end namespace clang
562
563
#endif