PPCallbacks.h revision 226890
1193326Sed//===--- PPCallbacks.h - Callbacks for Preprocessor actions -----*- C++ -*-===// 2193326Sed// 3193326Sed// The LLVM Compiler Infrastructure 4193326Sed// 5193326Sed// This file is distributed under the University of Illinois Open Source 6193326Sed// License. See LICENSE.TXT for details. 7193326Sed// 8193326Sed//===----------------------------------------------------------------------===// 9193326Sed// 10193326Sed// This file defines the PPCallbacks interface. 11193326Sed// 12193326Sed//===----------------------------------------------------------------------===// 13193326Sed 14193326Sed#ifndef LLVM_CLANG_LEX_PPCALLBACKS_H 15193326Sed#define LLVM_CLANG_LEX_PPCALLBACKS_H 16193326Sed 17193326Sed#include "clang/Lex/DirectoryLookup.h" 18193326Sed#include "clang/Basic/SourceLocation.h" 19224145Sdim#include "clang/Basic/DiagnosticIDs.h" 20210299Sed#include "llvm/ADT/StringRef.h" 21193326Sed#include <string> 22193326Sed 23193326Sednamespace clang { 24193326Sed class SourceLocation; 25193326Sed class Token; 26193326Sed class IdentifierInfo; 27193326Sed class MacroInfo; 28198092Srdivacky 29193326Sed/// PPCallbacks - This interface provides a way to observe the actions of the 30193326Sed/// preprocessor as it does its thing. Clients can define their hooks here to 31193326Sed/// implement preprocessor level tools. 32193326Sedclass PPCallbacks { 33193326Sedpublic: 34193326Sed virtual ~PPCallbacks(); 35198092Srdivacky 36193326Sed enum FileChangeReason { 37193326Sed EnterFile, ExitFile, SystemHeaderPragma, RenameFile 38193326Sed }; 39198092Srdivacky 40193326Sed /// FileChanged - This callback is invoked whenever a source file is 41193326Sed /// entered or exited. The SourceLocation indicates the new location, and 42193326Sed /// EnteringFile indicates whether this is because we are entering a new 43193326Sed /// #include'd file (when true) or whether we're exiting one because we ran 44193326Sed /// off the end (when false). 45226890Sdim /// 46226890Sdim /// \param PrevFID the file that was exited if \arg Reason is ExitFile. 47193326Sed virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason, 48226890Sdim SrcMgr::CharacteristicKind FileType, 49226890Sdim FileID PrevFID = FileID()) { 50193326Sed } 51198092Srdivacky 52207619Srdivacky /// FileSkipped - This callback is invoked whenever a source file is 53207619Srdivacky /// skipped as the result of header guard optimization. ParentFile 54207619Srdivacky /// is the file that #includes the skipped file. FilenameTok is the 55207619Srdivacky /// token in ParentFile that indicates the skipped file. 56207619Srdivacky virtual void FileSkipped(const FileEntry &ParentFile, 57207619Srdivacky const Token &FilenameTok, 58207619Srdivacky SrcMgr::CharacteristicKind FileType) { 59207619Srdivacky } 60206084Srdivacky 61218893Sdim /// \brief This callback is invoked whenever an inclusion directive of 62218893Sdim /// any kind (\c #include, \c #import, etc.) has been processed, regardless 63218893Sdim /// of whether the inclusion will actually result in an inclusion. 64218893Sdim /// 65218893Sdim /// \param HashLoc The location of the '#' that starts the inclusion 66218893Sdim /// directive. 67218893Sdim /// 68218893Sdim /// \param IncludeTok The token that indicates the kind of inclusion 69218893Sdim /// directive, e.g., 'include' or 'import'. 70218893Sdim /// 71218893Sdim /// \param FileName The name of the file being included, as written in the 72218893Sdim /// source code. 73218893Sdim /// 74218893Sdim /// \param IsAngled Whether the file name was enclosed in angle brackets; 75218893Sdim /// otherwise, it was enclosed in quotes. 76218893Sdim /// 77218893Sdim /// \param File The actual file that may be included by this inclusion 78218893Sdim /// directive. 79218893Sdim /// 80218893Sdim /// \param EndLoc The location of the last token within the inclusion 81218893Sdim /// directive. 82221345Sdim /// 83221345Sdim /// \param SearchPath Contains the search path which was used to find the file 84221345Sdim /// in the file system. If the file was found via an absolute include path, 85221345Sdim /// SearchPath will be empty. For framework includes, the SearchPath and 86221345Sdim /// RelativePath will be split up. For example, if an include of "Some/Some.h" 87221345Sdim /// is found via the framework path 88221345Sdim /// "path/to/Frameworks/Some.framework/Headers/Some.h", SearchPath will be 89221345Sdim /// "path/to/Frameworks/Some.framework/Headers" and RelativePath will be 90221345Sdim /// "Some.h". 91221345Sdim /// 92221345Sdim /// \param RelativePath The path relative to SearchPath, at which the include 93221345Sdim /// file was found. This is equal to FileName except for framework includes. 94218893Sdim virtual void InclusionDirective(SourceLocation HashLoc, 95218893Sdim const Token &IncludeTok, 96226890Sdim StringRef FileName, 97218893Sdim bool IsAngled, 98218893Sdim const FileEntry *File, 99221345Sdim SourceLocation EndLoc, 100226890Sdim StringRef SearchPath, 101226890Sdim StringRef RelativePath) { 102218893Sdim } 103218893Sdim 104206084Srdivacky /// EndOfMainFile - This callback is invoked when the end of the main file is 105206084Srdivacky /// reach, no subsequent callbacks will be made. 106206084Srdivacky virtual void EndOfMainFile() { 107206084Srdivacky } 108206084Srdivacky 109193326Sed /// Ident - This callback is invoked when a #ident or #sccs directive is read. 110218893Sdim /// \param Loc The location of the directive. 111218893Sdim /// \param str The text of the directive. 112193326Sed /// 113193326Sed virtual void Ident(SourceLocation Loc, const std::string &str) { 114193326Sed } 115198092Srdivacky 116193326Sed /// PragmaComment - This callback is invoked when a #pragma comment directive 117193326Sed /// is read. 118193326Sed /// 119198092Srdivacky virtual void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind, 120193326Sed const std::string &Str) { 121193326Sed } 122198092Srdivacky 123210299Sed /// PragmaMessage - This callback is invoked when a #pragma message directive 124210299Sed /// is read. 125218893Sdim /// \param Loc The location of the message directive. 126218893Sdim /// \param str The text of the message directive. 127210299Sed /// 128226890Sdim virtual void PragmaMessage(SourceLocation Loc, StringRef Str) { 129210299Sed } 130210299Sed 131224145Sdim /// PragmaDiagnosticPush - This callback is invoked when a 132224145Sdim /// #pragma gcc dianostic push directive is read. 133224145Sdim virtual void PragmaDiagnosticPush(SourceLocation Loc, 134226890Sdim StringRef Namespace) { 135224145Sdim } 136224145Sdim 137224145Sdim /// PragmaDiagnosticPop - This callback is invoked when a 138224145Sdim /// #pragma gcc dianostic pop directive is read. 139224145Sdim virtual void PragmaDiagnosticPop(SourceLocation Loc, 140226890Sdim StringRef Namespace) { 141224145Sdim } 142224145Sdim 143224145Sdim /// PragmaDiagnostic - This callback is invoked when a 144224145Sdim /// #pragma gcc dianostic directive is read. 145226890Sdim virtual void PragmaDiagnostic(SourceLocation Loc, StringRef Namespace, 146226890Sdim diag::Mapping mapping, StringRef Str) { 147224145Sdim } 148224145Sdim 149193326Sed /// MacroExpands - This is called by 150193326Sed /// Preprocessor::HandleMacroExpandedIdentifier when a macro invocation is 151193326Sed /// found. 152226890Sdim virtual void MacroExpands(const Token &MacroNameTok, const MacroInfo* MI, 153226890Sdim SourceRange Range) { 154193326Sed } 155198092Srdivacky 156193326Sed /// MacroDefined - This hook is called whenever a macro definition is seen. 157218893Sdim virtual void MacroDefined(const Token &MacroNameTok, const MacroInfo *MI) { 158193326Sed } 159193326Sed 160193326Sed /// MacroUndefined - This hook is called whenever a macro #undef is seen. 161193326Sed /// MI is released immediately following this callback. 162218893Sdim virtual void MacroUndefined(const Token &MacroNameTok, const MacroInfo *MI) { 163193326Sed } 164226890Sdim 165226890Sdim /// Defined - This hook is called whenever the 'defined' operator is seen. 166226890Sdim virtual void Defined(const Token &MacroNameTok) { 167226890Sdim } 168226890Sdim 169226890Sdim /// SourceRangeSkipped - This hook is called when a source range is skipped. 170226890Sdim /// \param Range The SourceRange that was skipped. The range begins at the 171226890Sdim /// #if/#else directive and ends after the #endif/#else directive. 172226890Sdim virtual void SourceRangeSkipped(SourceRange Range) { 173226890Sdim } 174218893Sdim 175218893Sdim /// If -- This hook is called whenever an #if is seen. 176218893Sdim /// \param Range The SourceRange of the expression being tested. 177218893Sdim // FIXME: better to pass in a list (or tree!) of Tokens. 178218893Sdim virtual void If(SourceRange Range) { 179218893Sdim } 180218893Sdim 181218893Sdim /// Elif -- This hook is called whenever an #elif is seen. 182218893Sdim /// \param Range The SourceRange of the expression being tested. 183218893Sdim // FIXME: better to pass in a list (or tree!) of Tokens. 184218893Sdim virtual void Elif(SourceRange Range) { 185218893Sdim } 186218893Sdim 187218893Sdim /// Ifdef -- This hook is called whenever an #ifdef is seen. 188218893Sdim /// \param Loc The location of the token being tested. 189218893Sdim /// \param II Information on the token being tested. 190218893Sdim virtual void Ifdef(const Token &MacroNameTok) { 191218893Sdim } 192218893Sdim 193218893Sdim /// Ifndef -- This hook is called whenever an #ifndef is seen. 194218893Sdim /// \param Loc The location of the token being tested. 195218893Sdim /// \param II Information on the token being tested. 196218893Sdim virtual void Ifndef(const Token &MacroNameTok) { 197218893Sdim } 198218893Sdim 199218893Sdim /// Else -- This hook is called whenever an #else is seen. 200218893Sdim virtual void Else() { 201218893Sdim } 202218893Sdim 203218893Sdim /// Endif -- This hook is called whenever an #endif is seen. 204218893Sdim virtual void Endif() { 205218893Sdim } 206193326Sed}; 207193326Sed 208193326Sed/// PPChainedCallbacks - Simple wrapper class for chaining callbacks. 209193326Sedclass PPChainedCallbacks : public PPCallbacks { 210193326Sed PPCallbacks *First, *Second; 211193326Sed 212198092Srdivackypublic: 213193326Sed PPChainedCallbacks(PPCallbacks *_First, PPCallbacks *_Second) 214193326Sed : First(_First), Second(_Second) {} 215193326Sed ~PPChainedCallbacks() { 216193326Sed delete Second; 217193326Sed delete First; 218193326Sed } 219193326Sed 220193326Sed virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason, 221226890Sdim SrcMgr::CharacteristicKind FileType, 222226890Sdim FileID PrevFID) { 223226890Sdim First->FileChanged(Loc, Reason, FileType, PrevFID); 224226890Sdim Second->FileChanged(Loc, Reason, FileType, PrevFID); 225193326Sed } 226198092Srdivacky 227207619Srdivacky virtual void FileSkipped(const FileEntry &ParentFile, 228207619Srdivacky const Token &FilenameTok, 229207619Srdivacky SrcMgr::CharacteristicKind FileType) { 230207619Srdivacky First->FileSkipped(ParentFile, FilenameTok, FileType); 231207619Srdivacky Second->FileSkipped(ParentFile, FilenameTok, FileType); 232207619Srdivacky } 233207619Srdivacky 234218893Sdim virtual void InclusionDirective(SourceLocation HashLoc, 235218893Sdim const Token &IncludeTok, 236226890Sdim StringRef FileName, 237218893Sdim bool IsAngled, 238218893Sdim const FileEntry *File, 239221345Sdim SourceLocation EndLoc, 240226890Sdim StringRef SearchPath, 241226890Sdim StringRef RelativePath) { 242221345Sdim First->InclusionDirective(HashLoc, IncludeTok, FileName, IsAngled, File, 243221345Sdim EndLoc, SearchPath, RelativePath); 244221345Sdim Second->InclusionDirective(HashLoc, IncludeTok, FileName, IsAngled, File, 245221345Sdim EndLoc, SearchPath, RelativePath); 246218893Sdim } 247218893Sdim 248206084Srdivacky virtual void EndOfMainFile() { 249206084Srdivacky First->EndOfMainFile(); 250206084Srdivacky Second->EndOfMainFile(); 251206084Srdivacky } 252206084Srdivacky 253193326Sed virtual void Ident(SourceLocation Loc, const std::string &str) { 254193326Sed First->Ident(Loc, str); 255193326Sed Second->Ident(Loc, str); 256193326Sed } 257198092Srdivacky 258198092Srdivacky virtual void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind, 259193326Sed const std::string &Str) { 260193326Sed First->PragmaComment(Loc, Kind, Str); 261193326Sed Second->PragmaComment(Loc, Kind, Str); 262193326Sed } 263198092Srdivacky 264226890Sdim virtual void PragmaMessage(SourceLocation Loc, StringRef Str) { 265210299Sed First->PragmaMessage(Loc, Str); 266210299Sed Second->PragmaMessage(Loc, Str); 267210299Sed } 268210299Sed 269224145Sdim virtual void PragmaDiagnosticPush(SourceLocation Loc, 270226890Sdim StringRef Namespace) { 271224145Sdim First->PragmaDiagnosticPush(Loc, Namespace); 272224145Sdim Second->PragmaDiagnosticPush(Loc, Namespace); 273224145Sdim } 274224145Sdim 275224145Sdim virtual void PragmaDiagnosticPop(SourceLocation Loc, 276226890Sdim StringRef Namespace) { 277224145Sdim First->PragmaDiagnosticPop(Loc, Namespace); 278224145Sdim Second->PragmaDiagnosticPop(Loc, Namespace); 279224145Sdim } 280224145Sdim 281226890Sdim virtual void PragmaDiagnostic(SourceLocation Loc, StringRef Namespace, 282226890Sdim diag::Mapping mapping, StringRef Str) { 283224145Sdim First->PragmaDiagnostic(Loc, Namespace, mapping, Str); 284224145Sdim Second->PragmaDiagnostic(Loc, Namespace, mapping, Str); 285224145Sdim } 286224145Sdim 287226890Sdim virtual void MacroExpands(const Token &MacroNameTok, const MacroInfo* MI, 288226890Sdim SourceRange Range) { 289226890Sdim First->MacroExpands(MacroNameTok, MI, Range); 290226890Sdim Second->MacroExpands(MacroNameTok, MI, Range); 291193326Sed } 292198092Srdivacky 293218893Sdim virtual void MacroDefined(const Token &MacroNameTok, const MacroInfo *MI) { 294218893Sdim First->MacroDefined(MacroNameTok, MI); 295218893Sdim Second->MacroDefined(MacroNameTok, MI); 296193326Sed } 297193326Sed 298218893Sdim virtual void MacroUndefined(const Token &MacroNameTok, const MacroInfo *MI) { 299218893Sdim First->MacroUndefined(MacroNameTok, MI); 300218893Sdim Second->MacroUndefined(MacroNameTok, MI); 301193326Sed } 302218893Sdim 303226890Sdim virtual void Defined(const Token &MacroNameTok) { 304226890Sdim First->Defined(MacroNameTok); 305226890Sdim Second->Defined(MacroNameTok); 306226890Sdim } 307226890Sdim 308226890Sdim virtual void SourceRangeSkipped(SourceRange Range) { 309226890Sdim First->SourceRangeSkipped(Range); 310226890Sdim Second->SourceRangeSkipped(Range); 311226890Sdim } 312226890Sdim 313218893Sdim /// If -- This hook is called whenever an #if is seen. 314218893Sdim virtual void If(SourceRange Range) { 315218893Sdim First->If(Range); 316218893Sdim Second->If(Range); 317218893Sdim } 318218893Sdim 319218893Sdim /// Elif -- This hook is called whenever an #if is seen. 320218893Sdim virtual void Elif(SourceRange Range) { 321218893Sdim First->Elif(Range); 322218893Sdim Second->Elif(Range); 323218893Sdim } 324218893Sdim 325218893Sdim /// Ifdef -- This hook is called whenever an #ifdef is seen. 326218893Sdim virtual void Ifdef(const Token &MacroNameTok) { 327218893Sdim First->Ifdef(MacroNameTok); 328218893Sdim Second->Ifdef(MacroNameTok); 329218893Sdim } 330218893Sdim 331218893Sdim /// Ifndef -- This hook is called whenever an #ifndef is seen. 332218893Sdim virtual void Ifndef(const Token &MacroNameTok) { 333218893Sdim First->Ifndef(MacroNameTok); 334218893Sdim Second->Ifndef(MacroNameTok); 335218893Sdim } 336218893Sdim 337218893Sdim /// Else -- This hook is called whenever an #else is seen. 338218893Sdim virtual void Else() { 339218893Sdim First->Else(); 340218893Sdim Second->Else(); 341218893Sdim } 342218893Sdim 343218893Sdim /// Endif -- This hook is called whenever an #endif is seen. 344218893Sdim virtual void Endif() { 345218893Sdim First->Endif(); 346218893Sdim Second->Endif(); 347218893Sdim } 348193326Sed}; 349193326Sed 350193326Sed} // end namespace clang 351193326Sed 352193326Sed#endif 353