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