PPCallbacks.h revision 226890
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//===----------------------------------------------------------------------===//
9193326Sed//
10193326Sed//  This file defines the PPCallbacks interface.
11193326Sed//
12193326Sed//===----------------------------------------------------------------------===//
13193326Sed
14193326Sed#ifndef LLVM_CLANG_LEX_PPCALLBACKS_H
15193326Sed#define LLVM_CLANG_LEX_PPCALLBACKS_H
16193326Sed
17193326Sed#include "clang/Lex/DirectoryLookup.h"
18193326Sed#include "clang/Basic/SourceLocation.h"
19224145Sdim#include "clang/Basic/DiagnosticIDs.h"
20210299Sed#include "llvm/ADT/StringRef.h"
21193326Sed#include <string>
22193326Sed
23193326Sednamespace clang {
24193326Sed  class SourceLocation;
25193326Sed  class Token;
26193326Sed  class IdentifierInfo;
27193326Sed  class MacroInfo;
28198092Srdivacky
29193326Sed/// PPCallbacks - This interface provides a way to observe the actions of the
30193326Sed/// preprocessor as it does its thing.  Clients can define their hooks here to
31193326Sed/// implement preprocessor level tools.
32193326Sedclass PPCallbacks {
33193326Sedpublic:
34193326Sed  virtual ~PPCallbacks();
35198092Srdivacky
36193326Sed  enum FileChangeReason {
37193326Sed    EnterFile, ExitFile, SystemHeaderPragma, RenameFile
38193326Sed  };
39198092Srdivacky
40193326Sed  /// FileChanged - This callback is invoked whenever a source file is
41193326Sed  /// entered or exited.  The SourceLocation indicates the new location, and
42193326Sed  /// EnteringFile indicates whether this is because we are entering a new
43193326Sed  /// #include'd file (when true) or whether we're exiting one because we ran
44193326Sed  /// off the end (when false).
45226890Sdim  ///
46226890Sdim  /// \param PrevFID the file that was exited if \arg Reason is ExitFile.
47193326Sed  virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason,
48226890Sdim                           SrcMgr::CharacteristicKind FileType,
49226890Sdim                           FileID PrevFID = FileID()) {
50193326Sed  }
51198092Srdivacky
52207619Srdivacky  /// FileSkipped - This callback is invoked whenever a source file is
53207619Srdivacky  /// skipped as the result of header guard optimization.  ParentFile
54207619Srdivacky  /// is the file that #includes the skipped file.  FilenameTok is the
55207619Srdivacky  /// token in ParentFile that indicates the skipped file.
56207619Srdivacky  virtual void FileSkipped(const FileEntry &ParentFile,
57207619Srdivacky                           const Token &FilenameTok,
58207619Srdivacky                           SrcMgr::CharacteristicKind FileType) {
59207619Srdivacky  }
60206084Srdivacky
61218893Sdim  /// \brief This callback is invoked whenever an inclusion directive of
62218893Sdim  /// any kind (\c #include, \c #import, etc.) has been processed, regardless
63218893Sdim  /// of whether the inclusion will actually result in an inclusion.
64218893Sdim  ///
65218893Sdim  /// \param HashLoc The location of the '#' that starts the inclusion
66218893Sdim  /// directive.
67218893Sdim  ///
68218893Sdim  /// \param IncludeTok The token that indicates the kind of inclusion
69218893Sdim  /// directive, e.g., 'include' or 'import'.
70218893Sdim  ///
71218893Sdim  /// \param FileName The name of the file being included, as written in the
72218893Sdim  /// source code.
73218893Sdim  ///
74218893Sdim  /// \param IsAngled Whether the file name was enclosed in angle brackets;
75218893Sdim  /// otherwise, it was enclosed in quotes.
76218893Sdim  ///
77218893Sdim  /// \param File The actual file that may be included by this inclusion
78218893Sdim  /// directive.
79218893Sdim  ///
80218893Sdim  /// \param EndLoc The location of the last token within the inclusion
81218893Sdim  /// directive.
82221345Sdim  ///
83221345Sdim  /// \param SearchPath Contains the search path which was used to find the file
84221345Sdim  /// in the file system. If the file was found via an absolute include path,
85221345Sdim  /// SearchPath will be empty. For framework includes, the SearchPath and
86221345Sdim  /// RelativePath will be split up. For example, if an include of "Some/Some.h"
87221345Sdim  /// is found via the framework path
88221345Sdim  /// "path/to/Frameworks/Some.framework/Headers/Some.h", SearchPath will be
89221345Sdim  /// "path/to/Frameworks/Some.framework/Headers" and RelativePath will be
90221345Sdim  /// "Some.h".
91221345Sdim  ///
92221345Sdim  /// \param RelativePath The path relative to SearchPath, at which the include
93221345Sdim  /// file was found. This is equal to FileName except for framework includes.
94218893Sdim  virtual void InclusionDirective(SourceLocation HashLoc,
95218893Sdim                                  const Token &IncludeTok,
96226890Sdim                                  StringRef FileName,
97218893Sdim                                  bool IsAngled,
98218893Sdim                                  const FileEntry *File,
99221345Sdim                                  SourceLocation EndLoc,
100226890Sdim                                  StringRef SearchPath,
101226890Sdim                                  StringRef RelativePath) {
102218893Sdim  }
103218893Sdim
104206084Srdivacky  /// EndOfMainFile - This callback is invoked when the end of the main file is
105206084Srdivacky  /// reach, no subsequent callbacks will be made.
106206084Srdivacky  virtual void EndOfMainFile() {
107206084Srdivacky  }
108206084Srdivacky
109193326Sed  /// Ident - This callback is invoked when a #ident or #sccs directive is read.
110218893Sdim  /// \param Loc The location of the directive.
111218893Sdim  /// \param str The text of the directive.
112193326Sed  ///
113193326Sed  virtual void Ident(SourceLocation Loc, const std::string &str) {
114193326Sed  }
115198092Srdivacky
116193326Sed  /// PragmaComment - This callback is invoked when a #pragma comment directive
117193326Sed  /// is read.
118193326Sed  ///
119198092Srdivacky  virtual void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind,
120193326Sed                             const std::string &Str) {
121193326Sed  }
122198092Srdivacky
123210299Sed  /// PragmaMessage - This callback is invoked when a #pragma message directive
124210299Sed  /// is read.
125218893Sdim  /// \param Loc The location of the message directive.
126218893Sdim  /// \param str The text of the message directive.
127210299Sed  ///
128226890Sdim  virtual void PragmaMessage(SourceLocation Loc, StringRef Str) {
129210299Sed  }
130210299Sed
131224145Sdim  /// PragmaDiagnosticPush - This callback is invoked when a
132224145Sdim  /// #pragma gcc dianostic push directive is read.
133224145Sdim  virtual void PragmaDiagnosticPush(SourceLocation Loc,
134226890Sdim                                    StringRef Namespace) {
135224145Sdim  }
136224145Sdim
137224145Sdim  /// PragmaDiagnosticPop - This callback is invoked when a
138224145Sdim  /// #pragma gcc dianostic pop directive is read.
139224145Sdim  virtual void PragmaDiagnosticPop(SourceLocation Loc,
140226890Sdim                                   StringRef Namespace) {
141224145Sdim  }
142224145Sdim
143224145Sdim  /// PragmaDiagnostic - This callback is invoked when a
144224145Sdim  /// #pragma gcc dianostic directive is read.
145226890Sdim  virtual void PragmaDiagnostic(SourceLocation Loc, StringRef Namespace,
146226890Sdim                                diag::Mapping mapping, StringRef Str) {
147224145Sdim  }
148224145Sdim
149193326Sed  /// MacroExpands - This is called by
150193326Sed  /// Preprocessor::HandleMacroExpandedIdentifier when a macro invocation is
151193326Sed  /// found.
152226890Sdim  virtual void MacroExpands(const Token &MacroNameTok, const MacroInfo* MI,
153226890Sdim                            SourceRange Range) {
154193326Sed  }
155198092Srdivacky
156193326Sed  /// MacroDefined - This hook is called whenever a macro definition is seen.
157218893Sdim  virtual void MacroDefined(const Token &MacroNameTok, const MacroInfo *MI) {
158193326Sed  }
159193326Sed
160193326Sed  /// MacroUndefined - This hook is called whenever a macro #undef is seen.
161193326Sed  /// MI is released immediately following this callback.
162218893Sdim  virtual void MacroUndefined(const Token &MacroNameTok, const MacroInfo *MI) {
163193326Sed  }
164226890Sdim
165226890Sdim  /// Defined - This hook is called whenever the 'defined' operator is seen.
166226890Sdim  virtual void Defined(const Token &MacroNameTok) {
167226890Sdim  }
168226890Sdim
169226890Sdim  /// SourceRangeSkipped - This hook is called when a source range is skipped.
170226890Sdim  /// \param Range The SourceRange that was skipped. The range begins at the
171226890Sdim  /// #if/#else directive and ends after the #endif/#else directive.
172226890Sdim  virtual void SourceRangeSkipped(SourceRange Range) {
173226890Sdim  }
174218893Sdim
175218893Sdim  /// If -- This hook is called whenever an #if is seen.
176218893Sdim  /// \param Range The SourceRange of the expression being tested.
177218893Sdim  // FIXME: better to pass in a list (or tree!) of Tokens.
178218893Sdim  virtual void If(SourceRange Range) {
179218893Sdim  }
180218893Sdim
181218893Sdim  /// Elif -- This hook is called whenever an #elif is seen.
182218893Sdim  /// \param Range The SourceRange of the expression being tested.
183218893Sdim  // FIXME: better to pass in a list (or tree!) of Tokens.
184218893Sdim  virtual void Elif(SourceRange Range) {
185218893Sdim  }
186218893Sdim
187218893Sdim  /// Ifdef -- This hook is called whenever an #ifdef is seen.
188218893Sdim  /// \param Loc The location of the token being tested.
189218893Sdim  /// \param II Information on the token being tested.
190218893Sdim  virtual void Ifdef(const Token &MacroNameTok) {
191218893Sdim  }
192218893Sdim
193218893Sdim  /// Ifndef -- This hook is called whenever an #ifndef is seen.
194218893Sdim  /// \param Loc The location of the token being tested.
195218893Sdim  /// \param II Information on the token being tested.
196218893Sdim  virtual void Ifndef(const Token &MacroNameTok) {
197218893Sdim  }
198218893Sdim
199218893Sdim  /// Else -- This hook is called whenever an #else is seen.
200218893Sdim  virtual void Else() {
201218893Sdim  }
202218893Sdim
203218893Sdim  /// Endif -- This hook is called whenever an #endif is seen.
204218893Sdim  virtual void Endif() {
205218893Sdim  }
206193326Sed};
207193326Sed
208193326Sed/// PPChainedCallbacks - Simple wrapper class for chaining callbacks.
209193326Sedclass PPChainedCallbacks : public PPCallbacks {
210193326Sed  PPCallbacks *First, *Second;
211193326Sed
212198092Srdivackypublic:
213193326Sed  PPChainedCallbacks(PPCallbacks *_First, PPCallbacks *_Second)
214193326Sed    : First(_First), Second(_Second) {}
215193326Sed  ~PPChainedCallbacks() {
216193326Sed    delete Second;
217193326Sed    delete First;
218193326Sed  }
219193326Sed
220193326Sed  virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason,
221226890Sdim                           SrcMgr::CharacteristicKind FileType,
222226890Sdim                           FileID PrevFID) {
223226890Sdim    First->FileChanged(Loc, Reason, FileType, PrevFID);
224226890Sdim    Second->FileChanged(Loc, Reason, FileType, PrevFID);
225193326Sed  }
226198092Srdivacky
227207619Srdivacky  virtual void FileSkipped(const FileEntry &ParentFile,
228207619Srdivacky                           const Token &FilenameTok,
229207619Srdivacky                           SrcMgr::CharacteristicKind FileType) {
230207619Srdivacky    First->FileSkipped(ParentFile, FilenameTok, FileType);
231207619Srdivacky    Second->FileSkipped(ParentFile, FilenameTok, FileType);
232207619Srdivacky  }
233207619Srdivacky
234218893Sdim  virtual void InclusionDirective(SourceLocation HashLoc,
235218893Sdim                                  const Token &IncludeTok,
236226890Sdim                                  StringRef FileName,
237218893Sdim                                  bool IsAngled,
238218893Sdim                                  const FileEntry *File,
239221345Sdim                                  SourceLocation EndLoc,
240226890Sdim                                  StringRef SearchPath,
241226890Sdim                                  StringRef RelativePath) {
242221345Sdim    First->InclusionDirective(HashLoc, IncludeTok, FileName, IsAngled, File,
243221345Sdim                              EndLoc, SearchPath, RelativePath);
244221345Sdim    Second->InclusionDirective(HashLoc, IncludeTok, FileName, IsAngled, File,
245221345Sdim                               EndLoc, SearchPath, RelativePath);
246218893Sdim  }
247218893Sdim
248206084Srdivacky  virtual void EndOfMainFile() {
249206084Srdivacky    First->EndOfMainFile();
250206084Srdivacky    Second->EndOfMainFile();
251206084Srdivacky  }
252206084Srdivacky
253193326Sed  virtual void Ident(SourceLocation Loc, const std::string &str) {
254193326Sed    First->Ident(Loc, str);
255193326Sed    Second->Ident(Loc, str);
256193326Sed  }
257198092Srdivacky
258198092Srdivacky  virtual void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind,
259193326Sed                             const std::string &Str) {
260193326Sed    First->PragmaComment(Loc, Kind, Str);
261193326Sed    Second->PragmaComment(Loc, Kind, Str);
262193326Sed  }
263198092Srdivacky
264226890Sdim  virtual void PragmaMessage(SourceLocation Loc, StringRef Str) {
265210299Sed    First->PragmaMessage(Loc, Str);
266210299Sed    Second->PragmaMessage(Loc, Str);
267210299Sed  }
268210299Sed
269224145Sdim  virtual void PragmaDiagnosticPush(SourceLocation Loc,
270226890Sdim                                    StringRef Namespace) {
271224145Sdim    First->PragmaDiagnosticPush(Loc, Namespace);
272224145Sdim    Second->PragmaDiagnosticPush(Loc, Namespace);
273224145Sdim  }
274224145Sdim
275224145Sdim  virtual void PragmaDiagnosticPop(SourceLocation Loc,
276226890Sdim                                    StringRef Namespace) {
277224145Sdim    First->PragmaDiagnosticPop(Loc, Namespace);
278224145Sdim    Second->PragmaDiagnosticPop(Loc, Namespace);
279224145Sdim  }
280224145Sdim
281226890Sdim  virtual void PragmaDiagnostic(SourceLocation Loc, StringRef Namespace,
282226890Sdim                                diag::Mapping mapping, StringRef Str) {
283224145Sdim    First->PragmaDiagnostic(Loc, Namespace, mapping, Str);
284224145Sdim    Second->PragmaDiagnostic(Loc, Namespace, mapping, Str);
285224145Sdim  }
286224145Sdim
287226890Sdim  virtual void MacroExpands(const Token &MacroNameTok, const MacroInfo* MI,
288226890Sdim                            SourceRange Range) {
289226890Sdim    First->MacroExpands(MacroNameTok, MI, Range);
290226890Sdim    Second->MacroExpands(MacroNameTok, MI, Range);
291193326Sed  }
292198092Srdivacky
293218893Sdim  virtual void MacroDefined(const Token &MacroNameTok, const MacroInfo *MI) {
294218893Sdim    First->MacroDefined(MacroNameTok, MI);
295218893Sdim    Second->MacroDefined(MacroNameTok, MI);
296193326Sed  }
297193326Sed
298218893Sdim  virtual void MacroUndefined(const Token &MacroNameTok, const MacroInfo *MI) {
299218893Sdim    First->MacroUndefined(MacroNameTok, MI);
300218893Sdim    Second->MacroUndefined(MacroNameTok, MI);
301193326Sed  }
302218893Sdim
303226890Sdim  virtual void Defined(const Token &MacroNameTok) {
304226890Sdim    First->Defined(MacroNameTok);
305226890Sdim    Second->Defined(MacroNameTok);
306226890Sdim  }
307226890Sdim
308226890Sdim  virtual void SourceRangeSkipped(SourceRange Range) {
309226890Sdim    First->SourceRangeSkipped(Range);
310226890Sdim    Second->SourceRangeSkipped(Range);
311226890Sdim  }
312226890Sdim
313218893Sdim  /// If -- This hook is called whenever an #if is seen.
314218893Sdim  virtual void If(SourceRange Range) {
315218893Sdim    First->If(Range);
316218893Sdim    Second->If(Range);
317218893Sdim  }
318218893Sdim
319218893Sdim  /// Elif -- This hook is called whenever an #if is seen.
320218893Sdim  virtual void Elif(SourceRange Range) {
321218893Sdim    First->Elif(Range);
322218893Sdim    Second->Elif(Range);
323218893Sdim  }
324218893Sdim
325218893Sdim  /// Ifdef -- This hook is called whenever an #ifdef is seen.
326218893Sdim  virtual void Ifdef(const Token &MacroNameTok) {
327218893Sdim    First->Ifdef(MacroNameTok);
328218893Sdim    Second->Ifdef(MacroNameTok);
329218893Sdim  }
330218893Sdim
331218893Sdim  /// Ifndef -- This hook is called whenever an #ifndef is seen.
332218893Sdim  virtual void Ifndef(const Token &MacroNameTok) {
333218893Sdim    First->Ifndef(MacroNameTok);
334218893Sdim    Second->Ifndef(MacroNameTok);
335218893Sdim  }
336218893Sdim
337218893Sdim  /// Else -- This hook is called whenever an #else is seen.
338218893Sdim  virtual void Else() {
339218893Sdim    First->Else();
340218893Sdim    Second->Else();
341218893Sdim  }
342218893Sdim
343218893Sdim  /// Endif -- This hook is called whenever an #endif is seen.
344218893Sdim  virtual void Endif() {
345218893Sdim    First->Endif();
346218893Sdim    Second->Endif();
347218893Sdim  }
348193326Sed};
349193326Sed
350193326Sed}  // end namespace clang
351193326Sed
352193326Sed#endif
353