+#define CLEANUP_AND_RETURN_ERROR(ret) do { \
+ if (dupkey != NULL) \
+ free((void*)dupkey); \
+ if (value != NULL) { \
+ value_destroy(value); \
+ free(value); \
+ } \
+ if (lens != NULL) { \
+ lens_destroy(&lens->super); \
+ free(lens); \
+ } \
+ if (result != NULL) { \
+ type_destroy(result); \
+ free(result); \
+ } \
+ dict_erase (type_dieoffset_hash, &die_offset, NULL, \
+ NULL, NULL); \
+ dict_insert(type_dieoffset_hash, &die_offset, \
+ &(struct arg_type_info*){ \
+ type_get_simple(ARGTYPE_VOID)}); \
+ return ret; \
+ } while (0)
+
+ struct arg_type_info *result = NULL;
+ struct enum_lens *lens = NULL;
+ const char *dupkey = NULL;
+ struct value *value = NULL;
+
+ Dwarf_Off die_offset = dwarf_dieoffset(parent);
+
+ result = calloc(1, sizeof(struct arg_type_info));
+ if (result == NULL) {
+ complain(parent, "alloc error");
+ CLEANUP_AND_RETURN_ERROR(NULL);
+ }
+
+ if (dict_insert(type_dieoffset_hash, &die_offset, &result) != 0) {
+ complain(parent, "Couldn't insert into cache dict");
+ CLEANUP_AND_RETURN_ERROR(NULL);
+ }
+
+ uint64_t byte_size;
+ if (!get_die_numeric(&byte_size, parent, DW_AT_byte_size)) {
+ // No byte size given, assume 'int'
+ result->type = ARGTYPE_INT;
+ } else {
+ if (!get_integer_base_type(&result->type,
+ (int)byte_size, true)) {
+ complain(parent, "Unknown integer base type. "
+ "Using 'int'");
+ result->type = ARGTYPE_INT;
+ }
+ }
+
+ lens = calloc(1, sizeof(struct enum_lens));