PPCallbacks.h revision b5142bb7af5c70fffd09f05172a1379a35a9c29a
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  ///
79  /// \param RawPath Contains the raw path at which the file was found in the
80  /// file system. For example, for a search path ".." and a filename
81  /// "../file.h" this would be "../../file.h".
82  virtual void InclusionDirective(SourceLocation HashLoc,
83                                  const Token &IncludeTok,
84                                  llvm::StringRef FileName,
85                                  bool IsAngled,
86                                  const FileEntry *File,
87                                  SourceLocation EndLoc,
88                                  const llvm::SmallVectorImpl<char> &RawPath) {
89  }
90
91  /// EndOfMainFile - This callback is invoked when the end of the main file is
92  /// reach, no subsequent callbacks will be made.
93  virtual void EndOfMainFile() {
94  }
95
96  /// Ident - This callback is invoked when a #ident or #sccs directive is read.
97  /// \param Loc The location of the directive.
98  /// \param str The text of the directive.
99  ///
100  virtual void Ident(SourceLocation Loc, const std::string &str) {
101  }
102
103  /// PragmaComment - This callback is invoked when a #pragma comment directive
104  /// is read.
105  ///
106  virtual void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind,
107                             const std::string &Str) {
108  }
109
110  /// PragmaMessage - This callback is invoked when a #pragma message directive
111  /// is read.
112  /// \param Loc The location of the message directive.
113  /// \param str The text of the message directive.
114  ///
115  virtual void PragmaMessage(SourceLocation Loc, llvm::StringRef Str) {
116  }
117
118  /// MacroExpands - This is called by
119  /// Preprocessor::HandleMacroExpandedIdentifier when a macro invocation is
120  /// found.
121  virtual void MacroExpands(const Token &MacroNameTok, const MacroInfo* MI) {
122  }
123
124  /// MacroDefined - This hook is called whenever a macro definition is seen.
125  virtual void MacroDefined(const Token &MacroNameTok, const MacroInfo *MI) {
126  }
127
128  /// MacroUndefined - This hook is called whenever a macro #undef is seen.
129  /// MI is released immediately following this callback.
130  virtual void MacroUndefined(const Token &MacroNameTok, const MacroInfo *MI) {
131  }
132
133  /// If -- This hook is called whenever an #if is seen.
134  /// \param Range The SourceRange of the expression being tested.
135  // FIXME: better to pass in a list (or tree!) of Tokens.
136  virtual void If(SourceRange Range) {
137  }
138
139  /// Elif -- This hook is called whenever an #elif is seen.
140  /// \param Range The SourceRange of the expression being tested.
141  // FIXME: better to pass in a list (or tree!) of Tokens.
142  virtual void Elif(SourceRange Range) {
143  }
144
145  /// Ifdef -- This hook is called whenever an #ifdef is seen.
146  /// \param Loc The location of the token being tested.
147  /// \param II Information on the token being tested.
148  virtual void Ifdef(const Token &MacroNameTok) {
149  }
150
151  /// Ifndef -- This hook is called whenever an #ifndef is seen.
152  /// \param Loc The location of the token being tested.
153  /// \param II Information on the token being tested.
154  virtual void Ifndef(const Token &MacroNameTok) {
155  }
156
157  /// Else -- This hook is called whenever an #else is seen.
158  virtual void Else() {
159  }
160
161  /// Endif -- This hook is called whenever an #endif is seen.
162  virtual void Endif() {
163  }
164};
165
166/// PPChainedCallbacks - Simple wrapper class for chaining callbacks.
167class PPChainedCallbacks : public PPCallbacks {
168  PPCallbacks *First, *Second;
169
170public:
171  PPChainedCallbacks(PPCallbacks *_First, PPCallbacks *_Second)
172    : First(_First), Second(_Second) {}
173  ~PPChainedCallbacks() {
174    delete Second;
175    delete First;
176  }
177
178  virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason,
179                           SrcMgr::CharacteristicKind FileType) {
180    First->FileChanged(Loc, Reason, FileType);
181    Second->FileChanged(Loc, Reason, FileType);
182  }
183
184  virtual void FileSkipped(const FileEntry &ParentFile,
185                           const Token &FilenameTok,
186                           SrcMgr::CharacteristicKind FileType) {
187    First->FileSkipped(ParentFile, FilenameTok, FileType);
188    Second->FileSkipped(ParentFile, FilenameTok, FileType);
189  }
190
191  virtual void InclusionDirective(SourceLocation HashLoc,
192                                  const Token &IncludeTok,
193                                  llvm::StringRef FileName,
194                                  bool IsAngled,
195                                  const FileEntry *File,
196                                  SourceLocation EndLoc,
197                                  const llvm::SmallVectorImpl<char> &RawPath) {
198    First->InclusionDirective(HashLoc, IncludeTok, FileName, IsAngled, File,
199                              EndLoc, RawPath);
200    Second->InclusionDirective(HashLoc, IncludeTok, FileName, IsAngled, File,
201                               EndLoc, RawPath);
202  }
203
204  virtual void EndOfMainFile() {
205    First->EndOfMainFile();
206    Second->EndOfMainFile();
207  }
208
209  virtual void Ident(SourceLocation Loc, const std::string &str) {
210    First->Ident(Loc, str);
211    Second->Ident(Loc, str);
212  }
213
214  virtual void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind,
215                             const std::string &Str) {
216    First->PragmaComment(Loc, Kind, Str);
217    Second->PragmaComment(Loc, Kind, Str);
218  }
219
220  virtual void PragmaMessage(SourceLocation Loc, llvm::StringRef Str) {
221    First->PragmaMessage(Loc, Str);
222    Second->PragmaMessage(Loc, Str);
223  }
224
225  virtual void MacroExpands(const Token &MacroNameTok, const MacroInfo* MI) {
226    First->MacroExpands(MacroNameTok, MI);
227    Second->MacroExpands(MacroNameTok, MI);
228  }
229
230  virtual void MacroDefined(const Token &MacroNameTok, const MacroInfo *MI) {
231    First->MacroDefined(MacroNameTok, MI);
232    Second->MacroDefined(MacroNameTok, MI);
233  }
234
235  virtual void MacroUndefined(const Token &MacroNameTok, const MacroInfo *MI) {
236    First->MacroUndefined(MacroNameTok, MI);
237    Second->MacroUndefined(MacroNameTok, MI);
238  }
239
240  /// If -- This hook is called whenever an #if is seen.
241  virtual void If(SourceRange Range) {
242    First->If(Range);
243    Second->If(Range);
244  }
245
246  /// Elif -- This hook is called whenever an #if is seen.
247  virtual void Elif(SourceRange Range) {
248    First->Elif(Range);
249    Second->Elif(Range);
250  }
251
252  /// Ifdef -- This hook is called whenever an #ifdef is seen.
253  virtual void Ifdef(const Token &MacroNameTok) {
254    First->Ifdef(MacroNameTok);
255    Second->Ifdef(MacroNameTok);
256  }
257
258  /// Ifndef -- This hook is called whenever an #ifndef is seen.
259  virtual void Ifndef(const Token &MacroNameTok) {
260    First->Ifndef(MacroNameTok);
261    Second->Ifndef(MacroNameTok);
262  }
263
264  /// Else -- This hook is called whenever an #else is seen.
265  virtual void Else() {
266    First->Else();
267    Second->Else();
268  }
269
270  /// Endif -- This hook is called whenever an #endif is seen.
271  virtual void Endif() {
272    First->Endif();
273    Second->Endif();
274  }
275};
276
277}  // end namespace clang
278
279#endif
280