PPCallbacks.h revision 6b4ff04dd22e7159887ea6c1bb8b1c01fc9c70a9
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//  This file 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/Lex/DirectoryLookup.h"
18#include "clang/Basic/SourceLocation.h"
19#include "clang/Basic/DiagnosticIDs.h"
20#include "llvm/ADT/StringRef.h"
21#include <string>
22
23namespace clang {
24  class SourceLocation;
25  class Token;
26  class IdentifierInfo;
27  class MacroInfo;
28
29/// PPCallbacks - This interface provides a way to observe the actions of the
30/// preprocessor as it does its thing.  Clients can define their hooks here to
31/// implement preprocessor level tools.
32class PPCallbacks {
33public:
34  virtual ~PPCallbacks();
35
36  enum FileChangeReason {
37    EnterFile, ExitFile, SystemHeaderPragma, RenameFile
38  };
39
40  /// FileChanged - This callback is invoked whenever a source file is
41  /// entered or exited.  The SourceLocation indicates the new location, and
42  /// EnteringFile indicates whether this is because we are entering a new
43  /// #include'd file (when true) or whether we're exiting one because we ran
44  /// off the end (when false).
45  virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason,
46                           SrcMgr::CharacteristicKind FileType) {
47  }
48
49  /// FileSkipped - This callback is invoked whenever a source file is
50  /// skipped as the result of header guard optimization.  ParentFile
51  /// is the file that #includes the skipped file.  FilenameTok is the
52  /// token in ParentFile that indicates the skipped file.
53  virtual void FileSkipped(const FileEntry &ParentFile,
54                           const Token &FilenameTok,
55                           SrcMgr::CharacteristicKind FileType) {
56  }
57
58  /// \brief This callback is invoked whenever an inclusion directive of
59  /// any kind (\c #include, \c #import, etc.) has been processed, regardless
60  /// of whether the inclusion will actually result in an inclusion.
61  ///
62  /// \param HashLoc The location of the '#' that starts the inclusion
63  /// directive.
64  ///
65  /// \param IncludeTok The token that indicates the kind of inclusion
66  /// directive, e.g., 'include' or 'import'.
67  ///
68  /// \param FileName The name of the file being included, as written in the
69  /// source code.
70  ///
71  /// \param IsAngled Whether the file name was enclosed in angle brackets;
72  /// otherwise, it was enclosed in quotes.
73  ///
74  /// \param File The actual file that may be included by this inclusion
75  /// directive.
76  ///
77  /// \param EndLoc The location of the last token within the inclusion
78  /// directive.
79  ///
80  /// \param SearchPath Contains the search path which was used to find the file
81  /// in the file system. If the file was found via an absolute include path,
82  /// SearchPath will be empty. For framework includes, the SearchPath and
83  /// RelativePath will be split up. For example, if an include of "Some/Some.h"
84  /// is found via the framework path
85  /// "path/to/Frameworks/Some.framework/Headers/Some.h", SearchPath will be
86  /// "path/to/Frameworks/Some.framework/Headers" and RelativePath will be
87  /// "Some.h".
88  ///
89  /// \param RelativePath The path relative to SearchPath, at which the include
90  /// file was found. This is equal to FileName except for framework includes.
91  virtual void InclusionDirective(SourceLocation HashLoc,
92                                  const Token &IncludeTok,
93                                  StringRef FileName,
94                                  bool IsAngled,
95                                  const FileEntry *File,
96                                  SourceLocation EndLoc,
97                                  StringRef SearchPath,
98                                  StringRef RelativePath) {
99  }
100
101  /// EndOfMainFile - This callback is invoked when the end of the main file is
102  /// reach, no subsequent callbacks will be made.
103  virtual void EndOfMainFile() {
104  }
105
106  /// Ident - This callback is invoked when a #ident or #sccs directive is read.
107  /// \param Loc The location of the directive.
108  /// \param str The text of the directive.
109  ///
110  virtual void Ident(SourceLocation Loc, const std::string &str) {
111  }
112
113  /// PragmaComment - This callback is invoked when a #pragma comment directive
114  /// is read.
115  ///
116  virtual void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind,
117                             const std::string &Str) {
118  }
119
120  /// PragmaMessage - This callback is invoked when a #pragma message directive
121  /// is read.
122  /// \param Loc The location of the message directive.
123  /// \param str The text of the message directive.
124  ///
125  virtual void PragmaMessage(SourceLocation Loc, StringRef Str) {
126  }
127
128  /// PragmaDiagnosticPush - This callback is invoked when a
129  /// #pragma gcc dianostic push directive is read.
130  virtual void PragmaDiagnosticPush(SourceLocation Loc,
131                                    StringRef Namespace) {
132  }
133
134  /// PragmaDiagnosticPop - This callback is invoked when a
135  /// #pragma gcc dianostic pop directive is read.
136  virtual void PragmaDiagnosticPop(SourceLocation Loc,
137                                   StringRef Namespace) {
138  }
139
140  /// PragmaDiagnostic - This callback is invoked when a
141  /// #pragma gcc dianostic directive is read.
142  virtual void PragmaDiagnostic(SourceLocation Loc, StringRef Namespace,
143                                diag::Mapping mapping, StringRef Str) {
144  }
145
146  /// MacroExpands - This is called by
147  /// Preprocessor::HandleMacroExpandedIdentifier when a macro invocation is
148  /// found.
149  virtual void MacroExpands(const Token &MacroNameTok, const MacroInfo* MI,
150                            SourceRange Range) {
151  }
152
153  /// MacroDefined - This hook is called whenever a macro definition is seen.
154  virtual void MacroDefined(const Token &MacroNameTok, const MacroInfo *MI) {
155  }
156
157  /// MacroUndefined - This hook is called whenever a macro #undef is seen.
158  /// MI is released immediately following this callback.
159  virtual void MacroUndefined(const Token &MacroNameTok, const MacroInfo *MI) {
160  }
161
162  /// SourceRangeSkipped - This hook is called when a source range is skipped.
163  /// \param Range The SourceRange that was skipped. The range begins at the
164  /// #if/#else directive and ends after the #endif/#else directive.
165  virtual void SourceRangeSkipped(SourceRange Range) {
166  }
167
168  /// If -- This hook is called whenever an #if is seen.
169  /// \param Range The SourceRange of the expression being tested.
170  // FIXME: better to pass in a list (or tree!) of Tokens.
171  virtual void If(SourceRange Range) {
172  }
173
174  /// Elif -- This hook is called whenever an #elif is seen.
175  /// \param Range The SourceRange of the expression being tested.
176  // FIXME: better to pass in a list (or tree!) of Tokens.
177  virtual void Elif(SourceRange Range) {
178  }
179
180  /// Ifdef -- This hook is called whenever an #ifdef is seen.
181  /// \param Loc The location of the token being tested.
182  /// \param II Information on the token being tested.
183  virtual void Ifdef(const Token &MacroNameTok) {
184  }
185
186  /// Ifndef -- This hook is called whenever an #ifndef is seen.
187  /// \param Loc The location of the token being tested.
188  /// \param II Information on the token being tested.
189  virtual void Ifndef(const Token &MacroNameTok) {
190  }
191
192  /// Else -- This hook is called whenever an #else is seen.
193  virtual void Else() {
194  }
195
196  /// Endif -- This hook is called whenever an #endif is seen.
197  virtual void Endif() {
198  }
199};
200
201/// PPChainedCallbacks - Simple wrapper class for chaining callbacks.
202class PPChainedCallbacks : public PPCallbacks {
203  PPCallbacks *First, *Second;
204
205public:
206  PPChainedCallbacks(PPCallbacks *_First, PPCallbacks *_Second)
207    : First(_First), Second(_Second) {}
208  ~PPChainedCallbacks() {
209    delete Second;
210    delete First;
211  }
212
213  virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason,
214                           SrcMgr::CharacteristicKind FileType) {
215    First->FileChanged(Loc, Reason, FileType);
216    Second->FileChanged(Loc, Reason, FileType);
217  }
218
219  virtual void FileSkipped(const FileEntry &ParentFile,
220                           const Token &FilenameTok,
221                           SrcMgr::CharacteristicKind FileType) {
222    First->FileSkipped(ParentFile, FilenameTok, FileType);
223    Second->FileSkipped(ParentFile, FilenameTok, FileType);
224  }
225
226  virtual void InclusionDirective(SourceLocation HashLoc,
227                                  const Token &IncludeTok,
228                                  StringRef FileName,
229                                  bool IsAngled,
230                                  const FileEntry *File,
231                                  SourceLocation EndLoc,
232                                  StringRef SearchPath,
233                                  StringRef RelativePath) {
234    First->InclusionDirective(HashLoc, IncludeTok, FileName, IsAngled, File,
235                              EndLoc, SearchPath, RelativePath);
236    Second->InclusionDirective(HashLoc, IncludeTok, FileName, IsAngled, File,
237                               EndLoc, SearchPath, RelativePath);
238  }
239
240  virtual void EndOfMainFile() {
241    First->EndOfMainFile();
242    Second->EndOfMainFile();
243  }
244
245  virtual void Ident(SourceLocation Loc, const std::string &str) {
246    First->Ident(Loc, str);
247    Second->Ident(Loc, str);
248  }
249
250  virtual void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind,
251                             const std::string &Str) {
252    First->PragmaComment(Loc, Kind, Str);
253    Second->PragmaComment(Loc, Kind, Str);
254  }
255
256  virtual void PragmaMessage(SourceLocation Loc, StringRef Str) {
257    First->PragmaMessage(Loc, Str);
258    Second->PragmaMessage(Loc, Str);
259  }
260
261  virtual void PragmaDiagnosticPush(SourceLocation Loc,
262                                    StringRef Namespace) {
263    First->PragmaDiagnosticPush(Loc, Namespace);
264    Second->PragmaDiagnosticPush(Loc, Namespace);
265  }
266
267  virtual void PragmaDiagnosticPop(SourceLocation Loc,
268                                    StringRef Namespace) {
269    First->PragmaDiagnosticPop(Loc, Namespace);
270    Second->PragmaDiagnosticPop(Loc, Namespace);
271  }
272
273  virtual void PragmaDiagnostic(SourceLocation Loc, StringRef Namespace,
274                                diag::Mapping mapping, StringRef Str) {
275    First->PragmaDiagnostic(Loc, Namespace, mapping, Str);
276    Second->PragmaDiagnostic(Loc, Namespace, mapping, Str);
277  }
278
279  virtual void MacroExpands(const Token &MacroNameTok, const MacroInfo* MI,
280                            SourceRange Range) {
281    First->MacroExpands(MacroNameTok, MI, Range);
282    Second->MacroExpands(MacroNameTok, MI, Range);
283  }
284
285  virtual void MacroDefined(const Token &MacroNameTok, const MacroInfo *MI) {
286    First->MacroDefined(MacroNameTok, MI);
287    Second->MacroDefined(MacroNameTok, MI);
288  }
289
290  virtual void MacroUndefined(const Token &MacroNameTok, const MacroInfo *MI) {
291    First->MacroUndefined(MacroNameTok, MI);
292    Second->MacroUndefined(MacroNameTok, MI);
293  }
294
295  virtual void SourceRangeSkipped(SourceRange Range) {
296    First->SourceRangeSkipped(Range);
297    Second->SourceRangeSkipped(Range);
298  }
299
300  /// If -- This hook is called whenever an #if is seen.
301  virtual void If(SourceRange Range) {
302    First->If(Range);
303    Second->If(Range);
304  }
305
306  /// Elif -- This hook is called whenever an #if is seen.
307  virtual void Elif(SourceRange Range) {
308    First->Elif(Range);
309    Second->Elif(Range);
310  }
311
312  /// Ifdef -- This hook is called whenever an #ifdef is seen.
313  virtual void Ifdef(const Token &MacroNameTok) {
314    First->Ifdef(MacroNameTok);
315    Second->Ifdef(MacroNameTok);
316  }
317
318  /// Ifndef -- This hook is called whenever an #ifndef is seen.
319  virtual void Ifndef(const Token &MacroNameTok) {
320    First->Ifndef(MacroNameTok);
321    Second->Ifndef(MacroNameTok);
322  }
323
324  /// Else -- This hook is called whenever an #else is seen.
325  virtual void Else() {
326    First->Else();
327    Second->Else();
328  }
329
330  /// Endif -- This hook is called whenever an #endif is seen.
331  virtual void Endif() {
332    First->Endif();
333    Second->Endif();
334  }
335};
336
337}  // end namespace clang
338
339#endif
340