@@ -2559,6 +2559,83 @@ bool DWARFExpression::Evaluate(
25592559 stack.back ().SetValueType (Value::eValueTypeScalar);
25602560 break ;
25612561
2562+ // OPCODE: DW_OP_convert
2563+ // OPERANDS: 1
2564+ // A ULEB128 that is either a DIE offset of a
2565+ // DW_TAG_base_type or 0 for the generic (pointer-sized) type.
2566+ //
2567+ // DESCRIPTION: Pop the top stack element, convert it to a
2568+ // different type, and push the result.
2569+ case DW_OP_convert: {
2570+ if (stack.size () < 1 ) {
2571+ if (error_ptr)
2572+ error_ptr->SetErrorString (
2573+ " Expression stack needs at least 1 item for DW_OP_convert." );
2574+ return false ;
2575+ }
2576+ const uint64_t die_offset = opcodes.GetULEB128 (&offset);
2577+ Scalar::Type type = Scalar::e_void;
2578+ uint64_t bit_size;
2579+ if (die_offset == 0 ) {
2580+ // The generic type has the size of an address on the target
2581+ // machine and an unspecified signedness. Scalar has no
2582+ // "unspecified signedness", so we use unsigned types.
2583+ if (!module_sp) {
2584+ if (error_ptr)
2585+ error_ptr->SetErrorString (" No module" );
2586+ return false ;
2587+ }
2588+ bit_size = module_sp->GetArchitecture ().GetAddressByteSize () * 8 ;
2589+ if (!bit_size) {
2590+ if (error_ptr)
2591+ error_ptr->SetErrorString (" unspecified architecture" );
2592+ return false ;
2593+ }
2594+ type = Scalar::GetBestTypeForBitSize (bit_size, false );
2595+ } else {
2596+ // Retrieve the type DIE that the value is being converted to.
2597+ // FIXME: the constness has annoying ripple effects.
2598+ DWARFDIE die = const_cast <DWARFUnit *>(dwarf_cu)->GetDIE (die_offset);
2599+ if (!die) {
2600+ if (error_ptr)
2601+ error_ptr->SetErrorString (" Cannot resolve DW_OP_convert type DIE" );
2602+ return false ;
2603+ }
2604+ uint64_t encoding =
2605+ die.GetAttributeValueAsUnsigned (DW_AT_encoding, DW_ATE_hi_user);
2606+ bit_size = die.GetAttributeValueAsUnsigned (DW_AT_byte_size, 0 ) * 8 ;
2607+ if (!bit_size)
2608+ bit_size = die.GetAttributeValueAsUnsigned (DW_AT_bit_size, 0 );
2609+ if (!bit_size) {
2610+ if (error_ptr)
2611+ error_ptr->SetErrorString (" Unsupported type size in DW_OP_convert" );
2612+ return false ;
2613+ }
2614+ switch (encoding) {
2615+ case DW_ATE_signed:
2616+ case DW_ATE_signed_char:
2617+ type = Scalar::GetBestTypeForBitSize (bit_size, true );
2618+ break ;
2619+ case DW_ATE_unsigned:
2620+ case DW_ATE_unsigned_char:
2621+ type = Scalar::GetBestTypeForBitSize (bit_size, false );
2622+ break ;
2623+ default :
2624+ if (error_ptr)
2625+ error_ptr->SetErrorString (" Unsupported encoding in DW_OP_convert" );
2626+ return false ;
2627+ }
2628+ }
2629+ if (type == Scalar::e_void) {
2630+ if (error_ptr)
2631+ error_ptr->SetErrorString (" Unsupported pointer size" );
2632+ return false ;
2633+ }
2634+ Scalar &top = stack.back ().ResolveValue (exe_ctx);
2635+ top.TruncOrExtendTo (type, bit_size);
2636+ break ;
2637+ }
2638+
25622639 // OPCODE: DW_OP_call_frame_cfa
25632640 // OPERANDS: None
25642641 // DESCRIPTION: Specifies a DWARF expression that pushes the value of
0 commit comments