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