clang API Documentation

PPCallbacks.h
Go to the documentation of this file.
00001 //===--- PPCallbacks.h - Callbacks for Preprocessor actions -----*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 //  This file defines the PPCallbacks interface.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #ifndef LLVM_CLANG_LEX_PPCALLBACKS_H
00015 #define LLVM_CLANG_LEX_PPCALLBACKS_H
00016 
00017 #include "clang/Lex/DirectoryLookup.h"
00018 #include "clang/Basic/SourceLocation.h"
00019 #include "clang/Basic/DiagnosticIDs.h"
00020 #include "llvm/ADT/StringRef.h"
00021 #include <string>
00022 
00023 namespace clang {
00024   class SourceLocation;
00025   class Token;
00026   class IdentifierInfo;
00027   class MacroInfo;
00028 
00029 /// PPCallbacks - This interface provides a way to observe the actions of the
00030 /// preprocessor as it does its thing.  Clients can define their hooks here to
00031 /// implement preprocessor level tools.
00032 class PPCallbacks {
00033 public:
00034   virtual ~PPCallbacks();
00035 
00036   enum FileChangeReason {
00037     EnterFile, ExitFile, SystemHeaderPragma, RenameFile
00038   };
00039 
00040   /// FileChanged - This callback is invoked whenever a source file is
00041   /// entered or exited.  The SourceLocation indicates the new location, and
00042   /// EnteringFile indicates whether this is because we are entering a new
00043   /// #include'd file (when true) or whether we're exiting one because we ran
00044   /// off the end (when false).
00045   ///
00046   /// \param PrevFID the file that was exited if \arg Reason is ExitFile. 
00047   virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason,
00048                            SrcMgr::CharacteristicKind FileType,
00049                            FileID PrevFID = FileID()) {
00050   }
00051 
00052   /// FileSkipped - This callback is invoked whenever a source file is
00053   /// skipped as the result of header guard optimization.  ParentFile
00054   /// is the file that #includes the skipped file.  FilenameTok is the
00055   /// token in ParentFile that indicates the skipped file.
00056   virtual void FileSkipped(const FileEntry &ParentFile,
00057                            const Token &FilenameTok,
00058                            SrcMgr::CharacteristicKind FileType) {
00059   }
00060 
00061   /// FileNotFound - This callback is invoked whenever an inclusion directive
00062   /// results in a file-not-found error.
00063   ///
00064   /// \param FileName The name of the file being included, as written in the 
00065   /// source code.
00066   ///
00067   /// \param RecoveryPath If this client indicates that it can recover from 
00068   /// this missing file, the client should set this as an additional header
00069   /// search patch.
00070   ///
00071   /// \returns true to indicate that the preprocessor should attempt to recover
00072   /// by adding \p RecoveryPath as a header search path.
00073   virtual bool FileNotFound(StringRef FileName,
00074                             SmallVectorImpl<char> &RecoveryPath) {
00075     return false;
00076   }
00077 
00078   /// \brief This callback is invoked whenever an inclusion directive of
00079   /// any kind (\c #include, \c #import, etc.) has been processed, regardless
00080   /// of whether the inclusion will actually result in an inclusion.
00081   ///
00082   /// \param HashLoc The location of the '#' that starts the inclusion 
00083   /// directive.
00084   ///
00085   /// \param IncludeTok The token that indicates the kind of inclusion 
00086   /// directive, e.g., 'include' or 'import'.
00087   ///
00088   /// \param FileName The name of the file being included, as written in the 
00089   /// source code.
00090   ///
00091   /// \param IsAngled Whether the file name was enclosed in angle brackets;
00092   /// otherwise, it was enclosed in quotes.
00093   ///
00094   /// \param File The actual file that may be included by this inclusion 
00095   /// directive.
00096   ///
00097   /// \param EndLoc The location of the last token within the inclusion
00098   /// directive.
00099   ///
00100   /// \param SearchPath Contains the search path which was used to find the file
00101   /// in the file system. If the file was found via an absolute include path,
00102   /// SearchPath will be empty. For framework includes, the SearchPath and
00103   /// RelativePath will be split up. For example, if an include of "Some/Some.h"
00104   /// is found via the framework path
00105   /// "path/to/Frameworks/Some.framework/Headers/Some.h", SearchPath will be
00106   /// "path/to/Frameworks/Some.framework/Headers" and RelativePath will be
00107   /// "Some.h".
00108   ///
00109   /// \param RelativePath The path relative to SearchPath, at which the include
00110   /// file was found. This is equal to FileName except for framework includes.
00111   virtual void InclusionDirective(SourceLocation HashLoc,
00112                                   const Token &IncludeTok,
00113                                   StringRef FileName,
00114                                   bool IsAngled,
00115                                   const FileEntry *File,
00116                                   SourceLocation EndLoc,
00117                                   StringRef SearchPath,
00118                                   StringRef RelativePath) {
00119   }
00120 
00121   /// EndOfMainFile - This callback is invoked when the end of the main file is
00122   /// reach, no subsequent callbacks will be made.
00123   virtual void EndOfMainFile() {
00124   }
00125 
00126   /// Ident - This callback is invoked when a #ident or #sccs directive is read.
00127   /// \param Loc The location of the directive.
00128   /// \param str The text of the directive.
00129   ///
00130   virtual void Ident(SourceLocation Loc, const std::string &str) {
00131   }
00132 
00133   /// PragmaComment - This callback is invoked when a #pragma comment directive
00134   /// is read.
00135   ///
00136   virtual void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind,
00137                              const std::string &Str) {
00138   }
00139 
00140   /// PragmaMessage - This callback is invoked when a #pragma message directive
00141   /// is read.
00142   /// \param Loc The location of the message directive.
00143   /// \param str The text of the message directive.
00144   ///
00145   virtual void PragmaMessage(SourceLocation Loc, StringRef Str) {
00146   }
00147 
00148   /// PragmaDiagnosticPush - This callback is invoked when a
00149   /// #pragma gcc dianostic push directive is read.
00150   virtual void PragmaDiagnosticPush(SourceLocation Loc,
00151                                     StringRef Namespace) {
00152   }
00153 
00154   /// PragmaDiagnosticPop - This callback is invoked when a
00155   /// #pragma gcc dianostic pop directive is read.
00156   virtual void PragmaDiagnosticPop(SourceLocation Loc,
00157                                    StringRef Namespace) {
00158   }
00159 
00160   /// PragmaDiagnostic - This callback is invoked when a
00161   /// #pragma gcc dianostic directive is read.
00162   virtual void PragmaDiagnostic(SourceLocation Loc, StringRef Namespace,
00163                                 diag::Mapping mapping, StringRef Str) {
00164   }
00165 
00166   /// MacroExpands - This is called by
00167   /// Preprocessor::HandleMacroExpandedIdentifier when a macro invocation is
00168   /// found.
00169   virtual void MacroExpands(const Token &MacroNameTok, const MacroInfo* MI,
00170                             SourceRange Range) {
00171   }
00172 
00173   /// MacroDefined - This hook is called whenever a macro definition is seen.
00174   virtual void MacroDefined(const Token &MacroNameTok, const MacroInfo *MI) {
00175   }
00176 
00177   /// MacroUndefined - This hook is called whenever a macro #undef is seen.
00178   /// MI is released immediately following this callback.
00179   virtual void MacroUndefined(const Token &MacroNameTok, const MacroInfo *MI) {
00180   }
00181   
00182   /// Defined - This hook is called whenever the 'defined' operator is seen.
00183   virtual void Defined(const Token &MacroNameTok) {
00184   }
00185   
00186   /// SourceRangeSkipped - This hook is called when a source range is skipped.
00187   /// \param Range The SourceRange that was skipped. The range begins at the
00188   /// #if/#else directive and ends after the #endif/#else directive.
00189   virtual void SourceRangeSkipped(SourceRange Range) {
00190   }
00191 
00192   /// If -- This hook is called whenever an #if is seen.
00193   /// \param Loc the source location of the directive.
00194   /// \param ConditionRange The SourceRange of the expression being tested.
00195   // FIXME: better to pass in a list (or tree!) of Tokens.
00196   virtual void If(SourceLocation Loc, SourceRange ConditionRange) {
00197   }
00198 
00199   /// Elif -- This hook is called whenever an #elif is seen.
00200   /// \param Loc the source location of the directive.
00201   /// \param ConditionRange The SourceRange of the expression being tested.
00202   /// \param IfLoc the source location of the #if/#ifdef/#ifndef directive.
00203   // FIXME: better to pass in a list (or tree!) of Tokens.
00204   virtual void Elif(SourceLocation Loc, SourceRange ConditionRange,
00205                     SourceLocation IfLoc) {
00206   }
00207 
00208   /// Ifdef -- This hook is called whenever an #ifdef is seen.
00209   /// \param Loc the source location of the directive.
00210   /// \param II Information on the token being tested.
00211   virtual void Ifdef(SourceLocation Loc, const Token &MacroNameTok) {
00212   }
00213 
00214   /// Ifndef -- This hook is called whenever an #ifndef is seen.
00215   /// \param Loc the source location of the directive.
00216   /// \param II Information on the token being tested.
00217   virtual void Ifndef(SourceLocation Loc, const Token &MacroNameTok) {
00218   }
00219 
00220   /// Else -- This hook is called whenever an #else is seen.
00221   /// \param Loc the source location of the directive.
00222   /// \param IfLoc the source location of the #if/#ifdef/#ifndef directive.
00223   virtual void Else(SourceLocation Loc, SourceLocation IfLoc) {
00224   }
00225 
00226   /// Endif -- This hook is called whenever an #endif is seen.
00227   /// \param Loc the source location of the directive.
00228   /// \param IfLoc the source location of the #if/#ifdef/#ifndef directive.
00229   virtual void Endif(SourceLocation Loc, SourceLocation IfLoc) {
00230   }
00231 };
00232 
00233 /// PPChainedCallbacks - Simple wrapper class for chaining callbacks.
00234 class PPChainedCallbacks : public PPCallbacks {
00235   virtual void anchor();
00236   PPCallbacks *First, *Second;
00237 
00238 public:
00239   PPChainedCallbacks(PPCallbacks *_First, PPCallbacks *_Second)
00240     : First(_First), Second(_Second) {}
00241   ~PPChainedCallbacks() {
00242     delete Second;
00243     delete First;
00244   }
00245 
00246   virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason,
00247                            SrcMgr::CharacteristicKind FileType,
00248                            FileID PrevFID) {
00249     First->FileChanged(Loc, Reason, FileType, PrevFID);
00250     Second->FileChanged(Loc, Reason, FileType, PrevFID);
00251   }
00252 
00253   virtual void FileSkipped(const FileEntry &ParentFile,
00254                            const Token &FilenameTok,
00255                            SrcMgr::CharacteristicKind FileType) {
00256     First->FileSkipped(ParentFile, FilenameTok, FileType);
00257     Second->FileSkipped(ParentFile, FilenameTok, FileType);
00258   }
00259 
00260   virtual bool FileNotFound(StringRef FileName,
00261                             SmallVectorImpl<char> &RecoveryPath) {
00262     return First->FileNotFound(FileName, RecoveryPath) ||
00263            Second->FileNotFound(FileName, RecoveryPath);
00264   }
00265 
00266   virtual void InclusionDirective(SourceLocation HashLoc,
00267                                   const Token &IncludeTok,
00268                                   StringRef FileName,
00269                                   bool IsAngled,
00270                                   const FileEntry *File,
00271                                   SourceLocation EndLoc,
00272                                   StringRef SearchPath,
00273                                   StringRef RelativePath) {
00274     First->InclusionDirective(HashLoc, IncludeTok, FileName, IsAngled, File,
00275                               EndLoc, SearchPath, RelativePath);
00276     Second->InclusionDirective(HashLoc, IncludeTok, FileName, IsAngled, File,
00277                                EndLoc, SearchPath, RelativePath);
00278   }
00279 
00280   virtual void EndOfMainFile() {
00281     First->EndOfMainFile();
00282     Second->EndOfMainFile();
00283   }
00284 
00285   virtual void Ident(SourceLocation Loc, const std::string &str) {
00286     First->Ident(Loc, str);
00287     Second->Ident(Loc, str);
00288   }
00289 
00290   virtual void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind,
00291                              const std::string &Str) {
00292     First->PragmaComment(Loc, Kind, Str);
00293     Second->PragmaComment(Loc, Kind, Str);
00294   }
00295 
00296   virtual void PragmaMessage(SourceLocation Loc, StringRef Str) {
00297     First->PragmaMessage(Loc, Str);
00298     Second->PragmaMessage(Loc, Str);
00299   }
00300 
00301   virtual void PragmaDiagnosticPush(SourceLocation Loc,
00302                                     StringRef Namespace) {
00303     First->PragmaDiagnosticPush(Loc, Namespace);
00304     Second->PragmaDiagnosticPush(Loc, Namespace);
00305   }
00306 
00307   virtual void PragmaDiagnosticPop(SourceLocation Loc,
00308                                     StringRef Namespace) {
00309     First->PragmaDiagnosticPop(Loc, Namespace);
00310     Second->PragmaDiagnosticPop(Loc, Namespace);
00311   }
00312 
00313   virtual void PragmaDiagnostic(SourceLocation Loc, StringRef Namespace,
00314                                 diag::Mapping mapping, StringRef Str) {
00315     First->PragmaDiagnostic(Loc, Namespace, mapping, Str);
00316     Second->PragmaDiagnostic(Loc, Namespace, mapping, Str);
00317   }
00318 
00319   virtual void MacroExpands(const Token &MacroNameTok, const MacroInfo* MI,
00320                             SourceRange Range) {
00321     First->MacroExpands(MacroNameTok, MI, Range);
00322     Second->MacroExpands(MacroNameTok, MI, Range);
00323   }
00324 
00325   virtual void MacroDefined(const Token &MacroNameTok, const MacroInfo *MI) {
00326     First->MacroDefined(MacroNameTok, MI);
00327     Second->MacroDefined(MacroNameTok, MI);
00328   }
00329 
00330   virtual void MacroUndefined(const Token &MacroNameTok, const MacroInfo *MI) {
00331     First->MacroUndefined(MacroNameTok, MI);
00332     Second->MacroUndefined(MacroNameTok, MI);
00333   }
00334 
00335   virtual void Defined(const Token &MacroNameTok) {
00336     First->Defined(MacroNameTok);
00337     Second->Defined(MacroNameTok);
00338   }
00339 
00340   virtual void SourceRangeSkipped(SourceRange Range) {
00341     First->SourceRangeSkipped(Range);
00342     Second->SourceRangeSkipped(Range);
00343   }
00344 
00345   /// If -- This hook is called whenever an #if is seen.
00346   virtual void If(SourceLocation Loc, SourceRange ConditionRange) {
00347     First->If(Loc, ConditionRange);
00348     Second->If(Loc, ConditionRange);
00349   }
00350 
00351   /// Elif -- This hook is called whenever an #if is seen.
00352   virtual void Elif(SourceLocation Loc, SourceRange ConditionRange,
00353                     SourceLocation IfLoc) {
00354     First->Elif(Loc, ConditionRange, IfLoc);
00355     Second->Elif(Loc, ConditionRange, IfLoc);
00356   }
00357 
00358   /// Ifdef -- This hook is called whenever an #ifdef is seen.
00359   virtual void Ifdef(SourceLocation Loc, const Token &MacroNameTok) {
00360     First->Ifdef(Loc, MacroNameTok);
00361     Second->Ifdef(Loc, MacroNameTok);
00362   }
00363 
00364   /// Ifndef -- This hook is called whenever an #ifndef is seen.
00365   virtual void Ifndef(SourceLocation Loc, const Token &MacroNameTok) {
00366     First->Ifndef(Loc, MacroNameTok);
00367     Second->Ifndef(Loc, MacroNameTok);
00368   }
00369 
00370   /// Else -- This hook is called whenever an #else is seen.
00371   virtual void Else(SourceLocation Loc, SourceLocation IfLoc) {
00372     First->Else(Loc, IfLoc);
00373     Second->Else(Loc, IfLoc);
00374   }
00375 
00376   /// Endif -- This hook is called whenever an #endif is seen.
00377   virtual void Endif(SourceLocation Loc, SourceLocation IfLoc) {
00378     First->Endif(Loc, IfLoc);
00379     Second->Endif(Loc, IfLoc);
00380   }
00381 };
00382 
00383 }  // end namespace clang
00384 
00385 #endif