1 //===-- ClangExpressionVariable.h -------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #ifndef liblldb_ClangExpressionVariable_h_ 11 #define liblldb_ClangExpressionVariable_h_ 12 13 // C Includes 14 #include <signal.h> 15 #include <stdint.h> 16 #include <string.h> 17 18 // C++ Includes 19 #include <map> 20 #include <string> 21 #include <vector> 22 23 // Other libraries and framework includes 24 #include "llvm/Support/Casting.h" 25 26 // Project includes 27 #include "lldb/Core/ClangForward.h" 28 #include "lldb/Core/ConstString.h" 29 #include "lldb/Core/Value.h" 30 #include "lldb/Expression/ExpressionVariable.h" 31 #include "lldb/Symbol/TaggedASTType.h" 32 #include "lldb/lldb-public.h" 33 34 namespace llvm { 35 class Value; 36 } 37 38 namespace lldb_private { 39 40 class ValueObjectConstResult; 41 42 //---------------------------------------------------------------------- 43 /// @class ClangExpressionVariable ClangExpressionVariable.h 44 /// "lldb/Expression/ClangExpressionVariable.h" 45 /// @brief Encapsulates one variable for the expression parser. 46 /// 47 /// The expression parser uses variables in three different contexts: 48 /// 49 /// First, it stores persistent variables along with the process for use 50 /// in expressions. These persistent variables contain their own data 51 /// and are typed. 52 /// 53 /// Second, in an interpreted expression, it stores the local variables 54 /// for the expression along with the expression. These variables 55 /// contain their own data and are typed. 56 /// 57 /// Third, in a JIT-compiled expression, it stores the variables that 58 /// the expression needs to have materialized and dematerialized at each 59 /// execution. These do not contain their own data but are named and 60 /// typed. 61 /// 62 /// This class supports all of these use cases using simple type 63 /// polymorphism, and provides necessary support methods. Its interface 64 /// is RTTI-neutral. 65 //---------------------------------------------------------------------- 66 class ClangExpressionVariable : public ExpressionVariable { 67 public: 68 ClangExpressionVariable(ExecutionContextScope *exe_scope, 69 lldb::ByteOrder byte_order, uint32_t addr_byte_size); 70 71 ClangExpressionVariable(ExecutionContextScope *exe_scope, Value &value, 72 const ConstString &name, uint16_t flags = EVNone); 73 74 ClangExpressionVariable(const lldb::ValueObjectSP &valobj_sp); 75 76 ClangExpressionVariable(ExecutionContextScope *exe_scope, 77 const ConstString &name, 78 const TypeFromUser &user_type, 79 lldb::ByteOrder byte_order, uint32_t addr_byte_size); 80 81 //---------------------------------------------------------------------- 82 /// Utility functions for dealing with ExpressionVariableLists in 83 /// Clang-specific ways 84 //---------------------------------------------------------------------- 85 86 //---------------------------------------------------------------------- 87 /// Finds a variable by NamedDecl in the list. 88 /// 89 /// @param[in] name 90 /// The name of the requested variable. 91 /// 92 /// @return 93 /// The variable requested, or NULL if that variable is not in the list. 94 //---------------------------------------------------------------------- 95 static ClangExpressionVariable * 96 FindVariableInList(ExpressionVariableList &list, const clang::NamedDecl *decl, 97 uint64_t parser_id) { 98 lldb::ExpressionVariableSP var_sp; 99 for (size_t index = 0, size = list.GetSize(); index < size; ++index) { 100 var_sp = list.GetVariableAtIndex(index); 101 102 if (ClangExpressionVariable *clang_var = 103 llvm::dyn_cast<ClangExpressionVariable>(var_sp.get())) { 104 ClangExpressionVariable::ParserVars *parser_vars = 105 clang_var->GetParserVars(parser_id); 106 107 if (parser_vars && parser_vars->m_named_decl == decl) 108 return clang_var; 109 } 110 } 111 return nullptr; 112 } 113 114 //---------------------------------------------------------------------- 115 /// If the variable contains its own data, make a Value point at it. 116 /// If \a exe_ctx in not NULL, the value will be resolved in with 117 /// that execution context. 118 /// 119 /// @param[in] value 120 /// The value to point at the data. 121 /// 122 /// @param[in] exe_ctx 123 /// The execution context to use to resolve \a value. 124 /// 125 /// @return 126 /// True on success; false otherwise (in particular, if this variable 127 /// does not contain its own data). 128 //---------------------------------------------------------------------- 129 bool PointValueAtData(Value &value, ExecutionContext *exe_ctx); 130 131 //---------------------------------------------------------------------- 132 /// The following values should not live beyond parsing 133 //---------------------------------------------------------------------- 134 class ParserVars { 135 public: 136 ParserVars() 137 : m_parser_type(), m_named_decl(NULL), m_llvm_value(NULL), 138 m_lldb_value(), m_lldb_var(), m_lldb_sym(NULL) {} 139 140 TypeFromParser 141 m_parser_type; ///< The type of the variable according to the parser 142 const clang::NamedDecl 143 *m_named_decl; ///< The Decl corresponding to this variable 144 llvm::Value *m_llvm_value; ///< The IR value corresponding to this variable; 145 ///usually a GlobalValue 146 lldb_private::Value 147 m_lldb_value; ///< The value found in LLDB for this variable 148 lldb::VariableSP m_lldb_var; ///< The original variable for this variable 149 const lldb_private::Symbol *m_lldb_sym; ///< The original symbol for this 150 ///variable, if it was a symbol 151 }; 152 153 private: 154 typedef std::map<uint64_t, ParserVars> ParserVarMap; 155 ParserVarMap m_parser_vars; 156 157 public: 158 //---------------------------------------------------------------------- 159 /// Make this variable usable by the parser by allocating space for 160 /// parser-specific variables 161 //---------------------------------------------------------------------- 162 void EnableParserVars(uint64_t parser_id) { 163 m_parser_vars.insert(std::make_pair(parser_id, ParserVars())); 164 } 165 166 //---------------------------------------------------------------------- 167 /// Deallocate parser-specific variables 168 //---------------------------------------------------------------------- 169 void DisableParserVars(uint64_t parser_id) { m_parser_vars.erase(parser_id); } 170 171 //---------------------------------------------------------------------- 172 /// Access parser-specific variables 173 //---------------------------------------------------------------------- 174 ParserVars *GetParserVars(uint64_t parser_id) { 175 ParserVarMap::iterator i = m_parser_vars.find(parser_id); 176 177 if (i == m_parser_vars.end()) 178 return NULL; 179 else 180 return &i->second; 181 } 182 183 //---------------------------------------------------------------------- 184 /// The following values are valid if the variable is used by JIT code 185 //---------------------------------------------------------------------- 186 struct JITVars { 187 JITVars() : m_alignment(0), m_size(0), m_offset(0) {} 188 189 lldb::offset_t 190 m_alignment; ///< The required alignment of the variable, in bytes 191 size_t m_size; ///< The space required for the variable, in bytes 192 lldb::offset_t 193 m_offset; ///< The offset of the variable in the struct, in bytes 194 }; 195 196 private: 197 typedef std::map<uint64_t, JITVars> JITVarMap; 198 JITVarMap m_jit_vars; 199 200 public: 201 //---------------------------------------------------------------------- 202 /// Make this variable usable for materializing for the JIT by allocating 203 /// space for JIT-specific variables 204 //---------------------------------------------------------------------- 205 void EnableJITVars(uint64_t parser_id) { 206 m_jit_vars.insert(std::make_pair(parser_id, JITVars())); 207 } 208 209 //---------------------------------------------------------------------- 210 /// Deallocate JIT-specific variables 211 //---------------------------------------------------------------------- 212 void DisableJITVars(uint64_t parser_id) { m_jit_vars.erase(parser_id); } 213 214 JITVars *GetJITVars(uint64_t parser_id) { 215 JITVarMap::iterator i = m_jit_vars.find(parser_id); 216 217 if (i == m_jit_vars.end()) 218 return NULL; 219 else 220 return &i->second; 221 } 222 223 TypeFromUser GetTypeFromUser(); 224 225 //------------------------------------------------------------------ 226 // llvm casting support 227 //------------------------------------------------------------------ 228 static bool classof(const ExpressionVariable *ev) { 229 return ev->getKind() == ExpressionVariable::eKindClang; 230 } 231 232 //---------------------------------------------------------------------- 233 /// Members 234 //---------------------------------------------------------------------- 235 DISALLOW_COPY_AND_ASSIGN(ClangExpressionVariable); 236 }; 237 238 } // namespace lldb_private 239 240 #endif // liblldb_ClangExpressionVariable_h_ 241