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