1 //===--- PPCallbacks.h - Callbacks for Preprocessor actions -----*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines the PPCallbacks interface.
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_CLANG_LEX_PPCALLBACKS_H
15 #define LLVM_CLANG_LEX_PPCALLBACKS_H
17 #include "clang/Lex/DirectoryLookup.h"
18 #include "clang/Basic/SourceLocation.h"
19 #include "clang/Basic/DiagnosticIDs.h"
20 #include "llvm/ADT/StringRef.h"
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.
34 virtual ~PPCallbacks();
36 enum FileChangeReason {
37 EnterFile, ExitFile, SystemHeaderPragma, RenameFile
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).
46 /// \param PrevFID the file that was exited if \arg Reason is ExitFile.
47 virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason,
48 SrcMgr::CharacteristicKind FileType,
49 FileID PrevFID = FileID()) {
52 /// FileSkipped - This callback is invoked whenever a source file is
53 /// skipped as the result of header guard optimization. ParentFile
54 /// is the file that #includes the skipped file. FilenameTok is the
55 /// token in ParentFile that indicates the skipped file.
56 virtual void FileSkipped(const FileEntry &ParentFile,
57 const Token &FilenameTok,
58 SrcMgr::CharacteristicKind FileType) {
61 /// FileNotFound - This callback is invoked whenever an inclusion directive
62 /// results in a file-not-found error.
64 /// \param FileName The name of the file being included, as written in the
67 /// \param RecoveryPath If this client indicates that it can recover from
68 /// this missing file, the client should set this as an additional header
71 /// \returns true to indicate that the preprocessor should attempt to recover
72 /// by adding \p RecoveryPath as a header search path.
73 virtual bool FileNotFound(StringRef FileName,
74 SmallVectorImpl<char> &RecoveryPath) {
78 /// \brief This callback is invoked whenever an inclusion directive of
79 /// any kind (\c #include, \c #import, etc.) has been processed, regardless
80 /// of whether the inclusion will actually result in an inclusion.
82 /// \param HashLoc The location of the '#' that starts the inclusion
85 /// \param IncludeTok The token that indicates the kind of inclusion
86 /// directive, e.g., 'include' or 'import'.
88 /// \param FileName The name of the file being included, as written in the
91 /// \param IsAngled Whether the file name was enclosed in angle brackets;
92 /// otherwise, it was enclosed in quotes.
94 /// \param File The actual file that may be included by this inclusion
97 /// \param EndLoc The location of the last token within the inclusion
100 /// \param SearchPath Contains the search path which was used to find the file
101 /// in the file system. If the file was found via an absolute include path,
102 /// SearchPath will be empty. For framework includes, the SearchPath and
103 /// RelativePath will be split up. For example, if an include of "Some/Some.h"
104 /// is found via the framework path
105 /// "path/to/Frameworks/Some.framework/Headers/Some.h", SearchPath will be
106 /// "path/to/Frameworks/Some.framework/Headers" and RelativePath will be
109 /// \param RelativePath The path relative to SearchPath, at which the include
110 /// file was found. This is equal to FileName except for framework includes.
111 virtual void InclusionDirective(SourceLocation HashLoc,
112 const Token &IncludeTok,
115 const FileEntry *File,
116 SourceLocation EndLoc,
117 StringRef SearchPath,
118 StringRef RelativePath) {
121 /// EndOfMainFile - This callback is invoked when the end of the main file is
122 /// reach, no subsequent callbacks will be made.
123 virtual void EndOfMainFile() {
126 /// Ident - This callback is invoked when a #ident or #sccs directive is read.
127 /// \param Loc The location of the directive.
128 /// \param str The text of the directive.
130 virtual void Ident(SourceLocation Loc, const std::string &str) {
133 /// PragmaComment - This callback is invoked when a #pragma comment directive
136 virtual void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind,
137 const std::string &Str) {
140 /// PragmaMessage - This callback is invoked when a #pragma message directive
142 /// \param Loc The location of the message directive.
143 /// \param str The text of the message directive.
145 virtual void PragmaMessage(SourceLocation Loc, StringRef Str) {
148 /// PragmaDiagnosticPush - This callback is invoked when a
149 /// #pragma gcc dianostic push directive is read.
150 virtual void PragmaDiagnosticPush(SourceLocation Loc,
151 StringRef Namespace) {
154 /// PragmaDiagnosticPop - This callback is invoked when a
155 /// #pragma gcc dianostic pop directive is read.
156 virtual void PragmaDiagnosticPop(SourceLocation Loc,
157 StringRef Namespace) {
160 /// PragmaDiagnostic - This callback is invoked when a
161 /// #pragma gcc dianostic directive is read.
162 virtual void PragmaDiagnostic(SourceLocation Loc, StringRef Namespace,
163 diag::Mapping mapping, StringRef Str) {
166 /// MacroExpands - This is called by
167 /// Preprocessor::HandleMacroExpandedIdentifier when a macro invocation is
169 virtual void MacroExpands(const Token &MacroNameTok, const MacroInfo* MI,
173 /// MacroDefined - This hook is called whenever a macro definition is seen.
174 virtual void MacroDefined(const Token &MacroNameTok, const MacroInfo *MI) {
177 /// MacroUndefined - This hook is called whenever a macro #undef is seen.
178 /// MI is released immediately following this callback.
179 virtual void MacroUndefined(const Token &MacroNameTok, const MacroInfo *MI) {
182 /// Defined - This hook is called whenever the 'defined' operator is seen.
183 virtual void Defined(const Token &MacroNameTok) {
186 /// SourceRangeSkipped - This hook is called when a source range is skipped.
187 /// \param Range The SourceRange that was skipped. The range begins at the
188 /// #if/#else directive and ends after the #endif/#else directive.
189 virtual void SourceRangeSkipped(SourceRange Range) {
192 /// If -- This hook is called whenever an #if is seen.
193 /// \param Loc the source location of the directive.
194 /// \param ConditionRange The SourceRange of the expression being tested.
195 // FIXME: better to pass in a list (or tree!) of Tokens.
196 virtual void If(SourceLocation Loc, SourceRange ConditionRange) {
199 /// Elif -- This hook is called whenever an #elif is seen.
200 /// \param Loc the source location of the directive.
201 /// \param ConditionRange The SourceRange of the expression being tested.
202 /// \param IfLoc the source location of the #if/#ifdef/#ifndef directive.
203 // FIXME: better to pass in a list (or tree!) of Tokens.
204 virtual void Elif(SourceLocation Loc, SourceRange ConditionRange,
205 SourceLocation IfLoc) {
208 /// Ifdef -- This hook is called whenever an #ifdef is seen.
209 /// \param Loc the source location of the directive.
210 /// \param II Information on the token being tested.
211 virtual void Ifdef(SourceLocation Loc, const Token &MacroNameTok) {
214 /// Ifndef -- This hook is called whenever an #ifndef is seen.
215 /// \param Loc the source location of the directive.
216 /// \param II Information on the token being tested.
217 virtual void Ifndef(SourceLocation Loc, const Token &MacroNameTok) {
220 /// Else -- This hook is called whenever an #else is seen.
221 /// \param Loc the source location of the directive.
222 /// \param IfLoc the source location of the #if/#ifdef/#ifndef directive.
223 virtual void Else(SourceLocation Loc, SourceLocation IfLoc) {
226 /// Endif -- This hook is called whenever an #endif is seen.
227 /// \param Loc the source location of the directive.
228 /// \param IfLoc the source location of the #if/#ifdef/#ifndef directive.
229 virtual void Endif(SourceLocation Loc, SourceLocation IfLoc) {
233 /// PPChainedCallbacks - Simple wrapper class for chaining callbacks.
234 class PPChainedCallbacks : public PPCallbacks {
235 virtual void anchor();
236 PPCallbacks *First, *Second;
239 PPChainedCallbacks(PPCallbacks *_First, PPCallbacks *_Second)
240 : First(_First), Second(_Second) {}
241 ~PPChainedCallbacks() {
246 virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason,
247 SrcMgr::CharacteristicKind FileType,
249 First->FileChanged(Loc, Reason, FileType, PrevFID);
250 Second->FileChanged(Loc, Reason, FileType, PrevFID);
253 virtual void FileSkipped(const FileEntry &ParentFile,
254 const Token &FilenameTok,
255 SrcMgr::CharacteristicKind FileType) {
256 First->FileSkipped(ParentFile, FilenameTok, FileType);
257 Second->FileSkipped(ParentFile, FilenameTok, FileType);
260 virtual bool FileNotFound(StringRef FileName,
261 SmallVectorImpl<char> &RecoveryPath) {
262 return First->FileNotFound(FileName, RecoveryPath) ||
263 Second->FileNotFound(FileName, RecoveryPath);
266 virtual void InclusionDirective(SourceLocation HashLoc,
267 const Token &IncludeTok,
270 const FileEntry *File,
271 SourceLocation EndLoc,
272 StringRef SearchPath,
273 StringRef RelativePath) {
274 First->InclusionDirective(HashLoc, IncludeTok, FileName, IsAngled, File,
275 EndLoc, SearchPath, RelativePath);
276 Second->InclusionDirective(HashLoc, IncludeTok, FileName, IsAngled, File,
277 EndLoc, SearchPath, RelativePath);
280 virtual void EndOfMainFile() {
281 First->EndOfMainFile();
282 Second->EndOfMainFile();
285 virtual void Ident(SourceLocation Loc, const std::string &str) {
286 First->Ident(Loc, str);
287 Second->Ident(Loc, str);
290 virtual void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind,
291 const std::string &Str) {
292 First->PragmaComment(Loc, Kind, Str);
293 Second->PragmaComment(Loc, Kind, Str);
296 virtual void PragmaMessage(SourceLocation Loc, StringRef Str) {
297 First->PragmaMessage(Loc, Str);
298 Second->PragmaMessage(Loc, Str);
301 virtual void PragmaDiagnosticPush(SourceLocation Loc,
302 StringRef Namespace) {
303 First->PragmaDiagnosticPush(Loc, Namespace);
304 Second->PragmaDiagnosticPush(Loc, Namespace);
307 virtual void PragmaDiagnosticPop(SourceLocation Loc,
308 StringRef Namespace) {
309 First->PragmaDiagnosticPop(Loc, Namespace);
310 Second->PragmaDiagnosticPop(Loc, Namespace);
313 virtual void PragmaDiagnostic(SourceLocation Loc, StringRef Namespace,
314 diag::Mapping mapping, StringRef Str) {
315 First->PragmaDiagnostic(Loc, Namespace, mapping, Str);
316 Second->PragmaDiagnostic(Loc, Namespace, mapping, Str);
319 virtual void MacroExpands(const Token &MacroNameTok, const MacroInfo* MI,
321 First->MacroExpands(MacroNameTok, MI, Range);
322 Second->MacroExpands(MacroNameTok, MI, Range);
325 virtual void MacroDefined(const Token &MacroNameTok, const MacroInfo *MI) {
326 First->MacroDefined(MacroNameTok, MI);
327 Second->MacroDefined(MacroNameTok, MI);
330 virtual void MacroUndefined(const Token &MacroNameTok, const MacroInfo *MI) {
331 First->MacroUndefined(MacroNameTok, MI);
332 Second->MacroUndefined(MacroNameTok, MI);
335 virtual void Defined(const Token &MacroNameTok) {
336 First->Defined(MacroNameTok);
337 Second->Defined(MacroNameTok);
340 virtual void SourceRangeSkipped(SourceRange Range) {
341 First->SourceRangeSkipped(Range);
342 Second->SourceRangeSkipped(Range);
345 /// If -- This hook is called whenever an #if is seen.
346 virtual void If(SourceLocation Loc, SourceRange ConditionRange) {
347 First->If(Loc, ConditionRange);
348 Second->If(Loc, ConditionRange);
351 /// Elif -- This hook is called whenever an #if is seen.
352 virtual void Elif(SourceLocation Loc, SourceRange ConditionRange,
353 SourceLocation IfLoc) {
354 First->Elif(Loc, ConditionRange, IfLoc);
355 Second->Elif(Loc, ConditionRange, IfLoc);
358 /// Ifdef -- This hook is called whenever an #ifdef is seen.
359 virtual void Ifdef(SourceLocation Loc, const Token &MacroNameTok) {
360 First->Ifdef(Loc, MacroNameTok);
361 Second->Ifdef(Loc, MacroNameTok);
364 /// Ifndef -- This hook is called whenever an #ifndef is seen.
365 virtual void Ifndef(SourceLocation Loc, const Token &MacroNameTok) {
366 First->Ifndef(Loc, MacroNameTok);
367 Second->Ifndef(Loc, MacroNameTok);
370 /// Else -- This hook is called whenever an #else is seen.
371 virtual void Else(SourceLocation Loc, SourceLocation IfLoc) {
372 First->Else(Loc, IfLoc);
373 Second->Else(Loc, IfLoc);
376 /// Endif -- This hook is called whenever an #endif is seen.
377 virtual void Endif(SourceLocation Loc, SourceLocation IfLoc) {
378 First->Endif(Loc, IfLoc);
379 Second->Endif(Loc, IfLoc);
383 } // end namespace clang