PPCallbacks.h revision 6b4ff04dd22e7159887ea6c1bb8b1c01fc9c70a9
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 "clang/Basic/DiagnosticIDs.h" 20#include "llvm/ADT/StringRef.h" 21#include <string> 22 23namespace clang { 24 class SourceLocation; 25 class Token; 26 class IdentifierInfo; 27 class MacroInfo; 28 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. 32class PPCallbacks { 33public: 34 virtual ~PPCallbacks(); 35 36 enum FileChangeReason { 37 EnterFile, ExitFile, SystemHeaderPragma, RenameFile 38 }; 39 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). 45 virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason, 46 SrcMgr::CharacteristicKind FileType) { 47 } 48 49 /// FileSkipped - This callback is invoked whenever a source file is 50 /// skipped as the result of header guard optimization. ParentFile 51 /// is the file that #includes the skipped file. FilenameTok is the 52 /// token in ParentFile that indicates the skipped file. 53 virtual void FileSkipped(const FileEntry &ParentFile, 54 const Token &FilenameTok, 55 SrcMgr::CharacteristicKind FileType) { 56 } 57 58 /// \brief This callback is invoked whenever an inclusion directive of 59 /// any kind (\c #include, \c #import, etc.) has been processed, regardless 60 /// of whether the inclusion will actually result in an inclusion. 61 /// 62 /// \param HashLoc The location of the '#' that starts the inclusion 63 /// directive. 64 /// 65 /// \param IncludeTok The token that indicates the kind of inclusion 66 /// directive, e.g., 'include' or 'import'. 67 /// 68 /// \param FileName The name of the file being included, as written in the 69 /// source code. 70 /// 71 /// \param IsAngled Whether the file name was enclosed in angle brackets; 72 /// otherwise, it was enclosed in quotes. 73 /// 74 /// \param File The actual file that may be included by this inclusion 75 /// directive. 76 /// 77 /// \param EndLoc The location of the last token within the inclusion 78 /// directive. 79 /// 80 /// \param SearchPath Contains the search path which was used to find the file 81 /// in the file system. If the file was found via an absolute include path, 82 /// SearchPath will be empty. For framework includes, the SearchPath and 83 /// RelativePath will be split up. For example, if an include of "Some/Some.h" 84 /// is found via the framework path 85 /// "path/to/Frameworks/Some.framework/Headers/Some.h", SearchPath will be 86 /// "path/to/Frameworks/Some.framework/Headers" and RelativePath will be 87 /// "Some.h". 88 /// 89 /// \param RelativePath The path relative to SearchPath, at which the include 90 /// file was found. This is equal to FileName except for framework includes. 91 virtual void InclusionDirective(SourceLocation HashLoc, 92 const Token &IncludeTok, 93 StringRef FileName, 94 bool IsAngled, 95 const FileEntry *File, 96 SourceLocation EndLoc, 97 StringRef SearchPath, 98 StringRef RelativePath) { 99 } 100 101 /// EndOfMainFile - This callback is invoked when the end of the main file is 102 /// reach, no subsequent callbacks will be made. 103 virtual void EndOfMainFile() { 104 } 105 106 /// Ident - This callback is invoked when a #ident or #sccs directive is read. 107 /// \param Loc The location of the directive. 108 /// \param str The text of the directive. 109 /// 110 virtual void Ident(SourceLocation Loc, const std::string &str) { 111 } 112 113 /// PragmaComment - This callback is invoked when a #pragma comment directive 114 /// is read. 115 /// 116 virtual void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind, 117 const std::string &Str) { 118 } 119 120 /// PragmaMessage - This callback is invoked when a #pragma message directive 121 /// is read. 122 /// \param Loc The location of the message directive. 123 /// \param str The text of the message directive. 124 /// 125 virtual void PragmaMessage(SourceLocation Loc, StringRef Str) { 126 } 127 128 /// PragmaDiagnosticPush - This callback is invoked when a 129 /// #pragma gcc dianostic push directive is read. 130 virtual void PragmaDiagnosticPush(SourceLocation Loc, 131 StringRef Namespace) { 132 } 133 134 /// PragmaDiagnosticPop - This callback is invoked when a 135 /// #pragma gcc dianostic pop directive is read. 136 virtual void PragmaDiagnosticPop(SourceLocation Loc, 137 StringRef Namespace) { 138 } 139 140 /// PragmaDiagnostic - This callback is invoked when a 141 /// #pragma gcc dianostic directive is read. 142 virtual void PragmaDiagnostic(SourceLocation Loc, StringRef Namespace, 143 diag::Mapping mapping, StringRef Str) { 144 } 145 146 /// MacroExpands - This is called by 147 /// Preprocessor::HandleMacroExpandedIdentifier when a macro invocation is 148 /// found. 149 virtual void MacroExpands(const Token &MacroNameTok, const MacroInfo* MI, 150 SourceRange Range) { 151 } 152 153 /// MacroDefined - This hook is called whenever a macro definition is seen. 154 virtual void MacroDefined(const Token &MacroNameTok, const MacroInfo *MI) { 155 } 156 157 /// MacroUndefined - This hook is called whenever a macro #undef is seen. 158 /// MI is released immediately following this callback. 159 virtual void MacroUndefined(const Token &MacroNameTok, const MacroInfo *MI) { 160 } 161 162 /// SourceRangeSkipped - This hook is called when a source range is skipped. 163 /// \param Range The SourceRange that was skipped. The range begins at the 164 /// #if/#else directive and ends after the #endif/#else directive. 165 virtual void SourceRangeSkipped(SourceRange Range) { 166 } 167 168 /// If -- This hook is called whenever an #if is seen. 169 /// \param Range The SourceRange of the expression being tested. 170 // FIXME: better to pass in a list (or tree!) of Tokens. 171 virtual void If(SourceRange Range) { 172 } 173 174 /// Elif -- This hook is called whenever an #elif is seen. 175 /// \param Range The SourceRange of the expression being tested. 176 // FIXME: better to pass in a list (or tree!) of Tokens. 177 virtual void Elif(SourceRange Range) { 178 } 179 180 /// Ifdef -- This hook is called whenever an #ifdef is seen. 181 /// \param Loc The location of the token being tested. 182 /// \param II Information on the token being tested. 183 virtual void Ifdef(const Token &MacroNameTok) { 184 } 185 186 /// Ifndef -- This hook is called whenever an #ifndef is seen. 187 /// \param Loc The location of the token being tested. 188 /// \param II Information on the token being tested. 189 virtual void Ifndef(const Token &MacroNameTok) { 190 } 191 192 /// Else -- This hook is called whenever an #else is seen. 193 virtual void Else() { 194 } 195 196 /// Endif -- This hook is called whenever an #endif is seen. 197 virtual void Endif() { 198 } 199}; 200 201/// PPChainedCallbacks - Simple wrapper class for chaining callbacks. 202class PPChainedCallbacks : public PPCallbacks { 203 PPCallbacks *First, *Second; 204 205public: 206 PPChainedCallbacks(PPCallbacks *_First, PPCallbacks *_Second) 207 : First(_First), Second(_Second) {} 208 ~PPChainedCallbacks() { 209 delete Second; 210 delete First; 211 } 212 213 virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason, 214 SrcMgr::CharacteristicKind FileType) { 215 First->FileChanged(Loc, Reason, FileType); 216 Second->FileChanged(Loc, Reason, FileType); 217 } 218 219 virtual void FileSkipped(const FileEntry &ParentFile, 220 const Token &FilenameTok, 221 SrcMgr::CharacteristicKind FileType) { 222 First->FileSkipped(ParentFile, FilenameTok, FileType); 223 Second->FileSkipped(ParentFile, FilenameTok, FileType); 224 } 225 226 virtual void InclusionDirective(SourceLocation HashLoc, 227 const Token &IncludeTok, 228 StringRef FileName, 229 bool IsAngled, 230 const FileEntry *File, 231 SourceLocation EndLoc, 232 StringRef SearchPath, 233 StringRef RelativePath) { 234 First->InclusionDirective(HashLoc, IncludeTok, FileName, IsAngled, File, 235 EndLoc, SearchPath, RelativePath); 236 Second->InclusionDirective(HashLoc, IncludeTok, FileName, IsAngled, File, 237 EndLoc, SearchPath, RelativePath); 238 } 239 240 virtual void EndOfMainFile() { 241 First->EndOfMainFile(); 242 Second->EndOfMainFile(); 243 } 244 245 virtual void Ident(SourceLocation Loc, const std::string &str) { 246 First->Ident(Loc, str); 247 Second->Ident(Loc, str); 248 } 249 250 virtual void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind, 251 const std::string &Str) { 252 First->PragmaComment(Loc, Kind, Str); 253 Second->PragmaComment(Loc, Kind, Str); 254 } 255 256 virtual void PragmaMessage(SourceLocation Loc, StringRef Str) { 257 First->PragmaMessage(Loc, Str); 258 Second->PragmaMessage(Loc, Str); 259 } 260 261 virtual void PragmaDiagnosticPush(SourceLocation Loc, 262 StringRef Namespace) { 263 First->PragmaDiagnosticPush(Loc, Namespace); 264 Second->PragmaDiagnosticPush(Loc, Namespace); 265 } 266 267 virtual void PragmaDiagnosticPop(SourceLocation Loc, 268 StringRef Namespace) { 269 First->PragmaDiagnosticPop(Loc, Namespace); 270 Second->PragmaDiagnosticPop(Loc, Namespace); 271 } 272 273 virtual void PragmaDiagnostic(SourceLocation Loc, StringRef Namespace, 274 diag::Mapping mapping, StringRef Str) { 275 First->PragmaDiagnostic(Loc, Namespace, mapping, Str); 276 Second->PragmaDiagnostic(Loc, Namespace, mapping, Str); 277 } 278 279 virtual void MacroExpands(const Token &MacroNameTok, const MacroInfo* MI, 280 SourceRange Range) { 281 First->MacroExpands(MacroNameTok, MI, Range); 282 Second->MacroExpands(MacroNameTok, MI, Range); 283 } 284 285 virtual void MacroDefined(const Token &MacroNameTok, const MacroInfo *MI) { 286 First->MacroDefined(MacroNameTok, MI); 287 Second->MacroDefined(MacroNameTok, MI); 288 } 289 290 virtual void MacroUndefined(const Token &MacroNameTok, const MacroInfo *MI) { 291 First->MacroUndefined(MacroNameTok, MI); 292 Second->MacroUndefined(MacroNameTok, MI); 293 } 294 295 virtual void SourceRangeSkipped(SourceRange Range) { 296 First->SourceRangeSkipped(Range); 297 Second->SourceRangeSkipped(Range); 298 } 299 300 /// If -- This hook is called whenever an #if is seen. 301 virtual void If(SourceRange Range) { 302 First->If(Range); 303 Second->If(Range); 304 } 305 306 /// Elif -- This hook is called whenever an #if is seen. 307 virtual void Elif(SourceRange Range) { 308 First->Elif(Range); 309 Second->Elif(Range); 310 } 311 312 /// Ifdef -- This hook is called whenever an #ifdef is seen. 313 virtual void Ifdef(const Token &MacroNameTok) { 314 First->Ifdef(MacroNameTok); 315 Second->Ifdef(MacroNameTok); 316 } 317 318 /// Ifndef -- This hook is called whenever an #ifndef is seen. 319 virtual void Ifndef(const Token &MacroNameTok) { 320 First->Ifndef(MacroNameTok); 321 Second->Ifndef(MacroNameTok); 322 } 323 324 /// Else -- This hook is called whenever an #else is seen. 325 virtual void Else() { 326 First->Else(); 327 Second->Else(); 328 } 329 330 /// Endif -- This hook is called whenever an #endif is seen. 331 virtual void Endif() { 332 First->Endif(); 333 Second->Endif(); 334 } 335}; 336 337} // end namespace clang 338 339#endif 340