Warning: That file was not part of the compilation database. It may have many parsing errors.
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 | FileID PrevFID = FileID()) { |
51 | } |
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 | SrcMgr::CharacteristicKind FileType) { |
64 | } |
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 | SmallVectorImpl<char> &RecoveryPath) { |
80 | return false; |
81 | } |
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 | SrcMgr::CharacteristicKind FileType) { |
134 | } |
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 | const Module *Imported) { |
149 | } |
150 | |
151 | /// Callback invoked when the end of the main file is reached. |
152 | /// |
153 | /// No subsequent callbacks will be made. |
154 | virtual void EndOfMainFile() { |
155 | } |
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 | virtual void Ident(SourceLocation Loc, StringRef str) { |
162 | } |
163 | |
164 | /// Callback invoked when start reading any pragma directive. |
165 | virtual void PragmaDirective(SourceLocation Loc, |
166 | PragmaIntroducerKind Introducer) { |
167 | } |
168 | |
169 | /// Callback invoked when a \#pragma comment directive is read. |
170 | virtual void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind, |
171 | StringRef Str) { |
172 | } |
173 | |
174 | /// Callback invoked when a \#pragma detect_mismatch directive is |
175 | /// read. |
176 | virtual void PragmaDetectMismatch(SourceLocation Loc, StringRef Name, |
177 | StringRef Value) { |
178 | } |
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 | virtual void PragmaDebug(SourceLocation Loc, StringRef DebugType) { |
184 | } |
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 | PragmaMessageKind Kind, StringRef Str) { |
205 | } |
206 | |
207 | /// Callback invoked when a \#pragma gcc diagnostic push directive |
208 | /// is read. |
209 | virtual void PragmaDiagnosticPush(SourceLocation Loc, |
210 | StringRef Namespace) { |
211 | } |
212 | |
213 | /// Callback invoked when a \#pragma gcc diagnostic pop directive |
214 | /// is read. |
215 | virtual void PragmaDiagnosticPop(SourceLocation Loc, |
216 | StringRef Namespace) { |
217 | } |
218 | |
219 | /// Callback invoked when a \#pragma gcc diagnostic directive is read. |
220 | virtual void PragmaDiagnostic(SourceLocation Loc, StringRef Namespace, |
221 | 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 | SourceLocation StateLoc, unsigned State) { |
228 | } |
229 | |
230 | /// Callback invoked when a \#pragma warning directive is read. |
231 | virtual void PragmaWarning(SourceLocation Loc, StringRef WarningSpec, |
232 | ArrayRef<int> Ids) { |
233 | } |
234 | |
235 | /// Callback invoked when a \#pragma warning(push) directive is read. |
236 | virtual void PragmaWarningPush(SourceLocation Loc, int Level) { |
237 | } |
238 | |
239 | /// Callback invoked when a \#pragma warning(pop) directive is read. |
240 | virtual void PragmaWarningPop(SourceLocation Loc) { |
241 | } |
242 | |
243 | /// Callback invoked when a \#pragma clang assume_nonnull begin directive |
244 | /// is read. |
245 | virtual void PragmaAssumeNonNullBegin(SourceLocation Loc) {} |
246 | |
247 | /// Callback invoked when a \#pragma clang assume_nonnull end directive |
248 | /// is read. |
249 | 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 | const MacroArgs *Args) {} |
256 | |
257 | /// Hook called whenever a macro definition is seen. |
258 | virtual void MacroDefined(const Token &MacroNameTok, |
259 | const MacroDirective *MD) { |
260 | } |
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 | const MacroDirective *Undef) { |
271 | } |
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 | SourceRange Range) { |
277 | } |
278 | |
279 | /// Hook called when a source range is skipped. |
280 | /// \param Range The SourceRange that was skipped. The range begins at the |
281 | /// \#if/\#else directive and ends after the \#endif/\#else directive. |
282 | /// \param EndifLoc The end location of the 'endif' token, which may precede |
283 | /// the range skipped by the directive (e.g excluding comments after an |
284 | /// 'endif'). |
285 | virtual void SourceRangeSkipped(SourceRange Range, SourceLocation EndifLoc) { |
286 | } |
287 | |
288 | enum ConditionValueKind { |
289 | CVK_NotEvaluated, CVK_False, CVK_True |
290 | }; |
291 | |
292 | /// Hook called whenever an \#if is seen. |
293 | /// \param Loc the source location of the directive. |
294 | /// \param ConditionRange The SourceRange of the expression being tested. |
295 | /// \param ConditionValue The evaluated value of the condition. |
296 | /// |
297 | // FIXME: better to pass in a list (or tree!) of Tokens. |
298 | virtual void If(SourceLocation Loc, SourceRange ConditionRange, |
299 | ConditionValueKind ConditionValue) { |
300 | } |
301 | |
302 | /// Hook called whenever an \#elif is seen. |
303 | /// \param Loc the source location of the directive. |
304 | /// \param ConditionRange The SourceRange of the expression being tested. |
305 | /// \param ConditionValue The evaluated value of the condition. |
306 | /// \param IfLoc the source location of the \#if/\#ifdef/\#ifndef directive. |
307 | // FIXME: better to pass in a list (or tree!) of Tokens. |
308 | virtual void Elif(SourceLocation Loc, SourceRange ConditionRange, |
309 | ConditionValueKind ConditionValue, SourceLocation IfLoc) { |
310 | } |
311 | |
312 | /// Hook called whenever an \#ifdef is seen. |
313 | /// \param Loc the source location of the directive. |
314 | /// \param MacroNameTok Information on the token being tested. |
315 | /// \param MD The MacroDefinition if the name was a macro, null otherwise. |
316 | virtual void Ifdef(SourceLocation Loc, const Token &MacroNameTok, |
317 | const MacroDefinition &MD) { |
318 | } |
319 | |
320 | /// Hook called whenever an \#ifndef is seen. |
321 | /// \param Loc the source location of the directive. |
322 | /// \param MacroNameTok Information on the token being tested. |
323 | /// \param MD The MacroDefiniton if the name was a macro, null otherwise. |
324 | virtual void Ifndef(SourceLocation Loc, const Token &MacroNameTok, |
325 | const MacroDefinition &MD) { |
326 | } |
327 | |
328 | /// Hook called whenever an \#else is seen. |
329 | /// \param Loc the source location of the directive. |
330 | /// \param IfLoc the source location of the \#if/\#ifdef/\#ifndef directive. |
331 | virtual void Else(SourceLocation Loc, SourceLocation IfLoc) { |
332 | } |
333 | |
334 | /// Hook called whenever an \#endif is seen. |
335 | /// \param Loc the source location of the directive. |
336 | /// \param IfLoc the source location of the \#if/\#ifdef/\#ifndef directive. |
337 | virtual void Endif(SourceLocation Loc, SourceLocation IfLoc) { |
338 | } |
339 | }; |
340 | |
341 | /// Simple wrapper class for chaining callbacks. |
342 | class PPChainedCallbacks : public PPCallbacks { |
343 | virtual void anchor(); |
344 | std::unique_ptr<PPCallbacks> First, Second; |
345 | |
346 | public: |
347 | PPChainedCallbacks(std::unique_ptr<PPCallbacks> _First, |
348 | std::unique_ptr<PPCallbacks> _Second) |
349 | : First(std::move(_First)), Second(std::move(_Second)) {} |
350 | |
351 | void FileChanged(SourceLocation Loc, FileChangeReason Reason, |
352 | SrcMgr::CharacteristicKind FileType, |
353 | FileID PrevFID) override { |
354 | First->FileChanged(Loc, Reason, FileType, PrevFID); |
355 | Second->FileChanged(Loc, Reason, FileType, PrevFID); |
356 | } |
357 | |
358 | void FileSkipped(const FileEntry &SkippedFile, |
359 | const Token &FilenameTok, |
360 | SrcMgr::CharacteristicKind FileType) override { |
361 | First->FileSkipped(SkippedFile, FilenameTok, FileType); |
362 | Second->FileSkipped(SkippedFile, FilenameTok, FileType); |
363 | } |
364 | |
365 | bool FileNotFound(StringRef FileName, |
366 | SmallVectorImpl<char> &RecoveryPath) override { |
367 | return First->FileNotFound(FileName, RecoveryPath) || |
368 | Second->FileNotFound(FileName, RecoveryPath); |
369 | } |
370 | |
371 | void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, |
372 | StringRef FileName, bool IsAngled, |
373 | CharSourceRange FilenameRange, const FileEntry *File, |
374 | StringRef SearchPath, StringRef RelativePath, |
375 | const Module *Imported, |
376 | SrcMgr::CharacteristicKind FileType) override { |
377 | First->InclusionDirective(HashLoc, IncludeTok, FileName, IsAngled, |
378 | FilenameRange, File, SearchPath, RelativePath, |
379 | Imported, FileType); |
380 | Second->InclusionDirective(HashLoc, IncludeTok, FileName, IsAngled, |
381 | FilenameRange, File, SearchPath, RelativePath, |
382 | Imported, FileType); |
383 | } |
384 | |
385 | void moduleImport(SourceLocation ImportLoc, ModuleIdPath Path, |
386 | const Module *Imported) override { |
387 | First->moduleImport(ImportLoc, Path, Imported); |
388 | Second->moduleImport(ImportLoc, Path, Imported); |
389 | } |
390 | |
391 | void EndOfMainFile() override { |
392 | First->EndOfMainFile(); |
393 | Second->EndOfMainFile(); |
394 | } |
395 | |
396 | void Ident(SourceLocation Loc, StringRef str) override { |
397 | First->Ident(Loc, str); |
398 | Second->Ident(Loc, str); |
399 | } |
400 | |
401 | void PragmaDirective(SourceLocation Loc, |
402 | PragmaIntroducerKind Introducer) override { |
403 | First->PragmaDirective(Loc, Introducer); |
404 | Second->PragmaDirective(Loc, Introducer); |
405 | } |
406 | |
407 | void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind, |
408 | StringRef Str) override { |
409 | First->PragmaComment(Loc, Kind, Str); |
410 | Second->PragmaComment(Loc, Kind, Str); |
411 | } |
412 | |
413 | void PragmaDetectMismatch(SourceLocation Loc, StringRef Name, |
414 | StringRef Value) override { |
415 | First->PragmaDetectMismatch(Loc, Name, Value); |
416 | Second->PragmaDetectMismatch(Loc, Name, Value); |
417 | } |
418 | |
419 | void PragmaDebug(SourceLocation Loc, StringRef DebugType) override { |
420 | First->PragmaDebug(Loc, DebugType); |
421 | Second->PragmaDebug(Loc, DebugType); |
422 | } |
423 | |
424 | void PragmaMessage(SourceLocation Loc, StringRef Namespace, |
425 | PragmaMessageKind Kind, StringRef Str) override { |
426 | First->PragmaMessage(Loc, Namespace, Kind, Str); |
427 | Second->PragmaMessage(Loc, Namespace, Kind, Str); |
428 | } |
429 | |
430 | void PragmaDiagnosticPush(SourceLocation Loc, StringRef Namespace) override { |
431 | First->PragmaDiagnosticPush(Loc, Namespace); |
432 | Second->PragmaDiagnosticPush(Loc, Namespace); |
433 | } |
434 | |
435 | void PragmaDiagnosticPop(SourceLocation Loc, StringRef Namespace) override { |
436 | First->PragmaDiagnosticPop(Loc, Namespace); |
437 | Second->PragmaDiagnosticPop(Loc, Namespace); |
438 | } |
439 | |
440 | void PragmaDiagnostic(SourceLocation Loc, StringRef Namespace, |
441 | diag::Severity mapping, StringRef Str) override { |
442 | First->PragmaDiagnostic(Loc, Namespace, mapping, Str); |
443 | Second->PragmaDiagnostic(Loc, Namespace, mapping, Str); |
444 | } |
445 | |
446 | void PragmaOpenCLExtension(SourceLocation NameLoc, const IdentifierInfo *Name, |
447 | SourceLocation StateLoc, unsigned State) override { |
448 | First->PragmaOpenCLExtension(NameLoc, Name, StateLoc, State); |
449 | Second->PragmaOpenCLExtension(NameLoc, Name, StateLoc, State); |
450 | } |
451 | |
452 | void PragmaWarning(SourceLocation Loc, StringRef WarningSpec, |
453 | ArrayRef<int> Ids) override { |
454 | First->PragmaWarning(Loc, WarningSpec, Ids); |
455 | Second->PragmaWarning(Loc, WarningSpec, Ids); |
456 | } |
457 | |
458 | void PragmaWarningPush(SourceLocation Loc, int Level) override { |
459 | First->PragmaWarningPush(Loc, Level); |
460 | Second->PragmaWarningPush(Loc, Level); |
461 | } |
462 | |
463 | void PragmaWarningPop(SourceLocation Loc) override { |
464 | First->PragmaWarningPop(Loc); |
465 | Second->PragmaWarningPop(Loc); |
466 | } |
467 | |
468 | void PragmaAssumeNonNullBegin(SourceLocation Loc) override { |
469 | First->PragmaAssumeNonNullBegin(Loc); |
470 | Second->PragmaAssumeNonNullBegin(Loc); |
471 | } |
472 | |
473 | void PragmaAssumeNonNullEnd(SourceLocation Loc) override { |
474 | First->PragmaAssumeNonNullEnd(Loc); |
475 | Second->PragmaAssumeNonNullEnd(Loc); |
476 | } |
477 | |
478 | void MacroExpands(const Token &MacroNameTok, const MacroDefinition &MD, |
479 | SourceRange Range, const MacroArgs *Args) override { |
480 | First->MacroExpands(MacroNameTok, MD, Range, Args); |
481 | Second->MacroExpands(MacroNameTok, MD, Range, Args); |
482 | } |
483 | |
484 | void MacroDefined(const Token &MacroNameTok, |
485 | const MacroDirective *MD) override { |
486 | First->MacroDefined(MacroNameTok, MD); |
487 | Second->MacroDefined(MacroNameTok, MD); |
488 | } |
489 | |
490 | void MacroUndefined(const Token &MacroNameTok, |
491 | const MacroDefinition &MD, |
492 | const MacroDirective *Undef) override { |
493 | First->MacroUndefined(MacroNameTok, MD, Undef); |
494 | Second->MacroUndefined(MacroNameTok, MD, Undef); |
495 | } |
496 | |
497 | void Defined(const Token &MacroNameTok, const MacroDefinition &MD, |
498 | SourceRange Range) override { |
499 | First->Defined(MacroNameTok, MD, Range); |
500 | Second->Defined(MacroNameTok, MD, Range); |
501 | } |
502 | |
503 | void SourceRangeSkipped(SourceRange Range, SourceLocation EndifLoc) override { |
504 | First->SourceRangeSkipped(Range, EndifLoc); |
505 | Second->SourceRangeSkipped(Range, EndifLoc); |
506 | } |
507 | |
508 | /// Hook called whenever an \#if is seen. |
509 | void If(SourceLocation Loc, SourceRange ConditionRange, |
510 | ConditionValueKind ConditionValue) override { |
511 | First->If(Loc, ConditionRange, ConditionValue); |
512 | Second->If(Loc, ConditionRange, ConditionValue); |
513 | } |
514 | |
515 | /// Hook called whenever an \#elif is seen. |
516 | void Elif(SourceLocation Loc, SourceRange ConditionRange, |
517 | ConditionValueKind ConditionValue, SourceLocation IfLoc) override { |
518 | First->Elif(Loc, ConditionRange, ConditionValue, IfLoc); |
519 | Second->Elif(Loc, ConditionRange, ConditionValue, IfLoc); |
520 | } |
521 | |
522 | /// Hook called whenever an \#ifdef is seen. |
523 | void Ifdef(SourceLocation Loc, const Token &MacroNameTok, |
524 | const MacroDefinition &MD) override { |
525 | First->Ifdef(Loc, MacroNameTok, MD); |
526 | Second->Ifdef(Loc, MacroNameTok, MD); |
527 | } |
528 | |
529 | /// Hook called whenever an \#ifndef is seen. |
530 | void Ifndef(SourceLocation Loc, const Token &MacroNameTok, |
531 | const MacroDefinition &MD) override { |
532 | First->Ifndef(Loc, MacroNameTok, MD); |
533 | Second->Ifndef(Loc, MacroNameTok, MD); |
534 | } |
535 | |
536 | /// Hook called whenever an \#else is seen. |
537 | void Else(SourceLocation Loc, SourceLocation IfLoc) override { |
538 | First->Else(Loc, IfLoc); |
539 | Second->Else(Loc, IfLoc); |
540 | } |
541 | |
542 | /// Hook called whenever an \#endif is seen. |
543 | void Endif(SourceLocation Loc, SourceLocation IfLoc) override { |
544 | First->Endif(Loc, IfLoc); |
545 | Second->Endif(Loc, IfLoc); |
546 | } |
547 | }; |
548 | |
549 | } // end namespace clang |
550 | |
551 | #endif |
552 |
Warning: That file was not part of the compilation database. It may have many parsing errors.