static lldb::Format GetItemFormatForFormat (lldb::Format format, ClangASTType element_type) { switch (format) { case lldb::eFormatVectorOfChar: return lldb::eFormatChar; case lldb::eFormatVectorOfFloat32: case lldb::eFormatVectorOfFloat64: return lldb::eFormatFloat; case lldb::eFormatVectorOfSInt16: case lldb::eFormatVectorOfSInt32: case lldb::eFormatVectorOfSInt64: case lldb::eFormatVectorOfSInt8: return lldb::eFormatDecimal; case lldb::eFormatVectorOfUInt128: case lldb::eFormatVectorOfUInt16: case lldb::eFormatVectorOfUInt32: case lldb::eFormatVectorOfUInt64: case lldb::eFormatVectorOfUInt8: return lldb::eFormatUnsigned; case lldb::eFormatBinary: case lldb::eFormatComplexInteger: case lldb::eFormatDecimal: case lldb::eFormatEnum: case lldb::eFormatInstruction: case lldb::eFormatOSType: case lldb::eFormatVoid: return eFormatHex; case lldb::eFormatDefault: { // special case the (default, char) combination to actually display as an integer value // most often, you won't want to see the ASCII characters... (and if you do, eFormatChar is a keystroke away) bool is_char = element_type.IsCharType(); bool is_signed = false; element_type.IsIntegerType(is_signed); return is_char ? (is_signed ? lldb::eFormatDecimal : eFormatHex) : format; } break; default: return format; } }
static size_t CalculateNumChildren (ClangASTType container_type, ClangASTType element_type, lldb_private::ExecutionContextScope *exe_scope = nullptr // does not matter here because all we trade in are basic types ) { auto container_size = container_type.GetByteSize(exe_scope); auto element_size = element_type.GetByteSize(exe_scope); if (element_size) { if (container_size % element_size) return 0; return container_size / element_size; } return 0; }
ValueObjectSP ABI::GetReturnValueObject (Thread &thread, ClangASTType &ast_type) const { if (!ast_type.IsValid()) return ValueObjectSP(); Value ret_value; ret_value.SetContext(Value::eContextTypeClangType, ast_type.GetOpaqueQualType()); if (GetReturnValue (thread, ret_value)) { return ValueObjectConstResult::Create( thread.GetStackFrameAtIndex(0).get(), ast_type.GetASTContext(), ret_value, ConstString("FunctionReturn")); } else return ValueObjectSP(); }
SBType::SBType (const ClangASTType &type) : m_opaque_sp(new TypeImpl(ClangASTType(type.GetASTContext(), type.GetOpaqueQualType()))) { }
ValueObjectSP ABI::GetReturnValueObject (Thread &thread, ClangASTType &ast_type, bool persistent) const { if (!ast_type.IsValid()) return ValueObjectSP(); ValueObjectSP return_valobj_sp; return_valobj_sp = GetReturnValueObjectImpl(thread, ast_type); if (!return_valobj_sp) return return_valobj_sp; // Now turn this into a persistent variable. // FIXME: This code is duplicated from Target::EvaluateExpression, and it is used in similar form in a couple // of other places. Figure out the correct Create function to do all this work. if (persistent) { ClangPersistentVariables& persistent_variables = thread.CalculateTarget()->GetPersistentVariables(); ConstString persistent_variable_name (persistent_variables.GetNextPersistentVariableName()); lldb::ValueObjectSP const_valobj_sp; // Check in case our value is already a constant value if (return_valobj_sp->GetIsConstant()) { const_valobj_sp = return_valobj_sp; const_valobj_sp->SetName (persistent_variable_name); } else const_valobj_sp = return_valobj_sp->CreateConstantValue (persistent_variable_name); lldb::ValueObjectSP live_valobj_sp = return_valobj_sp; return_valobj_sp = const_valobj_sp; ClangExpressionVariableSP clang_expr_variable_sp(persistent_variables.CreatePersistentVariable(return_valobj_sp)); assert (clang_expr_variable_sp.get()); // Set flags and live data as appropriate const Value &result_value = live_valobj_sp->GetValue(); switch (result_value.GetValueType()) { case Value::eValueTypeHostAddress: case Value::eValueTypeFileAddress: // we don't do anything with these for now break; case Value::eValueTypeScalar: case Value::eValueTypeVector: clang_expr_variable_sp->m_flags |= ClangExpressionVariable::EVIsFreezeDried; clang_expr_variable_sp->m_flags |= ClangExpressionVariable::EVIsLLDBAllocated; clang_expr_variable_sp->m_flags |= ClangExpressionVariable::EVNeedsAllocation; break; case Value::eValueTypeLoadAddress: clang_expr_variable_sp->m_live_sp = live_valobj_sp; clang_expr_variable_sp->m_flags |= ClangExpressionVariable::EVIsProgramReference; break; } return_valobj_sp = clang_expr_variable_sp->GetValueObject(); } return return_valobj_sp; }
static void PrivateAutoComplete (StackFrame *frame, const std::string &partial_path, const std::string &prefix_path, // Anything that has been resolved already will be in here const ClangASTType& clang_type, StringList &matches, bool &word_complete) { // printf ("\nPrivateAutoComplete()\n\tprefix_path = '%s'\n\tpartial_path = '%s'\n", prefix_path.c_str(), partial_path.c_str()); std::string remaining_partial_path; const lldb::TypeClass type_class = clang_type.GetTypeClass(); if (partial_path.empty()) { if (clang_type.IsValid()) { switch (type_class) { default: case eTypeClassArray: case eTypeClassBlockPointer: case eTypeClassBuiltin: case eTypeClassComplexFloat: case eTypeClassComplexInteger: case eTypeClassEnumeration: case eTypeClassFunction: case eTypeClassMemberPointer: case eTypeClassReference: case eTypeClassTypedef: case eTypeClassVector: { matches.AppendString (prefix_path); word_complete = matches.GetSize() == 1; } break; case eTypeClassClass: case eTypeClassStruct: case eTypeClassUnion: if (prefix_path.back() != '.') matches.AppendString (prefix_path + '.'); break; case eTypeClassObjCObject: case eTypeClassObjCInterface: break; case eTypeClassObjCObjectPointer: case eTypeClassPointer: { bool omit_empty_base_classes = true; if (clang_type.GetNumChildren (omit_empty_base_classes) > 0) matches.AppendString (prefix_path + "->"); else { matches.AppendString (prefix_path); word_complete = true; } } break; } } else { if (frame) { const bool get_file_globals = true; VariableList *variable_list = frame->GetVariableList(get_file_globals); if (variable_list) { const size_t num_variables = variable_list->GetSize(); for (size_t i=0; i<num_variables; ++i) { Variable *variable = variable_list->GetVariableAtIndex(i).get(); matches.AppendString (variable->GetName().AsCString()); } } } } } else { const char ch = partial_path[0]; switch (ch) { case '*': if (prefix_path.empty()) { PrivateAutoComplete (frame, partial_path.substr(1), std::string("*"), clang_type, matches, word_complete); } break; case '&': if (prefix_path.empty()) { PrivateAutoComplete (frame, partial_path.substr(1), std::string("&"), clang_type, matches, word_complete); } break; case '-': if (partial_path[1] == '>' && !prefix_path.empty()) { switch (type_class) { case lldb::eTypeClassPointer: { ClangASTType pointee_type(clang_type.GetPointeeType()); if (partial_path[2]) { // If there is more after the "->", then search deeper PrivateAutoComplete (frame, partial_path.substr(2), prefix_path + "->", pointee_type.GetCanonicalType(), matches, word_complete); } else { // Nothing after the "->", so list all members PrivateAutoCompleteMembers (frame, std::string(), std::string(), prefix_path + "->", pointee_type.GetCanonicalType(), matches, word_complete); } } default: break; } } break; case '.': if (clang_type.IsValid()) { switch (type_class) { case lldb::eTypeClassUnion: case lldb::eTypeClassStruct: case lldb::eTypeClassClass: if (partial_path[1]) { // If there is more after the ".", then search deeper PrivateAutoComplete (frame, partial_path.substr(1), prefix_path + ".", clang_type, matches, word_complete); } else { // Nothing after the ".", so list all members PrivateAutoCompleteMembers (frame, std::string(), partial_path, prefix_path + ".", clang_type, matches, word_complete); } default: break; } } break; default: if (isalpha(ch) || ch == '_' || ch == '$') { const size_t partial_path_len = partial_path.size(); size_t pos = 1; while (pos < partial_path_len) { const char curr_ch = partial_path[pos]; if (isalnum(curr_ch) || curr_ch == '_' || curr_ch == '$') { ++pos; continue; } break; } std::string token(partial_path, 0, pos); remaining_partial_path = partial_path.substr(pos); if (clang_type.IsValid()) { PrivateAutoCompleteMembers (frame, token, remaining_partial_path, prefix_path, clang_type, matches, word_complete); } else if (frame) { // We haven't found our variable yet const bool get_file_globals = true; VariableList *variable_list = frame->GetVariableList(get_file_globals); if (!variable_list) break; const size_t num_variables = variable_list->GetSize(); for (size_t i=0; i<num_variables; ++i) { Variable *variable = variable_list->GetVariableAtIndex(i).get(); if (!variable) continue; const char *variable_name = variable->GetName().AsCString(); if (strstr(variable_name, token.c_str()) == variable_name) { if (strcmp (variable_name, token.c_str()) == 0) { Type *variable_type = variable->GetType(); if (variable_type) { ClangASTType variable_clang_type (variable_type->GetClangForwardType()); PrivateAutoComplete (frame, remaining_partial_path, prefix_path + token, // Anything that has been resolved already will be in here variable_clang_type.GetCanonicalType(), matches, word_complete); } else { matches.AppendString (prefix_path + variable_name); } } else if (remaining_partial_path.empty()) { matches.AppendString (prefix_path + variable_name); } } } } } break; } } }
static void PrivateAutoCompleteMembers (StackFrame *frame, const std::string &partial_member_name, const std::string &partial_path, const std::string &prefix_path, // Anything that has been resolved already will be in here const ClangASTType& clang_type, StringList &matches, bool &word_complete) { // We are in a type parsing child members const uint32_t num_bases = clang_type.GetNumDirectBaseClasses(); if (num_bases > 0) { for (uint32_t i = 0; i < num_bases; ++i) { ClangASTType base_class_type (clang_type.GetDirectBaseClassAtIndex (i, nullptr)); PrivateAutoCompleteMembers (frame, partial_member_name, partial_path, prefix_path, base_class_type.GetCanonicalType(), matches, word_complete); } } const uint32_t num_vbases = clang_type.GetNumVirtualBaseClasses(); if (num_vbases > 0) { for (uint32_t i = 0; i < num_vbases; ++i) { ClangASTType vbase_class_type (clang_type.GetVirtualBaseClassAtIndex(i,nullptr)); PrivateAutoCompleteMembers (frame, partial_member_name, partial_path, prefix_path, vbase_class_type.GetCanonicalType(), matches, word_complete); } } // We are in a type parsing child members const uint32_t num_fields = clang_type.GetNumFields(); if (num_fields > 0) { for (uint32_t i = 0; i < num_fields; ++i) { std::string member_name; ClangASTType member_clang_type = clang_type.GetFieldAtIndex (i, member_name, nullptr, nullptr, nullptr); if (partial_member_name.empty() || member_name.find(partial_member_name) == 0) { if (member_name == partial_member_name) { PrivateAutoComplete (frame, partial_path, prefix_path + member_name, // Anything that has been resolved already will be in here member_clang_type.GetCanonicalType(), matches, word_complete); } else { matches.AppendString (prefix_path + member_name); } } } } }
ValueObjectSP ABISysV_ppc::GetReturnValueObjectImpl (Thread &thread, ClangASTType &return_clang_type) const { ValueObjectSP return_valobj_sp; if (!return_clang_type) return return_valobj_sp; ExecutionContext exe_ctx (thread.shared_from_this()); return_valobj_sp = GetReturnValueObjectSimple(thread, return_clang_type); if (return_valobj_sp) return return_valobj_sp; RegisterContextSP reg_ctx_sp = thread.GetRegisterContext(); if (!reg_ctx_sp) return return_valobj_sp; const size_t bit_width = return_clang_type.GetBitSize(&thread); if (return_clang_type.IsAggregateType()) { Target *target = exe_ctx.GetTargetPtr(); bool is_memory = true; if (bit_width <= 128) { ByteOrder target_byte_order = target->GetArchitecture().GetByteOrder(); DataBufferSP data_sp (new DataBufferHeap(16, 0)); DataExtractor return_ext (data_sp, target_byte_order, target->GetArchitecture().GetAddressByteSize()); const RegisterInfo *r3_info = reg_ctx_sp->GetRegisterInfoByName("r3", 0); const RegisterInfo *rdx_info = reg_ctx_sp->GetRegisterInfoByName("rdx", 0); RegisterValue r3_value, rdx_value; reg_ctx_sp->ReadRegister (r3_info, r3_value); reg_ctx_sp->ReadRegister (rdx_info, rdx_value); DataExtractor r3_data, rdx_data; r3_value.GetData(r3_data); rdx_value.GetData(rdx_data); uint32_t fp_bytes = 0; // Tracks how much of the xmm registers we've consumed so far uint32_t integer_bytes = 0; // Tracks how much of the r3/rds registers we've consumed so far const uint32_t num_children = return_clang_type.GetNumFields (); // Since we are in the small struct regime, assume we are not in memory. is_memory = false; for (uint32_t idx = 0; idx < num_children; idx++) { std::string name; uint64_t field_bit_offset = 0; bool is_signed; bool is_complex; uint32_t count; ClangASTType field_clang_type = return_clang_type.GetFieldAtIndex (idx, name, &field_bit_offset, NULL, NULL); const size_t field_bit_width = field_clang_type.GetBitSize(&thread); // If there are any unaligned fields, this is stored in memory. if (field_bit_offset % field_bit_width != 0) { is_memory = true; break; } uint32_t field_byte_width = field_bit_width/8; uint32_t field_byte_offset = field_bit_offset/8; DataExtractor *copy_from_extractor = NULL; uint32_t copy_from_offset = 0; if (field_clang_type.IsIntegerType (is_signed) || field_clang_type.IsPointerType ()) { if (integer_bytes < 8) { if (integer_bytes + field_byte_width <= 8) { // This is in RAX, copy from register to our result structure: copy_from_extractor = &r3_data; copy_from_offset = integer_bytes; integer_bytes += field_byte_width; } else { // The next field wouldn't fit in the remaining space, so we pushed it to rdx. copy_from_extractor = &rdx_data; copy_from_offset = 0; integer_bytes = 8 + field_byte_width; } } else if (integer_bytes + field_byte_width <= 16) { copy_from_extractor = &rdx_data; copy_from_offset = integer_bytes - 8; integer_bytes += field_byte_width; } else { // The last field didn't fit. I can't see how that would happen w/o the overall size being // greater than 16 bytes. For now, return a NULL return value object. return return_valobj_sp; } } else if (field_clang_type.IsFloatingPointType (count, is_complex)) { // Structs with long doubles are always passed in memory. if (field_bit_width == 128) { is_memory = true; break; } else if (field_bit_width == 64) { copy_from_offset = 0; fp_bytes += field_byte_width; } else if (field_bit_width == 32) { // This one is kind of complicated. If we are in an "eightbyte" with another float, we'll // be stuffed into an xmm register with it. If we are in an "eightbyte" with one or more ints, // then we will be stuffed into the appropriate GPR with them. bool in_gpr; if (field_byte_offset % 8 == 0) { // We are at the beginning of one of the eightbytes, so check the next element (if any) if (idx == num_children - 1) in_gpr = false; else { uint64_t next_field_bit_offset = 0; ClangASTType next_field_clang_type = return_clang_type.GetFieldAtIndex (idx + 1, name, &next_field_bit_offset, NULL, NULL); if (next_field_clang_type.IsIntegerType (is_signed)) in_gpr = true; else { copy_from_offset = 0; in_gpr = false; } } } else if (field_byte_offset % 4 == 0) { // We are inside of an eightbyte, so see if the field before us is floating point: // This could happen if somebody put padding in the structure. if (idx == 0) in_gpr = false; else { uint64_t prev_field_bit_offset = 0; ClangASTType prev_field_clang_type = return_clang_type.GetFieldAtIndex (idx - 1, name, &prev_field_bit_offset, NULL, NULL); if (prev_field_clang_type.IsIntegerType (is_signed)) in_gpr = true; else { copy_from_offset = 4; in_gpr = false; } } } else { is_memory = true; continue; } // Okay, we've figured out whether we are in GPR or XMM, now figure out which one. if (in_gpr) { if (integer_bytes < 8) { // This is in RAX, copy from register to our result structure: copy_from_extractor = &r3_data; copy_from_offset = integer_bytes; integer_bytes += field_byte_width; } else { copy_from_extractor = &rdx_data; copy_from_offset = integer_bytes - 8; integer_bytes += field_byte_width; } } else { fp_bytes += field_byte_width; } } } // These two tests are just sanity checks. If I somehow get the // type calculation wrong above it is better to just return nothing // than to assert or crash. if (!copy_from_extractor) return return_valobj_sp; if (copy_from_offset + field_byte_width > copy_from_extractor->GetByteSize()) return return_valobj_sp; copy_from_extractor->CopyByteOrderedData (copy_from_offset, field_byte_width, data_sp->GetBytes() + field_byte_offset, field_byte_width, target_byte_order); } if (!is_memory) { // The result is in our data buffer. Let's make a variable object out of it: return_valobj_sp = ValueObjectConstResult::Create (&thread, return_clang_type, ConstString(""), return_ext); } } // FIXME: This is just taking a guess, r3 may very well no longer hold the return storage location. // If we are going to do this right, when we make a new frame we should check to see if it uses a memory // return, and if we are at the first instruction and if so stash away the return location. Then we would // only return the memory return value if we know it is valid. if (is_memory) { unsigned r3_id = reg_ctx_sp->GetRegisterInfoByName("r3", 0)->kinds[eRegisterKindLLDB]; lldb::addr_t storage_addr = (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(r3_id, 0); return_valobj_sp = ValueObjectMemory::Create (&thread, "", Address (storage_addr, NULL), return_clang_type); } } return return_valobj_sp; }
ValueObjectSP ABISysV_ppc::GetReturnValueObjectSimple (Thread &thread, ClangASTType &return_clang_type) const { ValueObjectSP return_valobj_sp; Value value; if (!return_clang_type) return return_valobj_sp; //value.SetContext (Value::eContextTypeClangType, return_value_type); value.SetClangType (return_clang_type); RegisterContext *reg_ctx = thread.GetRegisterContext().get(); if (!reg_ctx) return return_valobj_sp; const uint32_t type_flags = return_clang_type.GetTypeInfo (); if (type_flags & eTypeIsScalar) { value.SetValueType(Value::eValueTypeScalar); bool success = false; if (type_flags & eTypeIsInteger) { // Extract the register context so we can read arguments from registers const size_t byte_size = return_clang_type.GetByteSize(nullptr); uint64_t raw_value = thread.GetRegisterContext()->ReadRegisterAsUnsigned(reg_ctx->GetRegisterInfoByName("r3", 0), 0); const bool is_signed = (type_flags & eTypeIsSigned) != 0; switch (byte_size) { default: break; case sizeof(uint64_t): if (is_signed) value.GetScalar() = (int64_t)(raw_value); else value.GetScalar() = (uint64_t)(raw_value); success = true; break; case sizeof(uint32_t): if (is_signed) value.GetScalar() = (int32_t)(raw_value & UINT32_MAX); else value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX); success = true; break; case sizeof(uint16_t): if (is_signed) value.GetScalar() = (int16_t)(raw_value & UINT16_MAX); else value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX); success = true; break; case sizeof(uint8_t): if (is_signed) value.GetScalar() = (int8_t)(raw_value & UINT8_MAX); else value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX); success = true; break; } } else if (type_flags & eTypeIsFloat) { if (type_flags & eTypeIsComplex) { // Don't handle complex yet. } else { const size_t byte_size = return_clang_type.GetByteSize(nullptr); if (byte_size <= sizeof(long double)) { const RegisterInfo *f1_info = reg_ctx->GetRegisterInfoByName("f1", 0); RegisterValue f1_value; if (reg_ctx->ReadRegister (f1_info, f1_value)) { DataExtractor data; if (f1_value.GetData(data)) { lldb::offset_t offset = 0; if (byte_size == sizeof(float)) { value.GetScalar() = (float) data.GetFloat(&offset); success = true; } else if (byte_size == sizeof(double)) { value.GetScalar() = (double) data.GetDouble(&offset); success = true; } } } } } } if (success) return_valobj_sp = ValueObjectConstResult::Create (thread.GetStackFrameAtIndex(0).get(), value, ConstString("")); } else if (type_flags & eTypeIsPointer) { unsigned r3_id = reg_ctx->GetRegisterInfoByName("r3", 0)->kinds[eRegisterKindLLDB]; value.GetScalar() = (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(r3_id, 0); value.SetValueType(Value::eValueTypeScalar); return_valobj_sp = ValueObjectConstResult::Create (thread.GetStackFrameAtIndex(0).get(), value, ConstString("")); } else if (type_flags & eTypeIsVector) { const size_t byte_size = return_clang_type.GetByteSize(nullptr); if (byte_size > 0) { const RegisterInfo *altivec_reg = reg_ctx->GetRegisterInfoByName("v2", 0); if (altivec_reg) { if (byte_size <= altivec_reg->byte_size) { ProcessSP process_sp (thread.GetProcess()); if (process_sp) { std::unique_ptr<DataBufferHeap> heap_data_ap (new DataBufferHeap(byte_size, 0)); const ByteOrder byte_order = process_sp->GetByteOrder(); RegisterValue reg_value; if (reg_ctx->ReadRegister(altivec_reg, reg_value)) { Error error; if (reg_value.GetAsMemoryData (altivec_reg, heap_data_ap->GetBytes(), heap_data_ap->GetByteSize(), byte_order, error)) { DataExtractor data (DataBufferSP (heap_data_ap.release()), byte_order, process_sp->GetTarget().GetArchitecture().GetAddressByteSize()); return_valobj_sp = ValueObjectConstResult::Create (&thread, return_clang_type, ConstString(""), data); } } } } } } } return return_valobj_sp; }
ValueObjectSP ABISysV_mips64::GetReturnValueObjectImpl (Thread &thread, ClangASTType &return_clang_type) const { ValueObjectSP return_valobj_sp; Value value; ExecutionContext exe_ctx (thread.shared_from_this()); if (exe_ctx.GetTargetPtr() == NULL || exe_ctx.GetProcessPtr() == NULL) return return_valobj_sp; value.SetClangType(return_clang_type); RegisterContext *reg_ctx = thread.GetRegisterContext().get(); if (!reg_ctx) return return_valobj_sp; const size_t byte_size = return_clang_type.GetByteSize(nullptr); const uint32_t type_flags = return_clang_type.GetTypeInfo (NULL); if (type_flags & eTypeIsScalar) { value.SetValueType(Value::eValueTypeScalar); bool success = false; if (type_flags & eTypeIsInteger) { // Extract the register context so we can read arguments from registers // In MIPS register "r2" (v0) holds the integer function return values uint64_t raw_value = reg_ctx->ReadRegisterAsUnsigned(reg_ctx->GetRegisterInfoByName("r2", 0), 0); const bool is_signed = (type_flags & eTypeIsSigned) != 0; switch (byte_size) { default: break; case sizeof(uint64_t): if (is_signed) value.GetScalar() = (int64_t)(raw_value); else value.GetScalar() = (uint64_t)(raw_value); success = true; break; case sizeof(uint32_t): if (is_signed) value.GetScalar() = (int32_t)(raw_value & UINT32_MAX); else value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX); success = true; break; case sizeof(uint16_t): if (is_signed) value.GetScalar() = (int16_t)(raw_value & UINT16_MAX); else value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX); success = true; break; case sizeof(uint8_t): if (is_signed) value.GetScalar() = (int8_t)(raw_value & UINT8_MAX); else value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX); success = true; break; } } if (success) return_valobj_sp = ValueObjectConstResult::Create (thread.GetStackFrameAtIndex(0).get(), value, ConstString("")); } else if (type_flags & eTypeIsPointer) { value.SetValueType(Value::eValueTypeScalar); uint64_t raw_value = reg_ctx->ReadRegisterAsUnsigned(reg_ctx->GetRegisterInfoByName("r2", 0), 0); value.GetScalar() = (uint64_t)(raw_value); return_valobj_sp = ValueObjectConstResult::Create (thread.GetStackFrameAtIndex(0).get(), value, ConstString("")); } else if (type_flags & eTypeIsVector) { // TODO: Handle vector types } return return_valobj_sp; }