//===--- MacroPPCallbacks.h -------------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // This file defines implementation for the macro preprocessors callbacks. // //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_LIB_CODEGEN_MACROPPCALLBACKS_H #define LLVM_CLANG_LIB_CODEGEN_MACROPPCALLBACKS_H #include "clang/Lex/PPCallbacks.h" namespace llvm { class DIMacroFile; } namespace clang { class Preprocessor; class MacroInfo; class CodeGenerator; class MacroPPCallbacks : public PPCallbacks { /// A pointer to code generator, where debug info generator can be found. CodeGenerator *Gen; /// Preprocessor. Preprocessor &PP; /// Location of recent included file, used for line number. SourceLocation LastHashLoc; /// Counts current number of command line included files, which were entered /// and were not exited yet. int EnteredCommandLineIncludeFiles = 0; enum FileScopeStatus { NoScope = 0, // Scope is not initialized yet. InitializedScope, // Main file scope is initialized but not set yet. BuiltinScope, // and file scopes. CommandLineIncludeScope, // Included file, from file, scope. MainFileScope // Main file scope. }; FileScopeStatus Status; /// Parent contains all entered files that were not exited yet according to /// the inclusion order. llvm::SmallVector Scopes; /// Get current DIMacroFile scope. /// \return current DIMacroFile scope or nullptr if there is no such scope. llvm::DIMacroFile *getCurrentScope(); /// Get current line location or invalid location. /// \param Loc current line location. /// \return current line location \p `Loc`, or invalid location if it's in a /// skipped file scope. SourceLocation getCorrectLocation(SourceLocation Loc); /// Use the passed preprocessor to write the macro name and value from the /// given macro info and identifier info into the given \p `Name` and \p /// `Value` output streams. /// /// \param II Identifier info, used to get the Macro name. /// \param MI Macro info, used to get the Macro argumets and values. /// \param PP Preprocessor. /// \param [out] Name Place holder for returned macro name and arguments. /// \param [out] Value Place holder for returned macro value. static void writeMacroDefinition(const IdentifierInfo &II, const MacroInfo &MI, Preprocessor &PP, raw_ostream &Name, raw_ostream &Value); /// Update current file scope status to next file scope. void updateStatusToNextScope(); /// Handle the case when entering a file. /// /// \param Loc Indicates the new location. void FileEntered(SourceLocation Loc); /// Handle the case when exiting a file. /// /// \param Loc Indicates the new location. void FileExited(SourceLocation Loc); public: MacroPPCallbacks(CodeGenerator *Gen, Preprocessor &PP); /// Callback invoked whenever a source file is entered or exited. /// /// \param Loc Indicates the new location. /// \param PrevFID the file that was exited if \p Reason is ExitFile. void FileChanged(SourceLocation Loc, FileChangeReason Reason, SrcMgr::CharacteristicKind FileType, FileID PrevFID = FileID()) override; /// Callback invoked whenever a directive (#xxx) is processed. void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName, bool IsAngled, CharSourceRange FilenameRange, const FileEntry *File, StringRef SearchPath, StringRef RelativePath, const Module *Imported, SrcMgr::CharacteristicKind FileType) override; /// Hook called whenever a macro definition is seen. void MacroDefined(const Token &MacroNameTok, const MacroDirective *MD) override; /// Hook called whenever a macro \#undef is seen. /// /// MD is released immediately following this callback. void MacroUndefined(const Token &MacroNameTok, const MacroDefinition &MD, const MacroDirective *Undef) override; }; } // end namespace clang #endif