PPCallbacks.h revision 686775deca8b8685eb90801495880e3abdd844c2
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  }
151
152  /// MacroDefined - This hook is called whenever a macro definition is seen.
153  virtual void MacroDefined(const Token &MacroNameTok, const MacroInfo *MI) {
154  }
155
156  /// MacroUndefined - This hook is called whenever a macro #undef is seen.
157  /// MI is released immediately following this callback.
158  virtual void MacroUndefined(const Token &MacroNameTok, const MacroInfo *MI) {
159  }
160
161  /// If -- This hook is called whenever an #if is seen.
162  /// \param Range The SourceRange of the expression being tested.
163  // FIXME: better to pass in a list (or tree!) of Tokens.
164  virtual void If(SourceRange Range) {
165  }
166
167  /// Elif -- This hook is called whenever an #elif is seen.
168  /// \param Range The SourceRange of the expression being tested.
169  // FIXME: better to pass in a list (or tree!) of Tokens.
170  virtual void Elif(SourceRange Range) {
171  }
172
173  /// Ifdef -- This hook is called whenever an #ifdef is seen.
174  /// \param Loc The location of the token being tested.
175  /// \param II Information on the token being tested.
176  virtual void Ifdef(const Token &MacroNameTok) {
177  }
178
179  /// Ifndef -- This hook is called whenever an #ifndef is seen.
180  /// \param Loc The location of the token being tested.
181  /// \param II Information on the token being tested.
182  virtual void Ifndef(const Token &MacroNameTok) {
183  }
184
185  /// Else -- This hook is called whenever an #else is seen.
186  virtual void Else() {
187  }
188
189  /// Endif -- This hook is called whenever an #endif is seen.
190  virtual void Endif() {
191  }
192};
193
194/// PPChainedCallbacks - Simple wrapper class for chaining callbacks.
195class PPChainedCallbacks : public PPCallbacks {
196  PPCallbacks *First, *Second;
197
198public:
199  PPChainedCallbacks(PPCallbacks *_First, PPCallbacks *_Second)
200    : First(_First), Second(_Second) {}
201  ~PPChainedCallbacks() {
202    delete Second;
203    delete First;
204  }
205
206  virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason,
207                           SrcMgr::CharacteristicKind FileType) {
208    First->FileChanged(Loc, Reason, FileType);
209    Second->FileChanged(Loc, Reason, FileType);
210  }
211
212  virtual void FileSkipped(const FileEntry &ParentFile,
213                           const Token &FilenameTok,
214                           SrcMgr::CharacteristicKind FileType) {
215    First->FileSkipped(ParentFile, FilenameTok, FileType);
216    Second->FileSkipped(ParentFile, FilenameTok, FileType);
217  }
218
219  virtual void InclusionDirective(SourceLocation HashLoc,
220                                  const Token &IncludeTok,
221                                  StringRef FileName,
222                                  bool IsAngled,
223                                  const FileEntry *File,
224                                  SourceLocation EndLoc,
225                                  StringRef SearchPath,
226                                  StringRef RelativePath) {
227    First->InclusionDirective(HashLoc, IncludeTok, FileName, IsAngled, File,
228                              EndLoc, SearchPath, RelativePath);
229    Second->InclusionDirective(HashLoc, IncludeTok, FileName, IsAngled, File,
230                               EndLoc, SearchPath, RelativePath);
231  }
232
233  virtual void EndOfMainFile() {
234    First->EndOfMainFile();
235    Second->EndOfMainFile();
236  }
237
238  virtual void Ident(SourceLocation Loc, const std::string &str) {
239    First->Ident(Loc, str);
240    Second->Ident(Loc, str);
241  }
242
243  virtual void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind,
244                             const std::string &Str) {
245    First->PragmaComment(Loc, Kind, Str);
246    Second->PragmaComment(Loc, Kind, Str);
247  }
248
249  virtual void PragmaMessage(SourceLocation Loc, StringRef Str) {
250    First->PragmaMessage(Loc, Str);
251    Second->PragmaMessage(Loc, Str);
252  }
253
254  virtual void PragmaDiagnosticPush(SourceLocation Loc,
255                                    StringRef Namespace) {
256    First->PragmaDiagnosticPush(Loc, Namespace);
257    Second->PragmaDiagnosticPush(Loc, Namespace);
258  }
259
260  virtual void PragmaDiagnosticPop(SourceLocation Loc,
261                                    StringRef Namespace) {
262    First->PragmaDiagnosticPop(Loc, Namespace);
263    Second->PragmaDiagnosticPop(Loc, Namespace);
264  }
265
266  virtual void PragmaDiagnostic(SourceLocation Loc, StringRef Namespace,
267                                diag::Mapping mapping, StringRef Str) {
268    First->PragmaDiagnostic(Loc, Namespace, mapping, Str);
269    Second->PragmaDiagnostic(Loc, Namespace, mapping, Str);
270  }
271
272  virtual void MacroExpands(const Token &MacroNameTok, const MacroInfo* MI) {
273    First->MacroExpands(MacroNameTok, MI);
274    Second->MacroExpands(MacroNameTok, MI);
275  }
276
277  virtual void MacroDefined(const Token &MacroNameTok, const MacroInfo *MI) {
278    First->MacroDefined(MacroNameTok, MI);
279    Second->MacroDefined(MacroNameTok, MI);
280  }
281
282  virtual void MacroUndefined(const Token &MacroNameTok, const MacroInfo *MI) {
283    First->MacroUndefined(MacroNameTok, MI);
284    Second->MacroUndefined(MacroNameTok, MI);
285  }
286
287  /// If -- This hook is called whenever an #if is seen.
288  virtual void If(SourceRange Range) {
289    First->If(Range);
290    Second->If(Range);
291  }
292
293  /// Elif -- This hook is called whenever an #if is seen.
294  virtual void Elif(SourceRange Range) {
295    First->Elif(Range);
296    Second->Elif(Range);
297  }
298
299  /// Ifdef -- This hook is called whenever an #ifdef is seen.
300  virtual void Ifdef(const Token &MacroNameTok) {
301    First->Ifdef(MacroNameTok);
302    Second->Ifdef(MacroNameTok);
303  }
304
305  /// Ifndef -- This hook is called whenever an #ifndef is seen.
306  virtual void Ifndef(const Token &MacroNameTok) {
307    First->Ifndef(MacroNameTok);
308    Second->Ifndef(MacroNameTok);
309  }
310
311  /// Else -- This hook is called whenever an #else is seen.
312  virtual void Else() {
313    First->Else();
314    Second->Else();
315  }
316
317  /// Endif -- This hook is called whenever an #endif is seen.
318  virtual void Endif() {
319    First->Endif();
320    Second->Endif();
321  }
322};
323
324}  // end namespace clang
325
326#endif
327