Coverage Report

Created: 2018-09-21 05:35

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