[CLASSES]: Support abstract origin in formal parameters
Sortof, mostly works, but still has a problem where the abstract origin is not being found, but for now its ok to keep the bandaid, everything works as before, there are more important things to do right now. Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
This commit is contained in:
parent
29103e42be
commit
0872d8e312
84
classes.c
84
classes.c
|
@ -684,6 +684,27 @@ static struct variable *cu__find_variable_by_id(const struct cu *self,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static struct parameter *cu__find_parameter_by_id(const struct cu *self,
|
||||
const Dwarf_Off id)
|
||||
{
|
||||
struct tag *pos;
|
||||
|
||||
list_for_each_entry(pos, &self->tags, node)
|
||||
if (pos->id == id)
|
||||
return tag__parameter(pos);
|
||||
|
||||
if (pos->tag == DW_TAG_subprogram) {
|
||||
struct function *fn = tag__function(pos);
|
||||
struct tag *tag =
|
||||
lexblock__find_tag_by_id(&fn->lexblock, id);
|
||||
|
||||
if (tag != NULL)
|
||||
return tag__parameter(tag);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int tag__is_struct(const struct tag *self, struct tag **typedef_alias,
|
||||
const struct cu *cu)
|
||||
{
|
||||
|
@ -1052,12 +1073,46 @@ static struct parameter *parameter__new(Dwarf_Die *die)
|
|||
|
||||
if (self != NULL) {
|
||||
tag__init(&self->tag, die);
|
||||
self->name = strings__add(attr_string(die, DW_AT_name));
|
||||
self->name = strings__add(attr_string(die,
|
||||
DW_AT_name));
|
||||
self->abstract_origin = attr_numeric(die,
|
||||
DW_AT_abstract_origin);
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
const char *parameter__name(struct parameter *self, const struct cu *cu)
|
||||
{
|
||||
/* Check if the tag doesn't comes with a DW_AT_name attribute... */
|
||||
if (self->name == NULL && self->abstract_origin != 0) {
|
||||
/* No? Does it have a DW_AT_abstract_origin? */
|
||||
struct parameter *alias =
|
||||
cu__find_parameter_by_id(cu, self->abstract_origin);
|
||||
assert(alias != NULL);
|
||||
/* Now cache the result in this tag ->name field */
|
||||
self->name = alias->name;
|
||||
}
|
||||
|
||||
return self->name;
|
||||
}
|
||||
|
||||
Dwarf_Off parameter__type(struct parameter *self, const struct cu *cu)
|
||||
{
|
||||
/* Check if the tag doesn't comes with a DW_AT_type attribute... */
|
||||
if (self->tag.type == 0 && self->abstract_origin != 0) {
|
||||
/* No? Does it have a DW_AT_abstract_origin? */
|
||||
struct parameter *alias =
|
||||
cu__find_parameter_by_id(cu, self->abstract_origin);
|
||||
assert(alias != NULL);
|
||||
/* Now cache the result in this tag ->name and type fields */
|
||||
self->name = alias->name;
|
||||
self->tag.type = alias->tag.type;
|
||||
}
|
||||
|
||||
return self->tag.type;
|
||||
}
|
||||
|
||||
static struct inline_expansion *inline_expansion__new(Dwarf_Die *die)
|
||||
{
|
||||
struct inline_expansion *self = zalloc(sizeof(*self));
|
||||
|
@ -1240,7 +1295,8 @@ int ftype__has_parm_of_type(const struct ftype *self, const struct tag *target,
|
|||
struct parameter *pos;
|
||||
|
||||
list_for_each_entry(pos, &self->parms, tag.node) {
|
||||
struct tag *type = cu__find_tag_by_id(cu, pos->tag.type);
|
||||
struct tag *type =
|
||||
cu__find_tag_by_id(cu, parameter__type(pos, cu));
|
||||
|
||||
if (type != NULL && type->tag == DW_TAG_pointer_type) {
|
||||
type = cu__find_tag_by_id(cu, type->type);
|
||||
|
@ -1528,12 +1584,15 @@ size_t ftype__snprintf(const struct ftype *self, const struct cu *cu,
|
|||
s += n; l -= n;
|
||||
|
||||
list_for_each_entry(pos, &self->parms, tag.node) {
|
||||
const char *name;
|
||||
|
||||
if (!first_parm) {
|
||||
n = snprintf(s, l, ", ");
|
||||
s += n; l -= n;
|
||||
} else
|
||||
first_parm = 0;
|
||||
type = cu__find_tag_by_id(cu, pos->tag.type);
|
||||
type = cu__find_tag_by_id(cu, parameter__type(pos, cu));
|
||||
name = parameter__name(pos, cu);
|
||||
if (type->tag == DW_TAG_pointer_type) {
|
||||
if (type->type != 0) {
|
||||
struct tag *ptype =
|
||||
|
@ -1541,18 +1600,18 @@ size_t ftype__snprintf(const struct ftype *self, const struct cu *cu,
|
|||
if (ptype->tag == DW_TAG_subroutine_type) {
|
||||
n = ftype__snprintf(tag__ftype(ptype),
|
||||
cu, s, l,
|
||||
pos->name, 0, 1, 0);
|
||||
name, 0, 1, 0);
|
||||
goto next;
|
||||
}
|
||||
}
|
||||
} else if (type->tag == DW_TAG_subroutine_type) {
|
||||
n = ftype__snprintf(tag__ftype(type), cu, s, l,
|
||||
pos->name, 0, 0, 0);
|
||||
name, 0, 0, 0);
|
||||
goto next;
|
||||
}
|
||||
stype = tag__name(type, cu, sbf, sizeof(sbf));
|
||||
n = snprintf(s, l, "%s%s%s", stype,
|
||||
pos->name ? " " : "", pos->name ?: "");
|
||||
name ? " " : "", name ?: "");
|
||||
next:
|
||||
s += n; l -= n;
|
||||
}
|
||||
|
@ -1942,14 +2001,18 @@ static void cu__create_new_array(Dwarf_Die *die, struct cu *cu)
|
|||
cu__add_tag(cu, &array->tag);
|
||||
}
|
||||
|
||||
static void cu__create_new_parameter(Dwarf_Die *die, struct ftype *ftype)
|
||||
static void cu__create_new_parameter(Dwarf_Die *die, struct ftype *ftype,
|
||||
struct cu *cu)
|
||||
{
|
||||
struct parameter *parm = parameter__new(die);
|
||||
|
||||
if (parm == NULL)
|
||||
oom("parameter__new");
|
||||
|
||||
ftype__add_parameter(ftype, parm);
|
||||
if (ftype != NULL)
|
||||
ftype__add_parameter(ftype, parm);
|
||||
else
|
||||
cu__add_tag(cu, &parm->tag);
|
||||
}
|
||||
|
||||
static void cu__create_new_label(Dwarf_Die *die, struct lexblock *lexblock)
|
||||
|
@ -1989,7 +2052,7 @@ static void cu__create_new_subroutine_type(Dwarf_Die *die, struct cu *cu)
|
|||
|
||||
switch (tag) {
|
||||
case DW_TAG_formal_parameter:
|
||||
cu__create_new_parameter(die, ftype);
|
||||
cu__create_new_parameter(die, ftype, cu);
|
||||
break;
|
||||
case DW_TAG_unspecified_parameters:
|
||||
ftype->unspec_parms = 1;
|
||||
|
@ -2120,8 +2183,7 @@ static void cu__process_function(Dwarf_Die *die,
|
|||
|
||||
switch (tag) {
|
||||
case DW_TAG_formal_parameter:
|
||||
if (ftype != NULL)
|
||||
cu__create_new_parameter(die, ftype);
|
||||
cu__create_new_parameter(die, ftype, cu);
|
||||
break;
|
||||
case DW_TAG_variable:
|
||||
cu__create_new_variable(cu, die, lexblock);
|
||||
|
|
|
@ -187,8 +187,14 @@ static inline struct function *tag__function(const struct tag *self)
|
|||
struct parameter {
|
||||
struct tag tag;
|
||||
char *name;
|
||||
Dwarf_Off abstract_origin;
|
||||
};
|
||||
|
||||
static inline struct parameter *tag__parameter(const struct tag *self)
|
||||
{
|
||||
return (struct parameter *)self;
|
||||
}
|
||||
|
||||
struct variable {
|
||||
struct tag tag;
|
||||
char *name;
|
||||
|
|
10
pfunct.c
10
pfunct.c
|
@ -156,7 +156,7 @@ static void fn_stats__dupmsg(struct function *self,
|
|||
printf("function: %s\nfirst: %s\ncurrent: %s\n",
|
||||
function__name(self, self_cu),
|
||||
self_cu->name,
|
||||
function__name(dup, dup_cu));
|
||||
dup_cu->name);
|
||||
|
||||
va_start(args, fmt);
|
||||
vprintf(fmt, args);
|
||||
|
@ -200,10 +200,14 @@ static struct tag *function__filter(struct tag *tag, struct cu *cu,
|
|||
return NULL;
|
||||
|
||||
function = tag__function(tag);
|
||||
name = function__name(function, cu);
|
||||
if (name == NULL)
|
||||
/*
|
||||
* FIXME: remove this check and try to fix the parameter abstract
|
||||
* origin code someday...
|
||||
*/
|
||||
if (function->name == NULL)
|
||||
return NULL;
|
||||
|
||||
name = function__name(function, cu);
|
||||
if (show_externals && !function->external)
|
||||
return NULL;
|
||||
|
||||
|
|
Loading…
Reference in New Issue