+ xbt_free(key);
+
+ if(type->name && type->byte_size!=0) {
+ xbt_dict_set(info->full_types_by_name, type->name, type, NULL);
+ }
+}
+
+static int mc_anonymous_variable_index = 0;
+
+static dw_variable_t MC_die_to_variable(mc_object_info_t info, Dwarf_Die* die, Dwarf_Die* unit, dw_frame_t frame, const char* namespace) {
+ // Skip declarations:
+ if (MC_dwarf_attr_flag(die, DW_AT_declaration, false))
+ return NULL;
+
+ // Skip compile time constants:
+ if(dwarf_hasattr(die, DW_AT_const_value))
+ return NULL;
+
+ Dwarf_Attribute attr_location;
+ if (dwarf_attr(die, DW_AT_location, &attr_location)==NULL) {
+ // No location: do not add it ?
+ return NULL;
+ }
+
+ dw_variable_t variable = xbt_new0(s_dw_variable_t, 1);
+ variable->dwarf_offset = dwarf_dieoffset(die);
+ variable->global = frame == NULL; // Can be override base on DW_AT_location
+ variable->object_info = info;
+
+ const char* name = MC_dwarf_attr_integrate_string(die, DW_AT_name);
+ variable->name = xbt_strdup(name);
+
+ variable->type_origin = MC_dwarf_at_type(die);
+
+ int form = dwarf_whatform(&attr_location);
+ int klass = form == DW_FORM_sec_offset ? MC_DW_CLASS_CONSTANT : MC_dwarf_form_get_class(form);
+ switch (klass) {
+ case MC_DW_CLASS_EXPRLOC:
+ case MC_DW_CLASS_BLOCK:
+ // Location expression:
+ {
+ Dwarf_Op* expr;
+ size_t len;
+ if (dwarf_getlocation(&attr_location, &expr, &len)) {
+ xbt_die(
+ "Could not read location expression in DW_AT_location of variable <%"PRIx64">%s",
+ (uint64_t) variable->dwarf_offset, variable->name);
+ }
+
+ if (len==1 && expr[0].atom == DW_OP_addr) {
+ variable->global = 1;
+ uintptr_t offset = (uintptr_t) expr[0].number;
+ uintptr_t base = (uintptr_t) MC_object_base_address(info);
+ variable->address = (void*) (base + offset);
+ } else {
+ mc_dwarf_location_list_init_from_expression(&variable->locations, len, expr);
+ }
+
+ break;
+ }
+ case MC_DW_CLASS_LOCLISTPTR:
+ case MC_DW_CLASS_CONSTANT:
+ // Reference to location list:
+ mc_dwarf_location_list_init(&variable->locations, info, die, &attr_location);
+ break;
+ default:
+ xbt_die("Unexpected form 0x%x (%i), class 0x%x (%i) list for location in <%"PRIx64">%s",
+ form, form, klass, klass, (uint64_t) variable->dwarf_offset, variable->name);
+ }
+
+ // Handle start_scope:
+ if (dwarf_hasattr(die, DW_AT_start_scope)) {
+ Dwarf_Attribute attr;
+ dwarf_attr(die, DW_AT_start_scope, &attr);
+ int form = dwarf_whatform(&attr);
+ int klass = MC_dwarf_form_get_class(form);
+ switch(klass) {
+ case MC_DW_CLASS_CONSTANT:
+ {
+ Dwarf_Word value;
+ variable->start_scope = dwarf_formudata(&attr, &value) == 0 ? (size_t) value : 0;
+ break;
+ }
+ case MC_DW_CLASS_RANGELISTPTR: // TODO
+ default:
+ xbt_die("Unhandled form 0x%x, class 0x%X for DW_AT_start_scope of variable %s",
+ form, klass, name==NULL ? "?" : name);
+ }
+ }
+
+ if(namespace && variable->global) {
+ char* old_name = variable->name;
+ variable->name = bprintf("%s::%s", namespace, old_name);
+ free(old_name);
+ }
+
+ // The current code needs a variable name,
+ // generate a fake one:
+ if(!variable->name) {
+ variable->name = bprintf("@anonymous#%i", mc_anonymous_variable_index++);
+ }
+
+ return variable;