1 //===--- MacroPPCallbacks.h -------------------------------------*- 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 implementation for the macro preprocessors callbacks. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "clang/Lex/PPCallbacks.h" 15 16 namespace llvm { 17 class DIMacroFile; 18 class DIMacroNode; 19 } 20 namespace clang { 21 class Preprocessor; 22 class MacroInfo; 23 class CodeGenerator; 24 25 class MacroPPCallbacks : public PPCallbacks { 26 /// A pointer to code generator, where debug info generator can be found. 27 CodeGenerator *Gen; 28 29 /// Preprocessor. 30 Preprocessor &PP; 31 32 /// Location of recent included file, used for line number. 33 SourceLocation LastHashLoc; 34 35 /// Counts current number of command line included files, which were entered 36 /// and were not exited yet. 37 int EnteredCommandLineIncludeFiles = 0; 38 39 enum FileScopeStatus { 40 NoScope = 0, // Scope is not initialized yet. 41 InitializedScope, // Main file scope is initialized but not set yet. 42 BuiltinScope, // <built-in> and <command line> file scopes. 43 CommandLineIncludeScope, // Included file, from <command line> file, scope. 44 MainFileScope // Main file scope. 45 }; 46 FileScopeStatus Status; 47 48 /// Parent contains all entered files that were not exited yet according to 49 /// the inclusion order. 50 llvm::SmallVector<llvm::DIMacroFile *, 4> Scopes; 51 52 /// Get current DIMacroFile scope. 53 /// \return current DIMacroFile scope or nullptr if there is no such scope. 54 llvm::DIMacroFile *getCurrentScope(); 55 56 /// Get current line location or invalid location. 57 /// \param Loc current line location. 58 /// \return current line location \p `Loc`, or invalid location if it's in a 59 /// skipped file scope. 60 SourceLocation getCorrectLocation(SourceLocation Loc); 61 62 /// Use the passed preprocessor to write the macro name and value from the 63 /// given macro info and identifier info into the given \p `Name` and \p 64 /// `Value` output streams. 65 /// 66 /// \param II Identifier info, used to get the Macro name. 67 /// \param MI Macro info, used to get the Macro argumets and values. 68 /// \param PP Preprocessor. 69 /// \param [out] Name Place holder for returned macro name and arguments. 70 /// \param [out] Value Place holder for returned macro value. 71 static void writeMacroDefinition(const IdentifierInfo &II, 72 const MacroInfo &MI, Preprocessor &PP, 73 raw_ostream &Name, raw_ostream &Value); 74 75 /// Update current file scope status to next file scope. 76 void updateStatusToNextScope(); 77 78 /// Handle the case when entering a file. 79 /// 80 /// \param Loc Indicates the new location. 81 void FileEntered(SourceLocation Loc); 82 83 /// Handle the case when exiting a file. 84 /// 85 /// \param Loc Indicates the new location. 86 void FileExited(SourceLocation Loc); 87 88 public: 89 MacroPPCallbacks(CodeGenerator *Gen, Preprocessor &PP); 90 91 /// Callback invoked whenever a source file is entered or exited. 92 /// 93 /// \param Loc Indicates the new location. 94 /// \param PrevFID the file that was exited if \p Reason is ExitFile. 95 void FileChanged(SourceLocation Loc, FileChangeReason Reason, 96 SrcMgr::CharacteristicKind FileType, 97 FileID PrevFID = FileID()) override; 98 99 /// Callback invoked whenever a directive (#xxx) is processed. 100 void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, 101 StringRef FileName, bool IsAngled, 102 CharSourceRange FilenameRange, const FileEntry *File, 103 StringRef SearchPath, StringRef RelativePath, 104 const Module *Imported) override; 105 106 /// Hook called whenever a macro definition is seen. 107 void MacroDefined(const Token &MacroNameTok, 108 const MacroDirective *MD) override; 109 110 /// Hook called whenever a macro \#undef is seen. 111 /// 112 /// MD is released immediately following this callback. 113 void MacroUndefined(const Token &MacroNameTok, const MacroDefinition &MD, 114 const MacroDirective *Undef) override; 115 }; 116 117 } // end namespace clang 118