1193326Sed//===--- PPCallbacks.h - Callbacks for Preprocessor actions -----*- C++ -*-===//
2193326Sed//
3193326Sed//                     The LLVM Compiler Infrastructure
4193326Sed//
5193326Sed// This file is distributed under the University of Illinois Open Source
6193326Sed// License. See LICENSE.TXT for details.
7193326Sed//
8193326Sed//===----------------------------------------------------------------------===//
9245431Sdim///
10245431Sdim/// \file
11245431Sdim/// \brief Defines the PPCallbacks interface.
12245431Sdim///
13193326Sed//===----------------------------------------------------------------------===//
14193326Sed
15193326Sed#ifndef LLVM_CLANG_LEX_PPCALLBACKS_H
16193326Sed#define LLVM_CLANG_LEX_PPCALLBACKS_H
17193326Sed
18252723Sdim#include "clang/Basic/DiagnosticIDs.h"
19252723Sdim#include "clang/Basic/SourceLocation.h"
20193326Sed#include "clang/Lex/DirectoryLookup.h"
21245431Sdim#include "clang/Lex/ModuleLoader.h"
22263509Sdim#include "clang/Lex/Pragma.h"
23210299Sed#include "llvm/ADT/StringRef.h"
24193326Sed#include <string>
25193326Sed
26193326Sednamespace clang {
27193326Sed  class SourceLocation;
28193326Sed  class Token;
29193326Sed  class IdentifierInfo;
30252723Sdim  class MacroDirective;
31252723Sdim  class MacroArgs;
32198092Srdivacky
33245431Sdim/// \brief This interface provides a way to observe the actions of the
34245431Sdim/// preprocessor as it does its thing.
35245431Sdim///
36245431Sdim/// Clients can define their hooks here to implement preprocessor level tools.
37193326Sedclass PPCallbacks {
38193326Sedpublic:
39193326Sed  virtual ~PPCallbacks();
40198092Srdivacky
41193326Sed  enum FileChangeReason {
42193326Sed    EnterFile, ExitFile, SystemHeaderPragma, RenameFile
43193326Sed  };
44198092Srdivacky
45245431Sdim  /// \brief Callback invoked whenever a source file is entered or exited.
46226890Sdim  ///
47245431Sdim  /// \param Loc Indicates the new location.
48245431Sdim  /// \param PrevFID the file that was exited if \p Reason is ExitFile.
49193326Sed  virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason,
50226890Sdim                           SrcMgr::CharacteristicKind FileType,
51226890Sdim                           FileID PrevFID = FileID()) {
52193326Sed  }
53198092Srdivacky
54245431Sdim  /// \brief Callback invoked whenever a source file is skipped as the result
55245431Sdim  /// of header guard optimization.
56245431Sdim  ///
57245431Sdim  /// \param ParentFile The file that \#included the skipped file.
58245431Sdim  ///
59245431Sdim  /// \param FilenameTok The token in ParentFile that indicates the
60245431Sdim  /// skipped file.
61207619Srdivacky  virtual void FileSkipped(const FileEntry &ParentFile,
62207619Srdivacky                           const Token &FilenameTok,
63207619Srdivacky                           SrcMgr::CharacteristicKind FileType) {
64207619Srdivacky  }
65206084Srdivacky
66245431Sdim  /// \brief Callback invoked whenever an inclusion directive results in a
67245431Sdim  /// file-not-found error.
68235633Sdim  ///
69235633Sdim  /// \param FileName The name of the file being included, as written in the
70235633Sdim  /// source code.
71235633Sdim  ///
72235633Sdim  /// \param RecoveryPath If this client indicates that it can recover from
73235633Sdim  /// this missing file, the client should set this as an additional header
74235633Sdim  /// search patch.
75235633Sdim  ///
76235633Sdim  /// \returns true to indicate that the preprocessor should attempt to recover
77235633Sdim  /// by adding \p RecoveryPath as a header search path.
78235633Sdim  virtual bool FileNotFound(StringRef FileName,
79235633Sdim                            SmallVectorImpl<char> &RecoveryPath) {
80235633Sdim    return false;
81235633Sdim  }
82235633Sdim
83245431Sdim  /// \brief Callback invoked whenever an inclusion directive of
84245431Sdim  /// any kind (\c \#include, \c \#import, etc.) has been processed, regardless
85218893Sdim  /// of whether the inclusion will actually result in an inclusion.
86218893Sdim  ///
87218893Sdim  /// \param HashLoc The location of the '#' that starts the inclusion
88218893Sdim  /// directive.
89218893Sdim  ///
90218893Sdim  /// \param IncludeTok The token that indicates the kind of inclusion
91218893Sdim  /// directive, e.g., 'include' or 'import'.
92218893Sdim  ///
93218893Sdim  /// \param FileName The name of the file being included, as written in the
94218893Sdim  /// source code.
95218893Sdim  ///
96218893Sdim  /// \param IsAngled Whether the file name was enclosed in angle brackets;
97218893Sdim  /// otherwise, it was enclosed in quotes.
98218893Sdim  ///
99245431Sdim  /// \param FilenameRange The character range of the quotes or angle brackets
100245431Sdim  /// for the written file name.
101245431Sdim  ///
102218893Sdim  /// \param File The actual file that may be included by this inclusion
103218893Sdim  /// directive.
104218893Sdim  ///
105221345Sdim  /// \param SearchPath Contains the search path which was used to find the file
106221345Sdim  /// in the file system. If the file was found via an absolute include path,
107221345Sdim  /// SearchPath will be empty. For framework includes, the SearchPath and
108221345Sdim  /// RelativePath will be split up. For example, if an include of "Some/Some.h"
109221345Sdim  /// is found via the framework path
110221345Sdim  /// "path/to/Frameworks/Some.framework/Headers/Some.h", SearchPath will be
111221345Sdim  /// "path/to/Frameworks/Some.framework/Headers" and RelativePath will be
112221345Sdim  /// "Some.h".
113221345Sdim  ///
114221345Sdim  /// \param RelativePath The path relative to SearchPath, at which the include
115221345Sdim  /// file was found. This is equal to FileName except for framework includes.
116245431Sdim  ///
117245431Sdim  /// \param Imported The module, whenever an inclusion directive was
118245431Sdim  /// automatically turned into a module import or null otherwise.
119245431Sdim  ///
120218893Sdim  virtual void InclusionDirective(SourceLocation HashLoc,
121218893Sdim                                  const Token &IncludeTok,
122226890Sdim                                  StringRef FileName,
123218893Sdim                                  bool IsAngled,
124245431Sdim                                  CharSourceRange FilenameRange,
125218893Sdim                                  const FileEntry *File,
126226890Sdim                                  StringRef SearchPath,
127245431Sdim                                  StringRef RelativePath,
128245431Sdim                                  const Module *Imported) {
129218893Sdim  }
130218893Sdim
131245431Sdim  /// \brief Callback invoked whenever there was an explicit module-import
132245431Sdim  /// syntax.
133245431Sdim  ///
134245431Sdim  /// \param ImportLoc The location of import directive token.
135245431Sdim  ///
136245431Sdim  /// \param Path The identifiers (and their locations) of the module
137245431Sdim  /// "path", e.g., "std.vector" would be split into "std" and "vector".
138245431Sdim  ///
139245431Sdim  /// \param Imported The imported module; can be null if importing failed.
140245431Sdim  ///
141245431Sdim  virtual void moduleImport(SourceLocation ImportLoc,
142245431Sdim                            ModuleIdPath Path,
143245431Sdim                            const Module *Imported) {
144245431Sdim  }
145245431Sdim
146245431Sdim  /// \brief Callback invoked when the end of the main file is reached.
147245431Sdim  ///
148245431Sdim  /// No subsequent callbacks will be made.
149206084Srdivacky  virtual void EndOfMainFile() {
150206084Srdivacky  }
151206084Srdivacky
152245431Sdim  /// \brief Callback invoked when a \#ident or \#sccs directive is read.
153218893Sdim  /// \param Loc The location of the directive.
154218893Sdim  /// \param str The text of the directive.
155193326Sed  ///
156193326Sed  virtual void Ident(SourceLocation Loc, const std::string &str) {
157193326Sed  }
158198092Srdivacky
159263509Sdim  /// \brief Callback invoked when start reading any pragma directive.
160263509Sdim  virtual void PragmaDirective(SourceLocation Loc,
161263509Sdim                               PragmaIntroducerKind Introducer) {
162263509Sdim  }
163263509Sdim
164245431Sdim  /// \brief Callback invoked when a \#pragma comment directive is read.
165198092Srdivacky  virtual void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind,
166193326Sed                             const std::string &Str) {
167193326Sed  }
168198092Srdivacky
169263509Sdim  /// \brief Callback invoked when a \#pragma detect_mismatch directive is
170263509Sdim  /// read.
171263509Sdim  virtual void PragmaDetectMismatch(SourceLocation Loc,
172263509Sdim                                    const std::string &Name,
173263509Sdim                                    const std::string &Value) {
174263509Sdim  }
175263509Sdim
176252723Sdim  /// \brief Callback invoked when a \#pragma clang __debug directive is read.
177252723Sdim  /// \param Loc The location of the debug directive.
178252723Sdim  /// \param DebugType The identifier following __debug.
179252723Sdim  virtual void PragmaDebug(SourceLocation Loc, StringRef DebugType) {
180252723Sdim  }
181252723Sdim
182252723Sdim  /// \brief Determines the kind of \#pragma invoking a call to PragmaMessage.
183252723Sdim  enum PragmaMessageKind {
184252723Sdim    /// \brief \#pragma message has been invoked.
185252723Sdim    PMK_Message,
186252723Sdim
187252723Sdim    /// \brief \#pragma GCC warning has been invoked.
188252723Sdim    PMK_Warning,
189252723Sdim
190252723Sdim    /// \brief \#pragma GCC error has been invoked.
191252723Sdim    PMK_Error
192252723Sdim  };
193252723Sdim
194245431Sdim  /// \brief Callback invoked when a \#pragma message directive is read.
195218893Sdim  /// \param Loc The location of the message directive.
196252723Sdim  /// \param Namespace The namespace of the message directive.
197252723Sdim  /// \param Kind The type of the message directive.
198245431Sdim  /// \param Str The text of the message directive.
199252723Sdim  virtual void PragmaMessage(SourceLocation Loc, StringRef Namespace,
200252723Sdim                             PragmaMessageKind Kind, StringRef Str) {
201210299Sed  }
202210299Sed
203245431Sdim  /// \brief Callback invoked when a \#pragma gcc dianostic push directive
204245431Sdim  /// is read.
205224145Sdim  virtual void PragmaDiagnosticPush(SourceLocation Loc,
206226890Sdim                                    StringRef Namespace) {
207224145Sdim  }
208224145Sdim
209245431Sdim  /// \brief Callback invoked when a \#pragma gcc dianostic pop directive
210245431Sdim  /// is read.
211224145Sdim  virtual void PragmaDiagnosticPop(SourceLocation Loc,
212226890Sdim                                   StringRef Namespace) {
213224145Sdim  }
214224145Sdim
215245431Sdim  /// \brief Callback invoked when a \#pragma gcc dianostic directive is read.
216226890Sdim  virtual void PragmaDiagnostic(SourceLocation Loc, StringRef Namespace,
217226890Sdim                                diag::Mapping mapping, StringRef Str) {
218224145Sdim  }
219224145Sdim
220263509Sdim  /// \brief Called when an OpenCL extension is either disabled or
221263509Sdim  /// enabled with a pragma.
222263509Sdim  virtual void PragmaOpenCLExtension(SourceLocation NameLoc,
223263509Sdim                                     const IdentifierInfo *Name,
224263509Sdim                                     SourceLocation StateLoc, unsigned State) {
225263509Sdim  }
226263509Sdim
227263509Sdim  /// \brief Callback invoked when a \#pragma warning directive is read.
228263509Sdim  virtual void PragmaWarning(SourceLocation Loc, StringRef WarningSpec,
229263509Sdim                             ArrayRef<int> Ids) {
230263509Sdim  }
231263509Sdim
232263509Sdim  /// \brief Callback invoked when a \#pragma warning(push) directive is read.
233263509Sdim  virtual void PragmaWarningPush(SourceLocation Loc, int Level) {
234263509Sdim  }
235263509Sdim
236263509Sdim  /// \brief Callback invoked when a \#pragma warning(pop) directive is read.
237263509Sdim  virtual void PragmaWarningPop(SourceLocation Loc) {
238263509Sdim  }
239263509Sdim
240245431Sdim  /// \brief Called by Preprocessor::HandleMacroExpandedIdentifier when a
241245431Sdim  /// macro invocation is found.
242252723Sdim  virtual void MacroExpands(const Token &MacroNameTok, const MacroDirective *MD,
243252723Sdim                            SourceRange Range, const MacroArgs *Args) {
244193326Sed  }
245198092Srdivacky
246245431Sdim  /// \brief Hook called whenever a macro definition is seen.
247252723Sdim  virtual void MacroDefined(const Token &MacroNameTok,
248252723Sdim                            const MacroDirective *MD) {
249193326Sed  }
250193326Sed
251245431Sdim  /// \brief Hook called whenever a macro \#undef is seen.
252245431Sdim  ///
253252723Sdim  /// MD is released immediately following this callback.
254252723Sdim  virtual void MacroUndefined(const Token &MacroNameTok,
255252723Sdim                              const MacroDirective *MD) {
256193326Sed  }
257226890Sdim
258245431Sdim  /// \brief Hook called whenever the 'defined' operator is seen.
259252723Sdim  /// \param MD The MacroDirective if the name was a macro, null otherwise.
260263509Sdim  virtual void Defined(const Token &MacroNameTok, const MacroDirective *MD,
261263509Sdim                       SourceRange Range) {
262226890Sdim  }
263226890Sdim
264245431Sdim  /// \brief Hook called when a source range is skipped.
265226890Sdim  /// \param Range The SourceRange that was skipped. The range begins at the
266245431Sdim  /// \#if/\#else directive and ends after the \#endif/\#else directive.
267226890Sdim  virtual void SourceRangeSkipped(SourceRange Range) {
268226890Sdim  }
269218893Sdim
270245431Sdim  /// \brief Hook called whenever an \#if is seen.
271235633Sdim  /// \param Loc the source location of the directive.
272235633Sdim  /// \param ConditionRange The SourceRange of the expression being tested.
273263509Sdim  /// \param ConditionValue The evaluated value of the condition.
274245431Sdim  ///
275218893Sdim  // FIXME: better to pass in a list (or tree!) of Tokens.
276263509Sdim  virtual void If(SourceLocation Loc, SourceRange ConditionRange,
277263509Sdim                  bool ConditionValue) {
278218893Sdim  }
279218893Sdim
280245431Sdim  /// \brief Hook called whenever an \#elif is seen.
281235633Sdim  /// \param Loc the source location of the directive.
282235633Sdim  /// \param ConditionRange The SourceRange of the expression being tested.
283263509Sdim  /// \param ConditionValue The evaluated value of the condition.
284245431Sdim  /// \param IfLoc the source location of the \#if/\#ifdef/\#ifndef directive.
285218893Sdim  // FIXME: better to pass in a list (or tree!) of Tokens.
286235633Sdim  virtual void Elif(SourceLocation Loc, SourceRange ConditionRange,
287263509Sdim                    bool ConditionValue, SourceLocation IfLoc) {
288218893Sdim  }
289218893Sdim
290245431Sdim  /// \brief Hook called whenever an \#ifdef is seen.
291235633Sdim  /// \param Loc the source location of the directive.
292245431Sdim  /// \param MacroNameTok Information on the token being tested.
293252723Sdim  /// \param MD The MacroDirective if the name was a macro, null otherwise.
294252723Sdim  virtual void Ifdef(SourceLocation Loc, const Token &MacroNameTok,
295252723Sdim                     const MacroDirective *MD) {
296218893Sdim  }
297218893Sdim
298245431Sdim  /// \brief Hook called whenever an \#ifndef is seen.
299235633Sdim  /// \param Loc the source location of the directive.
300245431Sdim  /// \param MacroNameTok Information on the token being tested.
301252723Sdim  /// \param MD The MacroDirective if the name was a macro, null otherwise.
302252723Sdim  virtual void Ifndef(SourceLocation Loc, const Token &MacroNameTok,
303252723Sdim                      const MacroDirective *MD) {
304218893Sdim  }
305218893Sdim
306245431Sdim  /// \brief Hook called whenever an \#else is seen.
307235633Sdim  /// \param Loc the source location of the directive.
308245431Sdim  /// \param IfLoc the source location of the \#if/\#ifdef/\#ifndef directive.
309235633Sdim  virtual void Else(SourceLocation Loc, SourceLocation IfLoc) {
310218893Sdim  }
311218893Sdim
312245431Sdim  /// \brief Hook called whenever an \#endif is seen.
313235633Sdim  /// \param Loc the source location of the directive.
314245431Sdim  /// \param IfLoc the source location of the \#if/\#ifdef/\#ifndef directive.
315235633Sdim  virtual void Endif(SourceLocation Loc, SourceLocation IfLoc) {
316218893Sdim  }
317193326Sed};
318193326Sed
319245431Sdim/// \brief Simple wrapper class for chaining callbacks.
320193326Sedclass PPChainedCallbacks : public PPCallbacks {
321235633Sdim  virtual void anchor();
322193326Sed  PPCallbacks *First, *Second;
323193326Sed
324198092Srdivackypublic:
325193326Sed  PPChainedCallbacks(PPCallbacks *_First, PPCallbacks *_Second)
326193326Sed    : First(_First), Second(_Second) {}
327193326Sed  ~PPChainedCallbacks() {
328193326Sed    delete Second;
329193326Sed    delete First;
330193326Sed  }
331193326Sed
332193326Sed  virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason,
333226890Sdim                           SrcMgr::CharacteristicKind FileType,
334226890Sdim                           FileID PrevFID) {
335226890Sdim    First->FileChanged(Loc, Reason, FileType, PrevFID);
336226890Sdim    Second->FileChanged(Loc, Reason, FileType, PrevFID);
337193326Sed  }
338198092Srdivacky
339207619Srdivacky  virtual void FileSkipped(const FileEntry &ParentFile,
340207619Srdivacky                           const Token &FilenameTok,
341207619Srdivacky                           SrcMgr::CharacteristicKind FileType) {
342207619Srdivacky    First->FileSkipped(ParentFile, FilenameTok, FileType);
343207619Srdivacky    Second->FileSkipped(ParentFile, FilenameTok, FileType);
344207619Srdivacky  }
345207619Srdivacky
346235633Sdim  virtual bool FileNotFound(StringRef FileName,
347235633Sdim                            SmallVectorImpl<char> &RecoveryPath) {
348235633Sdim    return First->FileNotFound(FileName, RecoveryPath) ||
349235633Sdim           Second->FileNotFound(FileName, RecoveryPath);
350235633Sdim  }
351235633Sdim
352218893Sdim  virtual void InclusionDirective(SourceLocation HashLoc,
353218893Sdim                                  const Token &IncludeTok,
354226890Sdim                                  StringRef FileName,
355218893Sdim                                  bool IsAngled,
356245431Sdim                                  CharSourceRange FilenameRange,
357218893Sdim                                  const FileEntry *File,
358226890Sdim                                  StringRef SearchPath,
359245431Sdim                                  StringRef RelativePath,
360245431Sdim                                  const Module *Imported) {
361245431Sdim    First->InclusionDirective(HashLoc, IncludeTok, FileName, IsAngled,
362245431Sdim                              FilenameRange, File, SearchPath, RelativePath,
363245431Sdim                              Imported);
364245431Sdim    Second->InclusionDirective(HashLoc, IncludeTok, FileName, IsAngled,
365245431Sdim                               FilenameRange, File, SearchPath, RelativePath,
366245431Sdim                               Imported);
367218893Sdim  }
368218893Sdim
369245431Sdim  virtual void moduleImport(SourceLocation ImportLoc,
370245431Sdim                            ModuleIdPath Path,
371245431Sdim                            const Module *Imported) {
372245431Sdim    First->moduleImport(ImportLoc, Path, Imported);
373245431Sdim    Second->moduleImport(ImportLoc, Path, Imported);
374245431Sdim  }
375245431Sdim
376206084Srdivacky  virtual void EndOfMainFile() {
377206084Srdivacky    First->EndOfMainFile();
378206084Srdivacky    Second->EndOfMainFile();
379206084Srdivacky  }
380206084Srdivacky
381193326Sed  virtual void Ident(SourceLocation Loc, const std::string &str) {
382193326Sed    First->Ident(Loc, str);
383193326Sed    Second->Ident(Loc, str);
384193326Sed  }
385198092Srdivacky
386198092Srdivacky  virtual void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind,
387193326Sed                             const std::string &Str) {
388193326Sed    First->PragmaComment(Loc, Kind, Str);
389193326Sed    Second->PragmaComment(Loc, Kind, Str);
390193326Sed  }
391198092Srdivacky
392263509Sdim  virtual void PragmaDetectMismatch(SourceLocation Loc,
393263509Sdim                                    const std::string &Name,
394263509Sdim                                    const std::string &Value) {
395263509Sdim    First->PragmaDetectMismatch(Loc, Name, Value);
396263509Sdim    Second->PragmaDetectMismatch(Loc, Name, Value);
397263509Sdim  }
398263509Sdim
399252723Sdim  virtual void PragmaMessage(SourceLocation Loc, StringRef Namespace,
400252723Sdim                             PragmaMessageKind Kind, StringRef Str) {
401252723Sdim    First->PragmaMessage(Loc, Namespace, Kind, Str);
402252723Sdim    Second->PragmaMessage(Loc, Namespace, Kind, Str);
403210299Sed  }
404210299Sed
405224145Sdim  virtual void PragmaDiagnosticPush(SourceLocation Loc,
406226890Sdim                                    StringRef Namespace) {
407224145Sdim    First->PragmaDiagnosticPush(Loc, Namespace);
408224145Sdim    Second->PragmaDiagnosticPush(Loc, Namespace);
409224145Sdim  }
410224145Sdim
411224145Sdim  virtual void PragmaDiagnosticPop(SourceLocation Loc,
412226890Sdim                                    StringRef Namespace) {
413224145Sdim    First->PragmaDiagnosticPop(Loc, Namespace);
414224145Sdim    Second->PragmaDiagnosticPop(Loc, Namespace);
415224145Sdim  }
416224145Sdim
417226890Sdim  virtual void PragmaDiagnostic(SourceLocation Loc, StringRef Namespace,
418226890Sdim                                diag::Mapping mapping, StringRef Str) {
419224145Sdim    First->PragmaDiagnostic(Loc, Namespace, mapping, Str);
420224145Sdim    Second->PragmaDiagnostic(Loc, Namespace, mapping, Str);
421224145Sdim  }
422224145Sdim
423263509Sdim  virtual void PragmaOpenCLExtension(SourceLocation NameLoc,
424263509Sdim                                     const IdentifierInfo *Name,
425263509Sdim                                     SourceLocation StateLoc, unsigned State) {
426263509Sdim    First->PragmaOpenCLExtension(NameLoc, Name, StateLoc, State);
427263509Sdim    Second->PragmaOpenCLExtension(NameLoc, Name, StateLoc, State);
428263509Sdim  }
429263509Sdim
430263509Sdim  virtual void PragmaWarning(SourceLocation Loc, StringRef WarningSpec,
431263509Sdim                             ArrayRef<int> Ids) {
432263509Sdim    First->PragmaWarning(Loc, WarningSpec, Ids);
433263509Sdim    Second->PragmaWarning(Loc, WarningSpec, Ids);
434263509Sdim  }
435263509Sdim
436263509Sdim  virtual void PragmaWarningPush(SourceLocation Loc, int Level) {
437263509Sdim    First->PragmaWarningPush(Loc, Level);
438263509Sdim    Second->PragmaWarningPush(Loc, Level);
439263509Sdim  }
440263509Sdim
441263509Sdim  virtual void PragmaWarningPop(SourceLocation Loc) {
442263509Sdim    First->PragmaWarningPop(Loc);
443263509Sdim    Second->PragmaWarningPop(Loc);
444263509Sdim  }
445263509Sdim
446252723Sdim  virtual void MacroExpands(const Token &MacroNameTok, const MacroDirective *MD,
447252723Sdim                            SourceRange Range, const MacroArgs *Args) {
448252723Sdim    First->MacroExpands(MacroNameTok, MD, Range, Args);
449252723Sdim    Second->MacroExpands(MacroNameTok, MD, Range, Args);
450193326Sed  }
451198092Srdivacky
452252723Sdim  virtual void MacroDefined(const Token &MacroNameTok, const MacroDirective *MD) {
453252723Sdim    First->MacroDefined(MacroNameTok, MD);
454252723Sdim    Second->MacroDefined(MacroNameTok, MD);
455193326Sed  }
456193326Sed
457252723Sdim  virtual void MacroUndefined(const Token &MacroNameTok,
458252723Sdim                              const MacroDirective *MD) {
459252723Sdim    First->MacroUndefined(MacroNameTok, MD);
460252723Sdim    Second->MacroUndefined(MacroNameTok, MD);
461193326Sed  }
462218893Sdim
463263509Sdim  virtual void Defined(const Token &MacroNameTok, const MacroDirective *MD,
464263509Sdim                       SourceRange Range) {
465263509Sdim    First->Defined(MacroNameTok, MD, Range);
466263509Sdim    Second->Defined(MacroNameTok, MD, Range);
467226890Sdim  }
468226890Sdim
469226890Sdim  virtual void SourceRangeSkipped(SourceRange Range) {
470226890Sdim    First->SourceRangeSkipped(Range);
471226890Sdim    Second->SourceRangeSkipped(Range);
472226890Sdim  }
473226890Sdim
474245431Sdim  /// \brief Hook called whenever an \#if is seen.
475263509Sdim  virtual void If(SourceLocation Loc, SourceRange ConditionRange,
476263509Sdim                  bool ConditionValue) {
477263509Sdim    First->If(Loc, ConditionRange, ConditionValue);
478263509Sdim    Second->If(Loc, ConditionRange, ConditionValue);
479218893Sdim  }
480218893Sdim
481263509Sdim  /// \brief Hook called whenever an \#elif is seen.
482235633Sdim  virtual void Elif(SourceLocation Loc, SourceRange ConditionRange,
483263509Sdim                    bool ConditionValue, SourceLocation IfLoc) {
484263509Sdim    First->Elif(Loc, ConditionRange, ConditionValue, IfLoc);
485263509Sdim    Second->Elif(Loc, ConditionRange, ConditionValue, IfLoc);
486218893Sdim  }
487218893Sdim
488245431Sdim  /// \brief Hook called whenever an \#ifdef is seen.
489252723Sdim  virtual void Ifdef(SourceLocation Loc, const Token &MacroNameTok,
490252723Sdim                     const MacroDirective *MD) {
491252723Sdim    First->Ifdef(Loc, MacroNameTok, MD);
492252723Sdim    Second->Ifdef(Loc, MacroNameTok, MD);
493218893Sdim  }
494218893Sdim
495245431Sdim  /// \brief Hook called whenever an \#ifndef is seen.
496252723Sdim  virtual void Ifndef(SourceLocation Loc, const Token &MacroNameTok,
497252723Sdim                      const MacroDirective *MD) {
498252723Sdim    First->Ifndef(Loc, MacroNameTok, MD);
499252723Sdim    Second->Ifndef(Loc, MacroNameTok, MD);
500218893Sdim  }
501218893Sdim
502245431Sdim  /// \brief Hook called whenever an \#else is seen.
503235633Sdim  virtual void Else(SourceLocation Loc, SourceLocation IfLoc) {
504235633Sdim    First->Else(Loc, IfLoc);
505235633Sdim    Second->Else(Loc, IfLoc);
506218893Sdim  }
507218893Sdim
508245431Sdim  /// \brief Hook called whenever an \#endif is seen.
509235633Sdim  virtual void Endif(SourceLocation Loc, SourceLocation IfLoc) {
510235633Sdim    First->Endif(Loc, IfLoc);
511235633Sdim    Second->Endif(Loc, IfLoc);
512218893Sdim  }
513193326Sed};
514193326Sed
515193326Sed}  // end namespace clang
516193326Sed
517193326Sed#endif
518