1061da546Spatrick //===-- ClangExpressionVariable.h -------------------------------*- C++ -*-===// 2061da546Spatrick // 3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information. 5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6061da546Spatrick // 7061da546Spatrick //===----------------------------------------------------------------------===// 8061da546Spatrick 9dda28197Spatrick #ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXPRESSIONVARIABLE_H 10dda28197Spatrick #define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXPRESSIONVARIABLE_H 11061da546Spatrick 12be691f3bSpatrick #include <csignal> 13be691f3bSpatrick #include <cstdint> 14be691f3bSpatrick #include <cstring> 15061da546Spatrick 16061da546Spatrick #include <map> 17061da546Spatrick #include <string> 18061da546Spatrick #include <vector> 19061da546Spatrick 20061da546Spatrick #include "llvm/Support/Casting.h" 21061da546Spatrick 22061da546Spatrick #include "lldb/Core/Value.h" 23061da546Spatrick #include "lldb/Expression/ExpressionVariable.h" 24061da546Spatrick #include "lldb/Symbol/TaggedASTType.h" 25061da546Spatrick #include "lldb/Utility/ConstString.h" 26061da546Spatrick #include "lldb/lldb-public.h" 27061da546Spatrick 28061da546Spatrick namespace llvm { 29061da546Spatrick class Value; 30061da546Spatrick } 31061da546Spatrick 32dda28197Spatrick namespace clang { 33dda28197Spatrick class NamedDecl; 34dda28197Spatrick } 35dda28197Spatrick 36061da546Spatrick namespace lldb_private { 37061da546Spatrick 38061da546Spatrick class ValueObjectConstResult; 39061da546Spatrick 40061da546Spatrick /// \class ClangExpressionVariable ClangExpressionVariable.h 41061da546Spatrick /// "lldb/Expression/ClangExpressionVariable.h" Encapsulates one variable for 42061da546Spatrick /// the expression parser. 43061da546Spatrick /// 44061da546Spatrick /// The expression parser uses variables in three different contexts: 45061da546Spatrick /// 46061da546Spatrick /// First, it stores persistent variables along with the process for use in 47061da546Spatrick /// expressions. These persistent variables contain their own data and are 48061da546Spatrick /// typed. 49061da546Spatrick /// 50061da546Spatrick /// Second, in an interpreted expression, it stores the local variables for 51061da546Spatrick /// the expression along with the expression. These variables contain their 52061da546Spatrick /// own data and are typed. 53061da546Spatrick /// 54061da546Spatrick /// Third, in a JIT-compiled expression, it stores the variables that the 55061da546Spatrick /// expression needs to have materialized and dematerialized at each 56061da546Spatrick /// execution. These do not contain their own data but are named and typed. 57061da546Spatrick /// 58061da546Spatrick /// This class supports all of these use cases using simple type polymorphism, 59061da546Spatrick /// and provides necessary support methods. Its interface is RTTI-neutral. 60061da546Spatrick class ClangExpressionVariable : public ExpressionVariable { 61061da546Spatrick public: 62061da546Spatrick ClangExpressionVariable(ExecutionContextScope *exe_scope, 63061da546Spatrick lldb::ByteOrder byte_order, uint32_t addr_byte_size); 64061da546Spatrick 65061da546Spatrick ClangExpressionVariable(ExecutionContextScope *exe_scope, Value &value, 66061da546Spatrick ConstString name, uint16_t flags = EVNone); 67061da546Spatrick 68061da546Spatrick ClangExpressionVariable(const lldb::ValueObjectSP &valobj_sp); 69061da546Spatrick 70061da546Spatrick ClangExpressionVariable(ExecutionContextScope *exe_scope, 71061da546Spatrick ConstString name, 72061da546Spatrick const TypeFromUser &user_type, 73061da546Spatrick lldb::ByteOrder byte_order, uint32_t addr_byte_size); 74061da546Spatrick 75061da546Spatrick /// Utility functions for dealing with ExpressionVariableLists in Clang- 76061da546Spatrick /// specific ways 77061da546Spatrick 78061da546Spatrick /// Finds a variable by NamedDecl in the list. 79061da546Spatrick /// 80061da546Spatrick /// \return 81061da546Spatrick /// The variable requested, or NULL if that variable is not in the list. 82061da546Spatrick static ClangExpressionVariable * FindVariableInList(ExpressionVariableList & list,const clang::NamedDecl * decl,uint64_t parser_id)83061da546Spatrick FindVariableInList(ExpressionVariableList &list, const clang::NamedDecl *decl, 84061da546Spatrick uint64_t parser_id) { 85061da546Spatrick lldb::ExpressionVariableSP var_sp; 86061da546Spatrick for (size_t index = 0, size = list.GetSize(); index < size; ++index) { 87061da546Spatrick var_sp = list.GetVariableAtIndex(index); 88061da546Spatrick 89061da546Spatrick if (ClangExpressionVariable *clang_var = 90061da546Spatrick llvm::dyn_cast<ClangExpressionVariable>(var_sp.get())) { 91061da546Spatrick ClangExpressionVariable::ParserVars *parser_vars = 92061da546Spatrick clang_var->GetParserVars(parser_id); 93061da546Spatrick 94061da546Spatrick if (parser_vars && parser_vars->m_named_decl == decl) 95061da546Spatrick return clang_var; 96061da546Spatrick } 97061da546Spatrick } 98061da546Spatrick return nullptr; 99061da546Spatrick } 100061da546Spatrick 101061da546Spatrick /// If the variable contains its own data, make a Value point at it. If \a 102061da546Spatrick /// exe_ctx in not NULL, the value will be resolved in with that execution 103061da546Spatrick /// context. 104061da546Spatrick /// 105061da546Spatrick /// \param[in] value 106061da546Spatrick /// The value to point at the data. 107061da546Spatrick /// 108061da546Spatrick /// \param[in] exe_ctx 109061da546Spatrick /// The execution context to use to resolve \a value. 110061da546Spatrick /// 111061da546Spatrick /// \return 112061da546Spatrick /// True on success; false otherwise (in particular, if this variable 113061da546Spatrick /// does not contain its own data). 114061da546Spatrick bool PointValueAtData(Value &value, ExecutionContext *exe_ctx); 115061da546Spatrick 116061da546Spatrick /// The following values should not live beyond parsing 117061da546Spatrick class ParserVars { 118061da546Spatrick public: 119*f6aab3d8Srobert ParserVars() = default; 120061da546Spatrick 121be691f3bSpatrick const clang::NamedDecl *m_named_decl = 122be691f3bSpatrick nullptr; ///< The Decl corresponding to this variable 123be691f3bSpatrick llvm::Value *m_llvm_value = 124be691f3bSpatrick nullptr; ///< The IR value corresponding to this variable; 125061da546Spatrick /// usually a GlobalValue 126061da546Spatrick lldb_private::Value 127061da546Spatrick m_lldb_value; ///< The value found in LLDB for this variable 128061da546Spatrick lldb::VariableSP m_lldb_var; ///< The original variable for this variable 129be691f3bSpatrick const lldb_private::Symbol *m_lldb_sym = 130be691f3bSpatrick nullptr; ///< The original symbol for this 131061da546Spatrick /// variable, if it was a symbol 132*f6aab3d8Srobert 133*f6aab3d8Srobert /// Callback that provides a ValueObject for the 134*f6aab3d8Srobert /// specified frame. Used by the materializer for 135*f6aab3d8Srobert /// re-fetching ValueObjects when materializing 136*f6aab3d8Srobert /// ivars. 137*f6aab3d8Srobert ValueObjectProviderTy m_lldb_valobj_provider; 138061da546Spatrick }; 139061da546Spatrick 140061da546Spatrick private: 141061da546Spatrick typedef std::map<uint64_t, ParserVars> ParserVarMap; 142061da546Spatrick ParserVarMap m_parser_vars; 143061da546Spatrick 144061da546Spatrick public: 145061da546Spatrick /// Make this variable usable by the parser by allocating space for parser- 146061da546Spatrick /// specific variables EnableParserVars(uint64_t parser_id)147061da546Spatrick void EnableParserVars(uint64_t parser_id) { 148061da546Spatrick m_parser_vars.insert(std::make_pair(parser_id, ParserVars())); 149061da546Spatrick } 150061da546Spatrick 151061da546Spatrick /// Deallocate parser-specific variables DisableParserVars(uint64_t parser_id)152061da546Spatrick void DisableParserVars(uint64_t parser_id) { m_parser_vars.erase(parser_id); } 153061da546Spatrick 154061da546Spatrick /// Access parser-specific variables GetParserVars(uint64_t parser_id)155061da546Spatrick ParserVars *GetParserVars(uint64_t parser_id) { 156061da546Spatrick ParserVarMap::iterator i = m_parser_vars.find(parser_id); 157061da546Spatrick 158061da546Spatrick if (i == m_parser_vars.end()) 159061da546Spatrick return nullptr; 160061da546Spatrick else 161061da546Spatrick return &i->second; 162061da546Spatrick } 163061da546Spatrick 164061da546Spatrick /// The following values are valid if the variable is used by JIT code 165061da546Spatrick struct JITVars { 166be691f3bSpatrick JITVars() = default; 167061da546Spatrick 168be691f3bSpatrick lldb::offset_t m_alignment = 169be691f3bSpatrick 0; ///< The required alignment of the variable, in bytes 170be691f3bSpatrick size_t m_size = 0; ///< The space required for the variable, in bytes 171be691f3bSpatrick lldb::offset_t m_offset = 172be691f3bSpatrick 0; ///< The offset of the variable in the struct, in bytes 173061da546Spatrick }; 174061da546Spatrick 175061da546Spatrick private: 176061da546Spatrick typedef std::map<uint64_t, JITVars> JITVarMap; 177061da546Spatrick JITVarMap m_jit_vars; 178061da546Spatrick 179061da546Spatrick public: 180061da546Spatrick /// Make this variable usable for materializing for the JIT by allocating 181061da546Spatrick /// space for JIT-specific variables EnableJITVars(uint64_t parser_id)182061da546Spatrick void EnableJITVars(uint64_t parser_id) { 183061da546Spatrick m_jit_vars.insert(std::make_pair(parser_id, JITVars())); 184061da546Spatrick } 185061da546Spatrick 186061da546Spatrick /// Deallocate JIT-specific variables DisableJITVars(uint64_t parser_id)187061da546Spatrick void DisableJITVars(uint64_t parser_id) { m_jit_vars.erase(parser_id); } 188061da546Spatrick GetJITVars(uint64_t parser_id)189061da546Spatrick JITVars *GetJITVars(uint64_t parser_id) { 190061da546Spatrick JITVarMap::iterator i = m_jit_vars.find(parser_id); 191061da546Spatrick 192061da546Spatrick if (i == m_jit_vars.end()) 193061da546Spatrick return nullptr; 194061da546Spatrick else 195061da546Spatrick return &i->second; 196061da546Spatrick } 197061da546Spatrick 198061da546Spatrick TypeFromUser GetTypeFromUser(); 199061da546Spatrick 200061da546Spatrick // llvm casting support classof(const ExpressionVariable * ev)201061da546Spatrick static bool classof(const ExpressionVariable *ev) { 202061da546Spatrick return ev->getKind() == ExpressionVariable::eKindClang; 203061da546Spatrick } 204061da546Spatrick 205061da546Spatrick /// Members 206dda28197Spatrick ClangExpressionVariable(const ClangExpressionVariable &) = delete; 207dda28197Spatrick const ClangExpressionVariable & 208dda28197Spatrick operator=(const ClangExpressionVariable &) = delete; 209061da546Spatrick }; 210061da546Spatrick 211061da546Spatrick } // namespace lldb_private 212061da546Spatrick 213dda28197Spatrick #endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXPRESSIONVARIABLE_H 214