Te_Field, /* struct/class field defn */
Te_Bound, /* array bounds indication, for one dimension */
Te_TyBase, /* base type */
- Te_TyPorR, /* pointer or reference type */
+ Te_TyPtr, /* pointer type */
+ Te_TyRef, /* reference type */
+ Te_TyPtrMbr, /* pointer to member type */
+ Te_TyRvalRef,/* rvalue reference type */
Te_TyTyDef, /* a renaming of some other type */
Te_TyStOrUn, /* structure or union type */
Te_TyEnum, /* an enum type */
struct {
Int szB;
UWord typeR;
- Bool isPtr;
} TyPorR;
struct {
UChar* name; /* in mallocville */
goto acquire_Type;
}
+ /*
+ * An example of DW_TAG_rvalue_reference_type:
+ *
+ * $ readelf --debug-dump /usr/lib/debug/usr/lib/libstdc++.so.6.0.16.debug
+ * <1><1014>: Abbrev Number: 55 (DW_TAG_rvalue_reference_type)
+ * <1015> DW_AT_byte_size : 4
+ * <1016> DW_AT_type : <0xe52>
+ */
if (dtag == DW_TAG_pointer_type || dtag == DW_TAG_reference_type
- || dtag == DW_TAG_ptr_to_member_type) {
+ || dtag == DW_TAG_ptr_to_member_type
+ || dtag == DW_TAG_rvalue_reference_type) {
/* This seems legit for _pointer_type and _reference_type. I
don't know if rolling _ptr_to_member_type in here really is
legit, but it's better than not handling it at all. */
VG_(memset)(&typeE, 0, sizeof(typeE));
typeE.cuOff = D3_INVALID_CUOFF;
- typeE.tag = Te_TyPorR;
+ switch (dtag) {
+ case DW_TAG_pointer_type:
+ typeE.tag = Te_TyPtr;
+ break;
+ case DW_TAG_reference_type:
+ typeE.tag = Te_TyRef;
+ break;
+ case DW_TAG_ptr_to_member_type:
+ typeE.tag = Te_TyPtrMbr;
+ break;
+ case DW_TAG_rvalue_reference_type:
+ typeE.tag = Te_TyRvalRef;
+ break;
+ default:
+ vg_assert(False);
+ }
/* target type defaults to void */
typeE.Te.TyPorR.typeR = D3_FAKEVOID_CUOFF;
- typeE.Te.TyPorR.isPtr = dtag == DW_TAG_pointer_type
- || dtag == DW_TAG_ptr_to_member_type;
- /* These three type kinds don't *have* to specify their size, in
+ /* These four type kinds don't *have* to specify their size, in
which case we assume it's a machine word. But if they do
specify it, it must be a machine word :-) This probably
assumes that the word size of the Dwarf3 we're reading is the
break;
case Te_TyBase:
break;
- case Te_TyPorR:
+ case Te_TyPtr:
+ case Te_TyRef:
+ case Te_TyPtrMbr:
+ case Te_TyRvalRef:
te->Te.TyPorR.typeR
= chase_cuOff( &b, ents, ents_cache, te->Te.TyPorR.typeR );
if (b) changed = True;
case Te_EMPTY: case Te_INDIR: case Te_UNKNOWN:
case Te_Atom: case Te_Field: case Te_Bound:
return False;
- case Te_TyBase: case Te_TyPorR: case Te_TyTyDef:
- case Te_TyStOrUn: case Te_TyEnum: case Te_TyArray:
- case Te_TyFn: case Te_TyQual: case Te_TyVoid:
+ case Te_TyBase: case Te_TyPtr: case Te_TyRef:
+ case Te_TyPtrMbr: case Te_TyRvalRef: case Te_TyTyDef:
+ case Te_TyStOrUn: case Te_TyEnum: case Te_TyArray:
+ case Te_TyFn: case Te_TyQual: case Te_TyVoid:
return True;
default:
vg_assert(0);
te->Te.TyBase.name ? te->Te.TyBase.name
: (UChar*)"(null)" );
break;
- case Te_TyPorR:
- VG_(printf)("Te_TyPorR(%d,%c,0x%05lx)",
- te->Te.TyPorR.szB,
- te->Te.TyPorR.isPtr ? 'P' : 'R',
+ case Te_TyPtr:
+ VG_(printf)("Te_TyPtr(%d,0x%05lx)", te->Te.TyPorR.szB,
+ te->Te.TyPorR.typeR);
+ break;
+ case Te_TyRef:
+ VG_(printf)("Te_TyRef(%d,0x%05lx)", te->Te.TyPorR.szB,
+ te->Te.TyPorR.typeR);
+ break;
+ case Te_TyPtrMbr:
+ VG_(printf)("Te_TyMbr(%d,0x%05lx)", te->Te.TyPorR.szB,
+ te->Te.TyPorR.typeR);
+ break;
+ case Te_TyRvalRef:
+ VG_(printf)("Te_TyRvalRef(%d,0x%05lx)", te->Te.TyPorR.szB,
te->Te.TyPorR.typeR);
break;
case Te_TyTyDef:
if (!ent->Te.TyBase.name) goto unhandled;
VG_(printf)("%s", ent->Te.TyBase.name);
break;
- case Te_TyPorR:
+ case Te_TyPtr:
ML_(pp_TyEnt_C_ishly)(tyents, ent->Te.TyPorR.typeR);
- VG_(printf)("%s", ent->Te.TyPorR.isPtr ? "*" : "&");
+ VG_(printf)("*");
+ break;
+ case Te_TyRef:
+ ML_(pp_TyEnt_C_ishly)(tyents, ent->Te.TyPorR.typeR);
+ VG_(printf)("&");
+ break;
+ case Te_TyPtrMbr:
+ ML_(pp_TyEnt_C_ishly)(tyents, ent->Te.TyPorR.typeR);
+ VG_(printf)("*");
+ break;
+ case Te_TyRvalRef:
+ ML_(pp_TyEnt_C_ishly)(tyents, ent->Te.TyPorR.typeR);
+ VG_(printf)("&&");
break;
case Te_TyEnum:
if (!ent->Te.TyEnum.name) goto unhandled;
if (r != 0) return r;
r = Asciiz__cmp(te1->Te.TyBase.name, te2->Te.TyBase.name);
return r;
- case Te_TyPorR:
+ case Te_TyPtr:
+ case Te_TyRef:
+ case Te_TyPtrMbr:
+ case Te_TyRvalRef:
r = Int__cmp(te1->Te.TyPorR.szB, te2->Te.TyPorR.szB);
if (r != 0) return r;
r = UWord__cmp(te1->Te.TyPorR.typeR, te2->Te.TyPorR.typeR);
- if (r != 0) return r;
- r = Bool__cmp(te1->Te.TyPorR.isPtr, te2->Te.TyPorR.isPtr);
return r;
case Te_TyTyDef:
r = UWord__cmp(te1->Te.TyTyDef.typeR, te2->Te.TyTyDef.typeR);
case Te_TyBase:
if (te->Te.TyBase.name) ML_(dinfo_free)(te->Te.TyBase.name);
break;
- case Te_TyPorR:
+ case Te_TyPtr:
+ case Te_TyRef:
+ case Te_TyPtrMbr:
+ case Te_TyRvalRef:
break;
case Te_TyTyDef:
if (te->Te.TyTyDef.name) ML_(dinfo_free)(te->Te.TyTyDef.name);
if (ent2->tag == Te_UNKNOWN)
return mk_MaybeULong_Nothing(); /*UNKNOWN*/
return ML_(sizeOfType)( tyents, ent->Te.TyTyDef.typeR );
- case Te_TyPorR:
+ case Te_TyPtr:
+ case Te_TyRef:
+ case Te_TyPtrMbr:
+ case Te_TyRvalRef:
vg_assert(ent->Te.TyPorR.szB == 4 || ent->Te.TyPorR.szB == 8);
return mk_MaybeULong_Just( ent->Te.TyPorR.szB );
case Te_TyStOrUn:
case Te_TyEnum:
case Te_TyFn:
case Te_TyVoid:
- case Te_TyPorR:
+ case Te_TyPtr:
+ case Te_TyRef:
+ case Te_TyPtrMbr:
+ case Te_TyRvalRef:
case Te_TyBase:
goto done;