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