[CLASSES]: Make struct class and enumeration share more thru struct type

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
This commit is contained in:
Arnaldo Carvalho de Melo 2007-01-09 10:00:47 -02:00
parent 99610d5857
commit 8062d1a874
5 changed files with 99 additions and 106 deletions

111
classes.c
View File

@ -289,9 +289,13 @@ static void type__init(struct type *self, Dwarf_Die *die)
{
tag__init(&self->tag, die);
INIT_LIST_HEAD(&self->node);
INIT_LIST_HEAD(&self->members);
self->name = strings__add(attr_string(die, DW_AT_name));
self->size = attr_numeric(die, DW_AT_byte_size);
self->declaration = attr_numeric(die, DW_AT_declaration);
self->definition_emitted = 0;
self->fwd_decl_emitted = 0;
self->nr_members = 0;
}
static struct type *type__new(Dwarf_Die *die)
@ -304,26 +308,11 @@ static struct type *type__new(Dwarf_Die *die)
return self;
}
static struct enumeration *enumeration__new(Dwarf_Die *die)
{
struct enumeration *self = malloc(sizeof(*self));
if (self != NULL) {
type__init(&self->type, die);
INIT_LIST_HEAD(&self->members);
self->nr_members = 0;
self->size = attr_numeric(die, DW_AT_byte_size);
}
return self;
}
static size_t enumeration__snprintf(const struct tag *tag_self,
char *bf, size_t len,
const char *suffix, uint8_t ntabs)
{
const struct type *type_self = tag__type(tag_self);
const struct enumeration *self = tag__enumeration(tag_self);
const struct type *self = tag__type(tag_self);
struct enumerator *pos;
char *s = bf;
size_t printed = 0, n;
@ -332,7 +321,7 @@ static size_t enumeration__snprintf(const struct tag *tag_self,
ntabs = sizeof(tabs) - 1;
n = snprintf(s, len, "enum%s%s {\n",
type_self->name ? " " : "", type_self->name ?: "");
self->name ? " " : "", self->name ?: "");
s += n;
len -= n;
printed += n;
@ -390,7 +379,7 @@ static struct variable *variable__new(Dwarf_Die *die)
return self;
}
static size_t union__snprintf(const struct class *self, const struct cu *cu,
static size_t union__snprintf(const struct type *self, const struct cu *cu,
char *bf, size_t len,
const char *suffix, uint8_t ntabs)
{
@ -404,7 +393,7 @@ static size_t union__snprintf(const struct class *self, const struct cu *cu,
ntabs = sizeof(tabs) - 1;
n = snprintf(s, len, "union%s%s {\n",
self->type.name ? " " : "", self->type.name ?: "");
self->name ? " " : "", self->name ?: "");
s += n;
len -= n;
printed += n;
@ -426,7 +415,7 @@ static size_t union__snprintf(const struct class *self, const struct cu *cu,
return printed + n;
}
static void union__print(const struct class *self, const struct cu *cu,
static void union__print(const struct type *self, const struct cu *cu,
const char *suffix, uint8_t ntabs)
{
struct enumerator *pos;
@ -436,7 +425,7 @@ static void union__print(const struct class *self, const struct cu *cu,
ntabs = sizeof(tabs) - 1;
printf("%.*s/* %s:%u */\n", ntabs, tabs,
self->type.tag.decl_file, self->type.tag.decl_line);
self->tag.decl_file, self->tag.decl_line);
union__snprintf(self, cu, bf, sizeof(bf), suffix, ntabs);
printf("%s\n", bf);
}
@ -738,11 +727,11 @@ static size_t tag__size(const struct tag *self, const struct cu *cu)
switch (self->tag) {
case DW_TAG_pointer_type: return cu->addr_size;
case DW_TAG_base_type: return tag__base_type(self)->size;
case DW_TAG_enumeration_type: return tag__enumeration(self)->size;
case DW_TAG_enumeration_type: return tag__type(self)->size;
}
if (self->type == 0) /* struct class: unions, structs */
size = tag__class(self)->size;
size = tag__type(self)->size;
else {
const struct tag *type = cu__find_tag_by_id(cu, self->type);
@ -994,9 +983,8 @@ static size_t class_member__print(struct class_member *self,
assert(type != NULL);
if (type->tag == DW_TAG_enumeration_type) {
const struct type *ctype = tag__type(type);
const struct enumeration *enumeration = tag__enumeration(type);
size = enumeration->size;
size = ctype->size;
if (ctype->name != NULL) {
snprintf(class_name, sizeof(class_name), "enum %s",
ctype->name);
@ -1015,10 +1003,8 @@ static size_t class_member__print(struct class_member *self,
}
} else if (type->tag == DW_TAG_union_type) {
const struct type *ctype = tag__type(type);
const struct class *class = tag__class(type);
size = class->size;
size = ctype->size;
if (ctype->name != NULL) {
snprintf(class_name, sizeof(class_name), "union %s",
ctype->name);
@ -1027,7 +1013,7 @@ static size_t class_member__print(struct class_member *self,
} else {
const size_t spacing = 45 - (self->name ?
strlen(self->name) : -1);
union__snprintf(class, cu,
union__snprintf(ctype, cu,
class_name, sizeof(class_name),
self->name, 1);
printf("%s %*.*s/* %5u %5u */",
@ -1179,24 +1165,19 @@ static struct class *class__new(Dwarf_Die *die)
{
struct class *self = zalloc(sizeof(*self));
if (self != NULL) {
if (self != NULL)
type__init(&self->type, die);
INIT_LIST_HEAD(&self->members);
self->size = attr_numeric(die, DW_AT_byte_size);
self->declaration = attr_numeric(die, DW_AT_declaration);
}
return self;
}
static void class__add_member(struct class *self, struct class_member *member)
static void type__add_member(struct type *self, struct class_member *member)
{
++self->nr_members;
list_add_tail(&member->tag.node, &self->members);
}
static void enumeration__add(struct enumeration *self,
struct enumerator *enumerator)
static void enumeration__add(struct type *self, struct enumerator *enumerator)
{
++self->nr_members;
list_add_tail(&enumerator->tag.node, &self->members);
@ -1340,7 +1321,7 @@ const struct class_member *class__find_bit_hole(const struct class *self,
struct class_member *pos;
const size_t byte_hole_size = bit_hole_size / 8;
list_for_each_entry(pos, &self->members, tag.node)
list_for_each_entry(pos, &self->type.members, tag.node)
if (pos == trailer)
break;
else if (pos->hole >= byte_hole_size ||
@ -1352,6 +1333,7 @@ const struct class_member *class__find_bit_hole(const struct class *self,
void class__find_holes(struct class *self, const struct cu *cu)
{
const struct type *ctype = &self->type;
struct class_member *pos, *last = NULL;
size_t last_size = 0, size;
uint32_t bit_sum = 0;
@ -1359,7 +1341,7 @@ void class__find_holes(struct class *self, const struct cu *cu)
self->nr_holes = 0;
self->nr_bit_holes = 0;
list_for_each_entry(pos, &self->members, tag.node) {
list_for_each_entry(pos, &ctype->members, tag.node) {
if (last != NULL) {
const ssize_t cc_last_size = pos->offset - last->offset;
@ -1411,24 +1393,23 @@ void class__find_holes(struct class *self, const struct cu *cu)
}
if (last != NULL) {
if (last->offset + last_size != self->size)
self->padding = self->size - (last->offset + last_size);
if (last->offset + last_size != ctype->size)
self->padding = ctype->size -
(last->offset + last_size);
if (last->bit_size != 0)
self->bit_padding = (last_size * 8) - bit_sum;
}
}
struct class_member *class__find_member_by_name(const struct class *self,
const char *name)
struct class_member *type__find_member_by_name(const struct type *self,
const char *name)
{
struct class_member *pos;
if (name == NULL)
return NULL;
list_for_each_entry(pos, &self->members, tag.node)
if (pos->name != NULL && strcmp(pos->name, name) == 0)
return pos;
if (name != NULL) {
struct class_member *pos;
list_for_each_entry(pos, &self->members, tag.node)
if (pos->name != NULL && strcmp(pos->name, name) == 0)
return pos;
}
return NULL;
}
@ -1710,7 +1691,7 @@ static void class__print_struct(const struct tag *tag, const struct cu *cu,
printf("%s%sstruct%s%s {\n", prefix ?: "", prefix ? " " : "",
tself->name ? " " : "", tself->name ?: "");
list_for_each_entry(pos, &self->members, tag.node) {
list_for_each_entry(pos, &self->type.members, tag.node) {
const ssize_t cc_last_size = pos->offset - last_offset;
last_cacheline = class__print_cacheline_boundary(last_cacheline,
@ -1799,8 +1780,8 @@ static void class__print_struct(const struct tag *tag, const struct cu *cu,
&newline);
printf("}%s%s; /* size: %u, cachelines: %u */\n",
suffix ? " ": "", suffix ?: "", self->size,
(self->size + cacheline_size - 1) / cacheline_size);
suffix ? " ": "", suffix ?: "", tself->size,
(tself->size + cacheline_size - 1) / cacheline_size);
if (sum_holes > 0)
printf(" /* sum members: %lu, holes: %d, sum holes: %lu */\n",
sum, self->nr_holes, sum_holes);
@ -1811,15 +1792,15 @@ static void class__print_struct(const struct tag *tag, const struct cu *cu,
printf(" /* padding: %u */\n", self->padding);
if (self->bit_padding > 0)
printf(" /* bit_padding: %u bits */\n", self->bit_padding);
last_cacheline = self->size % cacheline_size;
last_cacheline = tself->size % cacheline_size;
if (last_cacheline != 0)
printf(" /* last cacheline: %u bytes */\n", last_cacheline);
if (sum + sum_holes != self->size - self->padding)
if (sum + sum_holes != tself->size - self->padding)
printf("\n/* BRAIN FART ALERT! %u != "
"%u + %u(holes), diff = %u */\n\n",
self->size, sum, sum_holes,
self->size - (sum + sum_holes));
tself->size, sum, sum_holes,
tself->size - (sum + sum_holes));
}
void tag__print(const struct tag *self, const struct cu *cu,
@ -2072,7 +2053,7 @@ out:
static void cu__create_new_enumeration(Dwarf_Die *die, struct cu *cu)
{
Dwarf_Die child;
struct enumeration *enumeration = enumeration__new(die);
struct type *enumeration = type__new(die);
if (enumeration == NULL)
oom("class__new");
@ -2098,7 +2079,7 @@ static void cu__create_new_enumeration(Dwarf_Die *die, struct cu *cu)
enumeration__add(enumeration, enumerator);
} while (dwarf_siblingof(die, die) == 0);
cu__add_tag(cu, &enumeration->type.tag);
cu__add_tag(cu, &enumeration->tag);
}
static void cu__process_class(Dwarf_Die *die, struct class *class,
@ -2113,14 +2094,14 @@ static void cu__process_class(Dwarf_Die *die, struct class *class,
if (member == NULL)
oom("class_member__new");
class__add_member(class, member);
type__add_member(&class->type, member);
}
break;
case DW_TAG_enumeration_type:
cu__create_new_enumeration(die, cu);
break;
case DW_TAG_structure_type:
case DW_TAG_union_type:
case DW_TAG_structure_type:
/*
* structs within structs: C++
*
@ -2201,8 +2182,8 @@ static void cu__process_function(Dwarf_Die *die,
case DW_TAG_enumeration_type:
cu__create_new_enumeration(die, cu);
break;
case DW_TAG_structure_type:
case DW_TAG_union_type:
case DW_TAG_structure_type:
cu__create_new_class(die, cu);
break;
default:
@ -2252,8 +2233,8 @@ static void cu__process_unit(Dwarf_Die *die, struct cu *cu)
case DW_TAG_typedef:
cu__create_new_typedef(die, cu);
break;
case DW_TAG_structure_type:
case DW_TAG_union_type:
case DW_TAG_structure_type:
cu__create_new_class(die, cu);
break;
default:
@ -2574,7 +2555,7 @@ int cus__emit_struct_definitions(struct cus *self, struct cu *cu,
cus__add_definition(self, ctype);
class = tag__class(tag);
list_for_each_entry(pos, &class->members, tag.node)
list_for_each_entry(pos, &class->type.members, tag.node)
if (cus__emit_tag_definitions(self, cu, &pos->tag))
printed = 1;

View File

@ -55,8 +55,12 @@ struct type {
struct tag tag;
struct list_head node;
const char *name;
uint8_t definition_emitted;
uint8_t fwd_decl_emitted;
size_t size;
struct list_head members;
uint16_t nr_members;
uint8_t declaration; /* only one bit used */
uint8_t definition_emitted:1;
uint8_t fwd_decl_emitted:1;
};
static inline struct type *tag__type(const struct tag *self)
@ -66,14 +70,10 @@ static inline struct type *tag__type(const struct tag *self)
struct class {
struct type type;
struct list_head members;
size_t size;
uint16_t nr_members;
uint8_t nr_holes;
uint8_t nr_bit_holes;
uint16_t padding;
uint8_t bit_padding;
uint8_t declaration; /* Just one bit used */
void *priv;
};
@ -225,18 +225,6 @@ struct label {
Dwarf_Addr low_pc;
};
struct enumeration {
struct type type;
struct list_head members; /* struct enumerator */
uint16_t size;
uint16_t nr_members;
};
static inline struct enumeration *tag__enumeration(const struct tag *self)
{
return (struct enumeration *)self;
}
struct enumerator {
struct tag tag;
const char *name;
@ -333,8 +321,29 @@ extern int ftype__has_parm_of_type(const struct ftype *self,
extern const char *tag__name(const struct tag *self, const struct cu *cu,
char *bf, size_t len);
extern struct class_member *class__find_member_by_name(const struct class *self,
const char *name);
extern struct class_member *type__find_member_by_name(const struct type *self,
const char *name);
static inline struct class_member *
class__find_member_by_name(const struct class *self, const char *name)
{
return type__find_member_by_name(&self->type, name);
}
static inline uint16_t class__nr_members(const struct class *self)
{
return self->type.nr_members;
}
static inline size_t class__size(const struct class *self)
{
return self->type.size;
}
static inline int class__is_declaration(const struct class *self)
{
return self->type.declaration;
}
extern size_t class_member__names(const struct tag *type,
const struct cu *cu,

View File

@ -193,7 +193,7 @@ static int check_print_members_changes(const struct class *structure,
int changes = 0;
struct class_member *member;
list_for_each_entry(member, &structure->members, tag.node) {
list_for_each_entry(member, &structure->type.members, tag.node) {
struct class_member *twin =
class__find_member_by_name(new_structure, member->name);
if (twin != NULL)
@ -213,7 +213,7 @@ static void diff_struct(const struct cu *new_cu, struct class *structure,
assert(class__tag_type(structure) == DW_TAG_structure_type);
if (structure->size == 0 || class__name(structure) == NULL)
if (class__size(structure) == 0 || class__name(structure) == NULL)
return;
new_tag = cu__find_struct_by_name(new_cu, class__name(structure));
@ -223,13 +223,13 @@ static void diff_struct(const struct cu *new_cu, struct class *structure,
}
new_structure = tag__class(new_tag);
if (new_structure->size == 0)
if (class__size(new_structure) == 0)
return;
assert(class__tag_type(new_structure) == DW_TAG_structure_type);
diff = structure->size != new_structure->size ||
structure->nr_members != new_structure->nr_members ||
diff = class__size(structure) != class__size(new_structure) ||
class__nr_members(structure) != class__nr_members(new_structure) ||
check_print_members_changes(structure, cu,
new_structure, new_cu, 0);
if (diff == 0)
@ -306,7 +306,7 @@ static int find_new_classes_iterator(struct tag *tag, struct cu *cu, void *old_c
if (class__name(class) == NULL)
return 0;
if (class->size == 0)
if (class__size(class) == 0)
return 0;
if (cu__find_struct_by_name(old_cu, class__name(class)) != NULL)
@ -397,7 +397,7 @@ static void show_nr_members_changes(const struct class *structure,
struct class_member *member;
/* Find the removed ones */
list_for_each_entry(member, &structure->members, tag.node) {
list_for_each_entry(member, &structure->type.members, tag.node) {
struct class_member *twin =
class__find_member_by_name(new_structure, member->name);
if (twin == NULL)
@ -405,7 +405,7 @@ static void show_nr_members_changes(const struct class *structure,
}
/* Find the new ones */
list_for_each_entry(member, &new_structure->members, tag.node) {
list_for_each_entry(member, &new_structure->type.members, tag.node) {
struct class_member *twin =
class__find_member_by_name(structure, member->name);
if (twin == NULL)
@ -450,7 +450,8 @@ static void show_diffs_structure(const struct class *structure,
{
const struct diff_info *di = structure->priv;
const struct class *new_structure = tag__class(di->tag);
int diff = (new_structure != NULL ? new_structure->size : 0) - structure->size;
int diff = (new_structure != NULL ? class__size(new_structure) : 0) -
class__size(structure);
terse_type_changes = 0;
@ -467,9 +468,10 @@ static void show_diffs_structure(const struct class *structure,
return;
if (new_structure == NULL)
diff = -structure->nr_members;
diff = -class__nr_members(structure);
else
diff = new_structure->nr_members - structure->nr_members;
diff = (class__nr_members(new_structure) -
class__nr_members(structure));
if (diff != 0) {
terse_type_changes |= TCHANGEF__NR_MEMBERS;
if (!show_terse_type_changes) {

View File

@ -77,13 +77,14 @@ static void nr_definitions_formatter(const struct structure *self)
static void nr_members_formatter(const struct structure *self)
{
printf("%s: %u\n", class__name(self->class), self->class->nr_members);
printf("%s: %u\n", class__name(self->class),
class__nr_members(self->class));
}
static void size_formatter(const struct structure *self)
{
printf("%s: %u %u\n", class__name(self->class), self->class->size,
self->class->nr_holes);
printf("%s: %u %u\n", class__name(self->class),
class__size(self->class), self->class->nr_holes);
}
static void class_name_len_formatter(const struct structure *self)
@ -125,7 +126,7 @@ static int class__packable(const struct class *self)
if (self->nr_holes == 0 && self->nr_bit_holes == 0)
return 0;
list_for_each_entry(pos, &self->members, tag.node)
list_for_each_entry(pos, &self->type.members, tag.node)
if (pos->hole != 0 &&
class__find_bit_hole(self, pos, pos->hole * 8) != NULL)
return 1;
@ -157,15 +158,15 @@ static void class__chkdupdef(const struct class *self, const struct cu *cu,
{
char hdr = 0;
if (self->size != dup->size)
if (class__size(self) != class__size(dup))
class__dupmsg(self, cu, dup, dup_cu,
&hdr, "size: %u != %u\n",
self->size, dup->size);
class__size(self), class__size(dup));
if (self->nr_members != dup->nr_members)
if (class__nr_members(self) != class__nr_members(dup))
class__dupmsg(self, cu, dup, dup_cu,
&hdr, "nr_members: %u != %u\n",
self->nr_members, dup->nr_members);
class__nr_members(self), class__nr_members(dup));
if (self->nr_holes != dup->nr_holes)
class__dupmsg(self, cu, dup, dup_cu,
@ -212,7 +213,7 @@ static struct tag *tag__filter(struct tag *tag, struct cu *cu, void *cookie)
if (name == NULL)
return NULL;
if (class->declaration)
if (class__is_declaration(class))
return NULL;
if (class__exclude_prefix != NULL &&

View File

@ -81,7 +81,7 @@ static void refcnt_tag(struct tag *tag, const struct cu *cu)
if (tag->tag == DW_TAG_structure_type ||
tag->tag == DW_TAG_union_type)
list_for_each_entry(member, &tag__class(tag)->members, tag.node)
list_for_each_entry(member, &tag__type(tag)->members, tag.node)
refcnt_member(member, cu);
}