@@ -2559,6 +2559,83 @@ bool DWARFExpression::Evaluate(
2559
2559
stack.back ().SetValueType (Value::eValueTypeScalar);
2560
2560
break ;
2561
2561
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
+
2562
2639
// OPCODE: DW_OP_call_frame_cfa
2563
2640
// OPERANDS: None
2564
2641
// DESCRIPTION: Specifies a DWARF expression that pushes the value of
0 commit comments