213 lines · c
1//===-- ClangExpressionVariable.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-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXPRESSIONVARIABLE_H10#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXPRESSIONVARIABLE_H11 12#include <csignal>13#include <cstdint>14#include <cstring>15 16#include <map>17#include <string>18#include <vector>19 20#include "llvm/Support/Casting.h"21 22#include "lldb/Core/Value.h"23#include "lldb/Expression/ExpressionVariable.h"24#include "lldb/Symbol/TaggedASTType.h"25#include "lldb/Utility/ConstString.h"26#include "lldb/lldb-public.h"27 28namespace llvm {29class Value;30}31 32namespace clang {33class NamedDecl;34}35 36namespace lldb_private {37 38class ValueObjectConstResult;39 40/// \class ClangExpressionVariable ClangExpressionVariable.h41/// "lldb/Expression/ClangExpressionVariable.h" Encapsulates one variable for42/// the expression parser.43///44/// The expression parser uses variables in three different contexts:45///46/// First, it stores persistent variables along with the process for use in47/// expressions. These persistent variables contain their own data and are48/// typed.49///50/// Second, in an interpreted expression, it stores the local variables for51/// the expression along with the expression. These variables contain their52/// own data and are typed.53///54/// Third, in a JIT-compiled expression, it stores the variables that the55/// expression needs to have materialized and dematerialized at each56/// execution. These do not contain their own data but are named and typed.57///58/// This class supports all of these use cases using simple type polymorphism,59/// and provides necessary support methods. Its interface is RTTI-neutral.60class ClangExpressionVariable61 : public llvm::RTTIExtends<ClangExpressionVariable, ExpressionVariable> {62public:63 // LLVM RTTI support64 static char ID;65 66 ClangExpressionVariable(ExecutionContextScope *exe_scope,67 lldb::ByteOrder byte_order, uint32_t addr_byte_size);68 69 ClangExpressionVariable(ExecutionContextScope *exe_scope, Value &value,70 ConstString name, uint16_t flags = EVNone);71 72 ClangExpressionVariable(const lldb::ValueObjectSP &valobj_sp);73 74 ClangExpressionVariable(ExecutionContextScope *exe_scope,75 ConstString name,76 const TypeFromUser &user_type,77 lldb::ByteOrder byte_order, uint32_t addr_byte_size);78 79 /// Utility functions for dealing with ExpressionVariableLists in Clang-80 /// specific ways81 82 /// Finds a variable by NamedDecl in the list.83 ///84 /// \return85 /// The variable requested, or NULL if that variable is not in the list.86 static ClangExpressionVariable *87 FindVariableInList(ExpressionVariableList &list, const clang::NamedDecl *decl,88 uint64_t parser_id) {89 lldb::ExpressionVariableSP var_sp;90 for (size_t index = 0, size = list.GetSize(); index < size; ++index) {91 var_sp = list.GetVariableAtIndex(index);92 93 if (ClangExpressionVariable *clang_var =94 llvm::dyn_cast<ClangExpressionVariable>(var_sp.get())) {95 ClangExpressionVariable::ParserVars *parser_vars =96 clang_var->GetParserVars(parser_id);97 98 if (parser_vars && parser_vars->m_named_decl == decl)99 return clang_var;100 }101 }102 return nullptr;103 }104 105 /// If the variable contains its own data, make a Value point at it. If \a106 /// exe_ctx in not NULL, the value will be resolved in with that execution107 /// context.108 ///109 /// \param[in] value110 /// The value to point at the data.111 ///112 /// \param[in] exe_ctx113 /// The execution context to use to resolve \a value.114 ///115 /// \return116 /// True on success; false otherwise (in particular, if this variable117 /// does not contain its own data).118 bool PointValueAtData(Value &value, ExecutionContext *exe_ctx);119 120 /// The following values should not live beyond parsing121 class ParserVars {122 public:123 ParserVars() = default;124 125 const clang::NamedDecl *m_named_decl =126 nullptr; ///< The Decl corresponding to this variable127 llvm::Value *m_llvm_value =128 nullptr; ///< The IR value corresponding to this variable;129 /// usually a GlobalValue130 lldb_private::Value131 m_lldb_value; ///< The value found in LLDB for this variable132 lldb::VariableSP m_lldb_var; ///< The original variable for this variable133 const lldb_private::Symbol *m_lldb_sym =134 nullptr; ///< The original symbol for this135 /// variable, if it was a symbol136 137 /// Callback that provides a ValueObject for the138 /// specified frame. Used by the materializer for139 /// re-fetching ValueObjects when materializing140 /// ivars.141 ValueObjectProviderTy m_lldb_valobj_provider;142 };143 144private:145 typedef std::map<uint64_t, ParserVars> ParserVarMap;146 ParserVarMap m_parser_vars;147 148public:149 /// Make this variable usable by the parser by allocating space for parser-150 /// specific variables151 void EnableParserVars(uint64_t parser_id) {152 m_parser_vars.insert(std::make_pair(parser_id, ParserVars()));153 }154 155 /// Deallocate parser-specific variables156 void DisableParserVars(uint64_t parser_id) { m_parser_vars.erase(parser_id); }157 158 /// Access parser-specific variables159 ParserVars *GetParserVars(uint64_t parser_id) {160 ParserVarMap::iterator i = m_parser_vars.find(parser_id);161 162 if (i == m_parser_vars.end())163 return nullptr;164 else165 return &i->second;166 }167 168 /// The following values are valid if the variable is used by JIT code169 struct JITVars {170 JITVars() = default;171 172 lldb::offset_t m_alignment =173 0; ///< The required alignment of the variable, in bytes174 size_t m_size = 0; ///< The space required for the variable, in bytes175 lldb::offset_t m_offset =176 0; ///< The offset of the variable in the struct, in bytes177 };178 179private:180 typedef std::map<uint64_t, JITVars> JITVarMap;181 JITVarMap m_jit_vars;182 183public:184 /// Make this variable usable for materializing for the JIT by allocating185 /// space for JIT-specific variables186 void EnableJITVars(uint64_t parser_id) {187 m_jit_vars.insert(std::make_pair(parser_id, JITVars()));188 }189 190 /// Deallocate JIT-specific variables191 void DisableJITVars(uint64_t parser_id) { m_jit_vars.erase(parser_id); }192 193 JITVars *GetJITVars(uint64_t parser_id) {194 JITVarMap::iterator i = m_jit_vars.find(parser_id);195 196 if (i == m_jit_vars.end())197 return nullptr;198 else199 return &i->second;200 }201 202 TypeFromUser GetTypeFromUser();203 204 /// Members205 ClangExpressionVariable(const ClangExpressionVariable &) = delete;206 const ClangExpressionVariable &207 operator=(const ClangExpressionVariable &) = delete;208};209 210} // namespace lldb_private211 212#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXPRESSIONVARIABLE_H213