]> CyberLeo.Net >> Repos - FreeBSD/stable/9.git/blob - contrib/llvm/tools/clang/include/clang/Lex/PPCallbacks.h
MFC r244628:
[FreeBSD/stable/9.git] / contrib / llvm / tools / clang / include / clang / Lex / PPCallbacks.h
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 /// \file
11 /// \brief Defines the PPCallbacks interface.
12 ///
13 //===----------------------------------------------------------------------===//
14
15 #ifndef LLVM_CLANG_LEX_PPCALLBACKS_H
16 #define LLVM_CLANG_LEX_PPCALLBACKS_H
17
18 #include "clang/Lex/DirectoryLookup.h"
19 #include "clang/Lex/ModuleLoader.h"
20 #include "clang/Basic/SourceLocation.h"
21 #include "clang/Basic/DiagnosticIDs.h"
22 #include "llvm/ADT/StringRef.h"
23 #include <string>
24
25 namespace clang {
26   class SourceLocation;
27   class Token;
28   class IdentifierInfo;
29   class MacroInfo;
30
31 /// \brief This interface provides a way to observe the actions of the
32 /// preprocessor as it does its thing.
33 ///
34 /// Clients can define their hooks here to implement preprocessor level tools.
35 class PPCallbacks {
36 public:
37   virtual ~PPCallbacks();
38
39   enum FileChangeReason {
40     EnterFile, ExitFile, SystemHeaderPragma, RenameFile
41   };
42
43   /// \brief Callback invoked whenever a source file is entered or exited.
44   ///
45   /// \param Loc Indicates the new location.
46   /// \param PrevFID the file that was exited if \p Reason is ExitFile.
47   virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason,
48                            SrcMgr::CharacteristicKind FileType,
49                            FileID PrevFID = FileID()) {
50   }
51
52   /// \brief Callback invoked whenever a source file is skipped as the result
53   /// of header guard optimization.
54   ///
55   /// \param ParentFile The file that \#included the skipped file.
56   ///
57   /// \param FilenameTok The token in ParentFile that indicates the
58   /// skipped file.
59   virtual void FileSkipped(const FileEntry &ParentFile,
60                            const Token &FilenameTok,
61                            SrcMgr::CharacteristicKind FileType) {
62   }
63
64   /// \brief Callback invoked whenever an inclusion directive results in a
65   /// file-not-found error.
66   ///
67   /// \param FileName The name of the file being included, as written in the 
68   /// source code.
69   ///
70   /// \param RecoveryPath If this client indicates that it can recover from 
71   /// this missing file, the client should set this as an additional header
72   /// search patch.
73   ///
74   /// \returns true to indicate that the preprocessor should attempt to recover
75   /// by adding \p RecoveryPath as a header search path.
76   virtual bool FileNotFound(StringRef FileName,
77                             SmallVectorImpl<char> &RecoveryPath) {
78     return false;
79   }
80
81   /// \brief Callback invoked whenever an inclusion directive of
82   /// any kind (\c \#include, \c \#import, etc.) has been processed, regardless
83   /// of whether the inclusion will actually result in an inclusion.
84   ///
85   /// \param HashLoc The location of the '#' that starts the inclusion 
86   /// directive.
87   ///
88   /// \param IncludeTok The token that indicates the kind of inclusion 
89   /// directive, e.g., 'include' or 'import'.
90   ///
91   /// \param FileName The name of the file being included, as written in the 
92   /// source code.
93   ///
94   /// \param IsAngled Whether the file name was enclosed in angle brackets;
95   /// otherwise, it was enclosed in quotes.
96   ///
97   /// \param FilenameRange The character range of the quotes or angle brackets
98   /// for the written file name.
99   ///
100   /// \param File The actual file that may be included by this inclusion 
101   /// directive.
102   ///
103   /// \param SearchPath Contains the search path which was used to find the file
104   /// in the file system. If the file was found via an absolute include path,
105   /// SearchPath will be empty. For framework includes, the SearchPath and
106   /// RelativePath will be split up. For example, if an include of "Some/Some.h"
107   /// is found via the framework path
108   /// "path/to/Frameworks/Some.framework/Headers/Some.h", SearchPath will be
109   /// "path/to/Frameworks/Some.framework/Headers" and RelativePath will be
110   /// "Some.h".
111   ///
112   /// \param RelativePath The path relative to SearchPath, at which the include
113   /// file was found. This is equal to FileName except for framework includes.
114   ///
115   /// \param Imported The module, whenever an inclusion directive was
116   /// automatically turned into a module import or null otherwise.
117   ///
118   virtual void InclusionDirective(SourceLocation HashLoc,
119                                   const Token &IncludeTok,
120                                   StringRef FileName,
121                                   bool IsAngled,
122                                   CharSourceRange FilenameRange,
123                                   const FileEntry *File,
124                                   StringRef SearchPath,
125                                   StringRef RelativePath,
126                                   const Module *Imported) {
127   }
128
129   /// \brief Callback invoked whenever there was an explicit module-import
130   /// syntax.
131   ///
132   /// \param ImportLoc The location of import directive token.
133   ///
134   /// \param Path The identifiers (and their locations) of the module
135   /// "path", e.g., "std.vector" would be split into "std" and "vector".
136   ///
137   /// \param Imported The imported module; can be null if importing failed.
138   ///
139   virtual void moduleImport(SourceLocation ImportLoc,
140                             ModuleIdPath Path,
141                             const Module *Imported) {
142   }
143
144   /// \brief Callback invoked when the end of the main file is reached.
145   ///
146   /// No subsequent callbacks will be made.
147   virtual void EndOfMainFile() {
148   }
149
150   /// \brief Callback invoked when a \#ident or \#sccs directive is read.
151   /// \param Loc The location of the directive.
152   /// \param str The text of the directive.
153   ///
154   virtual void Ident(SourceLocation Loc, const std::string &str) {
155   }
156
157   /// \brief Callback invoked when a \#pragma comment directive is read.
158   virtual void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind,
159                              const std::string &Str) {
160   }
161
162   /// \brief Callback invoked when a \#pragma message directive is read.
163   /// \param Loc The location of the message directive.
164   /// \param Str The text of the message directive.
165   virtual void PragmaMessage(SourceLocation Loc, StringRef Str) {
166   }
167
168   /// \brief Callback invoked when a \#pragma gcc dianostic push directive
169   /// is read.
170   virtual void PragmaDiagnosticPush(SourceLocation Loc,
171                                     StringRef Namespace) {
172   }
173
174   /// \brief Callback invoked when a \#pragma gcc dianostic pop directive
175   /// is read.
176   virtual void PragmaDiagnosticPop(SourceLocation Loc,
177                                    StringRef Namespace) {
178   }
179
180   /// \brief Callback invoked when a \#pragma gcc dianostic directive is read.
181   virtual void PragmaDiagnostic(SourceLocation Loc, StringRef Namespace,
182                                 diag::Mapping mapping, StringRef Str) {
183   }
184
185   /// \brief Called by Preprocessor::HandleMacroExpandedIdentifier when a
186   /// macro invocation is found.
187   virtual void MacroExpands(const Token &MacroNameTok, const MacroInfo* MI,
188                             SourceRange Range) {
189   }
190
191   /// \brief Hook called whenever a macro definition is seen.
192   virtual void MacroDefined(const Token &MacroNameTok, const MacroInfo *MI) {
193   }
194
195   /// \brief Hook called whenever a macro \#undef is seen.
196   ///
197   /// MI is released immediately following this callback.
198   virtual void MacroUndefined(const Token &MacroNameTok, const MacroInfo *MI) {
199   }
200   
201   /// \brief Hook called whenever the 'defined' operator is seen.
202   virtual void Defined(const Token &MacroNameTok) {
203   }
204   
205   /// \brief Hook called when a source range is skipped.
206   /// \param Range The SourceRange that was skipped. The range begins at the
207   /// \#if/\#else directive and ends after the \#endif/\#else directive.
208   virtual void SourceRangeSkipped(SourceRange Range) {
209   }
210
211   /// \brief Hook called whenever an \#if is seen.
212   /// \param Loc the source location of the directive.
213   /// \param ConditionRange The SourceRange of the expression being tested.
214   ///
215   // FIXME: better to pass in a list (or tree!) of Tokens.
216   virtual void If(SourceLocation Loc, SourceRange ConditionRange) {
217   }
218
219   /// \brief Hook called whenever an \#elif is seen.
220   /// \param Loc the source location of the directive.
221   /// \param ConditionRange The SourceRange of the expression being tested.
222   /// \param IfLoc the source location of the \#if/\#ifdef/\#ifndef directive.
223   // FIXME: better to pass in a list (or tree!) of Tokens.
224   virtual void Elif(SourceLocation Loc, SourceRange ConditionRange,
225                     SourceLocation IfLoc) {
226   }
227
228   /// \brief Hook called whenever an \#ifdef is seen.
229   /// \param Loc the source location of the directive.
230   /// \param MacroNameTok Information on the token being tested.
231   virtual void Ifdef(SourceLocation Loc, const Token &MacroNameTok) {
232   }
233
234   /// \brief Hook called whenever an \#ifndef is seen.
235   /// \param Loc the source location of the directive.
236   /// \param MacroNameTok Information on the token being tested.
237   virtual void Ifndef(SourceLocation Loc, const Token &MacroNameTok) {
238   }
239
240   /// \brief Hook called whenever an \#else is seen.
241   /// \param Loc the source location of the directive.
242   /// \param IfLoc the source location of the \#if/\#ifdef/\#ifndef directive.
243   virtual void Else(SourceLocation Loc, SourceLocation IfLoc) {
244   }
245
246   /// \brief Hook called whenever an \#endif is seen.
247   /// \param Loc the source location of the directive.
248   /// \param IfLoc the source location of the \#if/\#ifdef/\#ifndef directive.
249   virtual void Endif(SourceLocation Loc, SourceLocation IfLoc) {
250   }
251 };
252
253 /// \brief Simple wrapper class for chaining callbacks.
254 class PPChainedCallbacks : public PPCallbacks {
255   virtual void anchor();
256   PPCallbacks *First, *Second;
257
258 public:
259   PPChainedCallbacks(PPCallbacks *_First, PPCallbacks *_Second)
260     : First(_First), Second(_Second) {}
261   ~PPChainedCallbacks() {
262     delete Second;
263     delete First;
264   }
265
266   virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason,
267                            SrcMgr::CharacteristicKind FileType,
268                            FileID PrevFID) {
269     First->FileChanged(Loc, Reason, FileType, PrevFID);
270     Second->FileChanged(Loc, Reason, FileType, PrevFID);
271   }
272
273   virtual void FileSkipped(const FileEntry &ParentFile,
274                            const Token &FilenameTok,
275                            SrcMgr::CharacteristicKind FileType) {
276     First->FileSkipped(ParentFile, FilenameTok, FileType);
277     Second->FileSkipped(ParentFile, FilenameTok, FileType);
278   }
279
280   virtual bool FileNotFound(StringRef FileName,
281                             SmallVectorImpl<char> &RecoveryPath) {
282     return First->FileNotFound(FileName, RecoveryPath) ||
283            Second->FileNotFound(FileName, RecoveryPath);
284   }
285
286   virtual void InclusionDirective(SourceLocation HashLoc,
287                                   const Token &IncludeTok,
288                                   StringRef FileName,
289                                   bool IsAngled,
290                                   CharSourceRange FilenameRange,
291                                   const FileEntry *File,
292                                   StringRef SearchPath,
293                                   StringRef RelativePath,
294                                   const Module *Imported) {
295     First->InclusionDirective(HashLoc, IncludeTok, FileName, IsAngled,
296                               FilenameRange, File, SearchPath, RelativePath,
297                               Imported);
298     Second->InclusionDirective(HashLoc, IncludeTok, FileName, IsAngled,
299                                FilenameRange, File, SearchPath, RelativePath,
300                                Imported);
301   }
302
303   virtual void moduleImport(SourceLocation ImportLoc,
304                             ModuleIdPath Path,
305                             const Module *Imported) {
306     First->moduleImport(ImportLoc, Path, Imported);
307     Second->moduleImport(ImportLoc, Path, Imported);
308   }
309
310   virtual void EndOfMainFile() {
311     First->EndOfMainFile();
312     Second->EndOfMainFile();
313   }
314
315   virtual void Ident(SourceLocation Loc, const std::string &str) {
316     First->Ident(Loc, str);
317     Second->Ident(Loc, str);
318   }
319
320   virtual void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind,
321                              const std::string &Str) {
322     First->PragmaComment(Loc, Kind, Str);
323     Second->PragmaComment(Loc, Kind, Str);
324   }
325
326   virtual void PragmaMessage(SourceLocation Loc, StringRef Str) {
327     First->PragmaMessage(Loc, Str);
328     Second->PragmaMessage(Loc, Str);
329   }
330
331   virtual void PragmaDiagnosticPush(SourceLocation Loc,
332                                     StringRef Namespace) {
333     First->PragmaDiagnosticPush(Loc, Namespace);
334     Second->PragmaDiagnosticPush(Loc, Namespace);
335   }
336
337   virtual void PragmaDiagnosticPop(SourceLocation Loc,
338                                     StringRef Namespace) {
339     First->PragmaDiagnosticPop(Loc, Namespace);
340     Second->PragmaDiagnosticPop(Loc, Namespace);
341   }
342
343   virtual void PragmaDiagnostic(SourceLocation Loc, StringRef Namespace,
344                                 diag::Mapping mapping, StringRef Str) {
345     First->PragmaDiagnostic(Loc, Namespace, mapping, Str);
346     Second->PragmaDiagnostic(Loc, Namespace, mapping, Str);
347   }
348
349   virtual void MacroExpands(const Token &MacroNameTok, const MacroInfo* MI,
350                             SourceRange Range) {
351     First->MacroExpands(MacroNameTok, MI, Range);
352     Second->MacroExpands(MacroNameTok, MI, Range);
353   }
354
355   virtual void MacroDefined(const Token &MacroNameTok, const MacroInfo *MI) {
356     First->MacroDefined(MacroNameTok, MI);
357     Second->MacroDefined(MacroNameTok, MI);
358   }
359
360   virtual void MacroUndefined(const Token &MacroNameTok, const MacroInfo *MI) {
361     First->MacroUndefined(MacroNameTok, MI);
362     Second->MacroUndefined(MacroNameTok, MI);
363   }
364
365   virtual void Defined(const Token &MacroNameTok) {
366     First->Defined(MacroNameTok);
367     Second->Defined(MacroNameTok);
368   }
369
370   virtual void SourceRangeSkipped(SourceRange Range) {
371     First->SourceRangeSkipped(Range);
372     Second->SourceRangeSkipped(Range);
373   }
374
375   /// \brief Hook called whenever an \#if is seen.
376   virtual void If(SourceLocation Loc, SourceRange ConditionRange) {
377     First->If(Loc, ConditionRange);
378     Second->If(Loc, ConditionRange);
379   }
380
381   /// \brief Hook called whenever an \#if is seen.
382   virtual void Elif(SourceLocation Loc, SourceRange ConditionRange,
383                     SourceLocation IfLoc) {
384     First->Elif(Loc, ConditionRange, IfLoc);
385     Second->Elif(Loc, ConditionRange, IfLoc);
386   }
387
388   /// \brief Hook called whenever an \#ifdef is seen.
389   virtual void Ifdef(SourceLocation Loc, const Token &MacroNameTok) {
390     First->Ifdef(Loc, MacroNameTok);
391     Second->Ifdef(Loc, MacroNameTok);
392   }
393
394   /// \brief Hook called whenever an \#ifndef is seen.
395   virtual void Ifndef(SourceLocation Loc, const Token &MacroNameTok) {
396     First->Ifndef(Loc, MacroNameTok);
397     Second->Ifndef(Loc, MacroNameTok);
398   }
399
400   /// \brief Hook called whenever an \#else is seen.
401   virtual void Else(SourceLocation Loc, SourceLocation IfLoc) {
402     First->Else(Loc, IfLoc);
403     Second->Else(Loc, IfLoc);
404   }
405
406   /// \brief Hook called whenever an \#endif is seen.
407   virtual void Endif(SourceLocation Loc, SourceLocation IfLoc) {
408     First->Endif(Loc, IfLoc);
409     Second->Endif(Loc, IfLoc);
410   }
411 };
412
413 }  // end namespace clang
414
415 #endif