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 12*be691f3bSpatrick #include <csignal> 13*be691f3bSpatrick #include <cstdint> 14*be691f3bSpatrick #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 * 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*be691f3bSpatrick ParserVars() : m_lldb_value(), m_lldb_var() {} 120061da546Spatrick 121*be691f3bSpatrick const clang::NamedDecl *m_named_decl = 122*be691f3bSpatrick nullptr; ///< The Decl corresponding to this variable 123*be691f3bSpatrick llvm::Value *m_llvm_value = 124*be691f3bSpatrick 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 129*be691f3bSpatrick const lldb_private::Symbol *m_lldb_sym = 130*be691f3bSpatrick nullptr; ///< The original symbol for this 131061da546Spatrick /// variable, if it was a symbol 132061da546Spatrick }; 133061da546Spatrick 134061da546Spatrick private: 135061da546Spatrick typedef std::map<uint64_t, ParserVars> ParserVarMap; 136061da546Spatrick ParserVarMap m_parser_vars; 137061da546Spatrick 138061da546Spatrick public: 139061da546Spatrick /// Make this variable usable by the parser by allocating space for parser- 140061da546Spatrick /// specific variables 141061da546Spatrick void EnableParserVars(uint64_t parser_id) { 142061da546Spatrick m_parser_vars.insert(std::make_pair(parser_id, ParserVars())); 143061da546Spatrick } 144061da546Spatrick 145061da546Spatrick /// Deallocate parser-specific variables 146061da546Spatrick void DisableParserVars(uint64_t parser_id) { m_parser_vars.erase(parser_id); } 147061da546Spatrick 148061da546Spatrick /// Access parser-specific variables 149061da546Spatrick ParserVars *GetParserVars(uint64_t parser_id) { 150061da546Spatrick ParserVarMap::iterator i = m_parser_vars.find(parser_id); 151061da546Spatrick 152061da546Spatrick if (i == m_parser_vars.end()) 153061da546Spatrick return nullptr; 154061da546Spatrick else 155061da546Spatrick return &i->second; 156061da546Spatrick } 157061da546Spatrick 158061da546Spatrick /// The following values are valid if the variable is used by JIT code 159061da546Spatrick struct JITVars { 160*be691f3bSpatrick JITVars() = default; 161061da546Spatrick 162*be691f3bSpatrick lldb::offset_t m_alignment = 163*be691f3bSpatrick 0; ///< The required alignment of the variable, in bytes 164*be691f3bSpatrick size_t m_size = 0; ///< The space required for the variable, in bytes 165*be691f3bSpatrick lldb::offset_t m_offset = 166*be691f3bSpatrick 0; ///< The offset of the variable in the struct, in bytes 167061da546Spatrick }; 168061da546Spatrick 169061da546Spatrick private: 170061da546Spatrick typedef std::map<uint64_t, JITVars> JITVarMap; 171061da546Spatrick JITVarMap m_jit_vars; 172061da546Spatrick 173061da546Spatrick public: 174061da546Spatrick /// Make this variable usable for materializing for the JIT by allocating 175061da546Spatrick /// space for JIT-specific variables 176061da546Spatrick void EnableJITVars(uint64_t parser_id) { 177061da546Spatrick m_jit_vars.insert(std::make_pair(parser_id, JITVars())); 178061da546Spatrick } 179061da546Spatrick 180061da546Spatrick /// Deallocate JIT-specific variables 181061da546Spatrick void DisableJITVars(uint64_t parser_id) { m_jit_vars.erase(parser_id); } 182061da546Spatrick 183061da546Spatrick JITVars *GetJITVars(uint64_t parser_id) { 184061da546Spatrick JITVarMap::iterator i = m_jit_vars.find(parser_id); 185061da546Spatrick 186061da546Spatrick if (i == m_jit_vars.end()) 187061da546Spatrick return nullptr; 188061da546Spatrick else 189061da546Spatrick return &i->second; 190061da546Spatrick } 191061da546Spatrick 192061da546Spatrick TypeFromUser GetTypeFromUser(); 193061da546Spatrick 194061da546Spatrick // llvm casting support 195061da546Spatrick static bool classof(const ExpressionVariable *ev) { 196061da546Spatrick return ev->getKind() == ExpressionVariable::eKindClang; 197061da546Spatrick } 198061da546Spatrick 199061da546Spatrick /// Members 200dda28197Spatrick ClangExpressionVariable(const ClangExpressionVariable &) = delete; 201dda28197Spatrick const ClangExpressionVariable & 202dda28197Spatrick operator=(const ClangExpressionVariable &) = delete; 203061da546Spatrick }; 204061da546Spatrick 205061da546Spatrick } // namespace lldb_private 206061da546Spatrick 207dda28197Spatrick #endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXPRESSIONVARIABLE_H 208