[CLASSES]: Pave the way to reuse DW_TAG_subprogram prototype code
Will be reused when handling DW_TAG_subprogram_type more comprehensively, in the upcoming csets. Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
This commit is contained in:
parent
e78718148d
commit
29fc67353c
159
classes.c
159
classes.c
|
@ -348,7 +348,7 @@ static void cu__add_tag(struct cu *self, struct tag *tag)
|
|||
static void cu__add_function(struct cu *self, struct function *function)
|
||||
{
|
||||
function->cu = self;
|
||||
list_add_tail(&function->tag.node, &self->functions);
|
||||
list_add_tail(&function->proto.tag.node, &self->functions);
|
||||
}
|
||||
|
||||
static void cu__add_variable(struct cu *self, struct variable *variable)
|
||||
|
@ -494,7 +494,7 @@ struct function *cu__find_function_by_name(const struct cu *self,
|
|||
if (name == NULL)
|
||||
return NULL;
|
||||
|
||||
list_for_each_entry(pos, &self->functions, tag.node)
|
||||
list_for_each_entry(pos, &self->functions, proto.tag.node)
|
||||
if (pos->name != NULL && strcmp(pos->name, name) == 0)
|
||||
return pos;
|
||||
|
||||
|
@ -506,8 +506,8 @@ struct function *cu__find_function_by_id(const struct cu *self,
|
|||
{
|
||||
struct function *pos;
|
||||
|
||||
list_for_each_entry(pos, &self->functions, tag.node)
|
||||
if (pos->tag.id == id)
|
||||
list_for_each_entry(pos, &self->functions, proto.tag.node)
|
||||
if (pos->proto.tag.id == id)
|
||||
return pos;
|
||||
|
||||
return NULL;
|
||||
|
@ -766,12 +766,11 @@ out:
|
|||
return size;
|
||||
}
|
||||
|
||||
size_t parameter__names(const struct parameter *self,
|
||||
size_t parameter__names(const struct parameter *self, const struct cu *cu,
|
||||
char *class_name, size_t class_name_size,
|
||||
char *parameter_name, size_t parameter_name_size)
|
||||
{
|
||||
struct tag *type = cu__find_tag_by_id(self->function->cu,
|
||||
self->tag.type);
|
||||
struct tag *type = cu__find_tag_by_id(cu, self->tag.type);
|
||||
size_t size = -1;
|
||||
|
||||
snprintf(parameter_name, parameter_name_size, "%s", self->name ?: "");
|
||||
|
@ -781,14 +780,12 @@ size_t parameter__names(const struct parameter *self,
|
|||
self->tag.type);
|
||||
else {
|
||||
if (type->tag == DW_TAG_const_type)
|
||||
type = cu__find_tag_by_id(self->function->cu,
|
||||
type->type);
|
||||
size = tag__size(type, self->function->cu);
|
||||
type = cu__find_tag_by_id(cu, type->type);
|
||||
size = tag__size(type, cu);
|
||||
|
||||
/* Is it a function pointer? */
|
||||
if (type->tag == DW_TAG_pointer_type) {
|
||||
struct tag *ptype =
|
||||
cu__find_tag_by_id(self->function->cu, type->type);
|
||||
struct tag *ptype = cu__find_tag_by_id(cu, type->type);
|
||||
|
||||
if (ptype != NULL &&
|
||||
ptype->tag == DW_TAG_subroutine_type) {
|
||||
|
@ -798,10 +795,9 @@ size_t parameter__names(const struct parameter *self,
|
|||
class_name_size, "void");
|
||||
else {
|
||||
struct tag *ret_type =
|
||||
cu__find_tag_by_id(self->function->cu,
|
||||
ptype->type);
|
||||
cu__find_tag_by_id(cu, ptype->type);
|
||||
|
||||
tag__name(ret_type, self->function->cu,
|
||||
tag__name(ret_type, cu,
|
||||
class_name, class_name_size);
|
||||
}
|
||||
snprintf(parameter_name, parameter_name_size,
|
||||
|
@ -812,8 +808,7 @@ size_t parameter__names(const struct parameter *self,
|
|||
}
|
||||
}
|
||||
|
||||
tag__name(type, self->function->cu,
|
||||
class_name, class_name_size);
|
||||
tag__name(type, cu, class_name, class_name_size);
|
||||
if (type->tag == DW_TAG_array_type) {
|
||||
struct array_type *array = tag__array_type(type);
|
||||
int i = 0;
|
||||
|
@ -1011,6 +1006,16 @@ static void lexblock__init(struct lexblock *self)
|
|||
self->nr_inline_expansions = 0;
|
||||
}
|
||||
|
||||
static ftype__init(struct ftype *self, uint16_t tag,
|
||||
Dwarf_Off id, Dwarf_Off type,
|
||||
const char *decl_file, uint32_t decl_line)
|
||||
{
|
||||
assert(tag == DW_TAG_subprogram || tag == DW_TAG_subroutine_type);
|
||||
|
||||
tag__init(&self->tag, tag, id, type, decl_file, decl_line);
|
||||
INIT_LIST_HEAD(&self->parms);
|
||||
}
|
||||
|
||||
static struct function *function__new(Dwarf_Off id, Dwarf_Off type,
|
||||
const char *decl_file,
|
||||
uint32_t decl_line, const char *name,
|
||||
|
@ -1020,10 +1025,8 @@ static struct function *function__new(Dwarf_Off id, Dwarf_Off type,
|
|||
struct function *self = zalloc(sizeof(*self));
|
||||
|
||||
if (self != NULL) {
|
||||
tag__init(&self->tag, DW_TAG_subprogram,
|
||||
id, type, decl_file, decl_line);
|
||||
|
||||
INIT_LIST_HEAD(&self->parameters);
|
||||
ftype__init(&self->proto, DW_TAG_subprogram, id, type,
|
||||
decl_file, decl_line);
|
||||
lexblock__init(&self->lexblock);
|
||||
self->name = strings__add(name);
|
||||
self->inlined = inlined;
|
||||
|
@ -1035,16 +1038,16 @@ static struct function *function__new(Dwarf_Off id, Dwarf_Off type,
|
|||
return self;
|
||||
}
|
||||
|
||||
int function__has_parameter_of_type(const struct function *self,
|
||||
const struct tag *target)
|
||||
int ftype__has_parm_of_type(const struct ftype *self, const struct tag *target,
|
||||
const struct cu *cu)
|
||||
{
|
||||
struct class_member *pos;
|
||||
struct parameter *pos;
|
||||
|
||||
list_for_each_entry(pos, &self->parameters, tag.node) {
|
||||
struct tag *type = cu__find_tag_by_id(self->cu, pos->tag.type);
|
||||
list_for_each_entry(pos, &self->parms, tag.node) {
|
||||
struct tag *type = cu__find_tag_by_id(cu, pos->tag.type);
|
||||
|
||||
if (type != NULL && type->tag == DW_TAG_pointer_type) {
|
||||
type = cu__find_tag_by_id(self->cu, type->type);
|
||||
type = cu__find_tag_by_id(cu, type->type);
|
||||
if (type != NULL && type->id == target->id)
|
||||
return 1;
|
||||
}
|
||||
|
@ -1052,12 +1055,10 @@ int function__has_parameter_of_type(const struct function *self,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void function__add_parameter(struct function *self,
|
||||
struct parameter *parameter)
|
||||
static void ftype__add_parameter(struct ftype *self, struct parameter *parm)
|
||||
{
|
||||
++self->nr_parameters;
|
||||
parameter->function = self;
|
||||
list_add_tail(¶meter->tag.node, &self->parameters);
|
||||
++self->nr_parms;
|
||||
list_add_tail(&parm->tag.node, &self->parms);
|
||||
}
|
||||
|
||||
static void lexblock__add_inline_expansion(struct lexblock *self,
|
||||
|
@ -1202,7 +1203,7 @@ void cu__account_inline_expansions(struct cu *self)
|
|||
{
|
||||
struct function *pos;
|
||||
|
||||
list_for_each_entry(pos, &self->functions, tag.node) {
|
||||
list_for_each_entry(pos, &self->functions, proto.tag.node) {
|
||||
function__account_inline_expansions(pos);
|
||||
self->nr_inline_expansions += pos->lexblock.nr_inline_expansions;
|
||||
self->size_inline_expansions += pos->lexblock.size_inline_expansions;
|
||||
|
@ -1292,21 +1293,21 @@ static void function__print_body(const struct function *self,
|
|||
if (show_variables)
|
||||
list_for_each_entry(pos, &self->lexblock.variables, node) {
|
||||
/* FIXME! this test shouln't be needed at all */
|
||||
if (pos->decl_line >= self->tag.decl_line)
|
||||
if (pos->decl_line >= self->proto.tag.decl_line)
|
||||
tags__add(&tags, pos);
|
||||
}
|
||||
|
||||
if (show_inline_expansions)
|
||||
list_for_each_entry(pos, &self->lexblock.inline_expansions, node) {
|
||||
/* FIXME! this test shouln't be needed at all */
|
||||
if (pos->decl_line >= self->tag.decl_line)
|
||||
if (pos->decl_line >= self->proto.tag.decl_line)
|
||||
tags__add(&tags, pos);
|
||||
}
|
||||
|
||||
if (show_labels)
|
||||
list_for_each_entry(pos, &self->lexblock.labels, node) {
|
||||
/* FIXME! this test shouln't be needed at all */
|
||||
if (pos->decl_line >= self->tag.decl_line)
|
||||
if (pos->decl_line >= self->proto.tag.decl_line)
|
||||
tags__add(&tags, pos);
|
||||
}
|
||||
|
||||
|
@ -1317,39 +1318,59 @@ static void function__print_body(const struct function *self,
|
|||
tdestroy(tags, tags__free);
|
||||
}
|
||||
|
||||
static size_t ftype__snprintf(const struct ftype *self, const struct cu *cu,
|
||||
char *bf, const size_t len,
|
||||
const char *name, const uint8_t inlined)
|
||||
{
|
||||
struct parameter *pos;
|
||||
struct tag *type = cu__find_tag_by_id(cu, self->tag.type);
|
||||
int first_parm = 1;
|
||||
char *s = bf, sbf[128];
|
||||
size_t l = len;
|
||||
const char *stype = tag__name(type, cu, sbf, sizeof(sbf));
|
||||
size_t n = snprintf(s, l, "%s%s %s(", inlined ? "inline " : "",
|
||||
stype, name ?: "");
|
||||
s += n; l -= n;
|
||||
|
||||
list_for_each_entry(pos, &self->parms, tag.node) {
|
||||
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);
|
||||
stype = tag__name(type, cu, sbf, sizeof(sbf));
|
||||
n = snprintf(s, l, "%s %s", stype, pos->name);
|
||||
s += n; l -= n;
|
||||
}
|
||||
|
||||
/* No parameters? */
|
||||
if (first_parm) {
|
||||
n = snprintf(s, l, "void");
|
||||
s += n; l -= n;
|
||||
}
|
||||
else if (self->unspec_parms) {
|
||||
n = snprintf(s, l, ", ...");
|
||||
s += n; l -= n;
|
||||
}
|
||||
n = snprintf(s, l, ");\n", stdout);
|
||||
return len - l - n;
|
||||
}
|
||||
|
||||
void function__print(const struct function *self, int show_stats,
|
||||
const int show_variables,
|
||||
const int show_inline_expansions)
|
||||
{
|
||||
char bf[256];
|
||||
char bf[2048];
|
||||
struct tag *class_type;
|
||||
const char *type = "<ERROR>";
|
||||
struct parameter *pos;
|
||||
int first_parameter = 1;
|
||||
|
||||
class_type = cu__find_tag_by_id(self->cu, self->tag.type);
|
||||
type = tag__name(class_type, self->cu, bf, sizeof(bf));
|
||||
printf("/* %s:%u */\n", self->proto.tag.decl_file,
|
||||
self->proto.tag.decl_line);
|
||||
|
||||
printf("/* %s:%u */\n", self->tag.decl_file, self->tag.decl_line);
|
||||
printf("%s%s %s(", function__declared_inline(self) ? "inline " : "",
|
||||
type, self->name ?: "");
|
||||
list_for_each_entry(pos, &self->parameters, tag.node) {
|
||||
if (!first_parameter)
|
||||
fputs(", ", stdout);
|
||||
else
|
||||
first_parameter = 0;
|
||||
type = "<ERROR>";
|
||||
class_type = cu__find_tag_by_id(self->cu, pos->tag.type);
|
||||
type = tag__name(class_type, self->cu, bf, sizeof(bf));
|
||||
printf("%s %s", type, pos->name ?: "");
|
||||
}
|
||||
|
||||
/* No parameters? */
|
||||
if (first_parameter)
|
||||
fputs("void", stdout);
|
||||
else if (self->unspecified_parameters)
|
||||
fputs(", ...", stdout);
|
||||
fputs(");\n", stdout);
|
||||
ftype__snprintf(&self->proto, self->cu, bf, sizeof(bf), self->name,
|
||||
function__declared_inline(self));
|
||||
fputs(bf, stdout);
|
||||
|
||||
if (show_variables || show_inline_expansions)
|
||||
function__print_body(self, show_variables,
|
||||
|
@ -1574,7 +1595,7 @@ int cu__for_each_function(struct cu *cu,
|
|||
|
||||
struct function *pos;
|
||||
|
||||
list_for_each_entry(pos, &cu->functions, tag.node) {
|
||||
list_for_each_entry(pos, &cu->functions, proto.tag.node) {
|
||||
struct function *function = pos;
|
||||
if (filter != NULL) {
|
||||
function = filter(pos, cookie);
|
||||
|
@ -1936,7 +1957,7 @@ static void cu__process_function(Dwarf *dwarf, Dwarf_Die *die,
|
|||
if (parameter == NULL)
|
||||
oom("parameter__new");
|
||||
|
||||
function__add_parameter(function, parameter);
|
||||
ftype__add_parameter(&function->proto, parameter);
|
||||
}
|
||||
break;
|
||||
case DW_TAG_variable: {
|
||||
|
@ -1955,7 +1976,7 @@ static void cu__process_function(Dwarf *dwarf, Dwarf_Die *die,
|
|||
}
|
||||
break;
|
||||
case DW_TAG_unspecified_parameters:
|
||||
function->unspecified_parameters = 1;
|
||||
function->proto.unspec_parms = 1;
|
||||
break;
|
||||
case DW_TAG_label: {
|
||||
struct label *label;
|
||||
|
@ -2423,16 +2444,16 @@ next_indirection:
|
|||
return 0;
|
||||
}
|
||||
|
||||
int cus__emit_function_definitions(struct cus *self,
|
||||
struct function *function)
|
||||
int cus__emit_ftype_definitions(struct cus *self, struct cu *cu,
|
||||
struct ftype *ftype)
|
||||
{
|
||||
struct parameter *pos;
|
||||
/* First check the function return type */
|
||||
int printed = cus__emit_tag_definitions(self, function->cu, &function->tag);
|
||||
int printed = cus__emit_tag_definitions(self, cu, &ftype->tag);
|
||||
|
||||
/* Then its parameters */
|
||||
list_for_each_entry(pos, &function->parameters, tag.node)
|
||||
if (cus__emit_tag_definitions(self, function->cu, &pos->tag))
|
||||
list_for_each_entry(pos, &ftype->parms, tag.node)
|
||||
if (cus__emit_tag_definitions(self, cu, &pos->tag))
|
||||
printed = 1;
|
||||
|
||||
if (printed)
|
||||
|
|
23
classes.h
23
classes.h
|
@ -124,20 +124,27 @@ struct lexblock {
|
|||
size_t size_inline_expansions;
|
||||
};
|
||||
|
||||
struct function {
|
||||
/*
|
||||
* tag.tag can be DW_TAG_subprogram_type or DW_TAG_subroutine_type.
|
||||
*/
|
||||
struct ftype {
|
||||
struct tag tag;
|
||||
struct list_head parms;
|
||||
uint16_t nr_parms;
|
||||
uint8_t unspec_parms:1;
|
||||
};
|
||||
|
||||
struct function {
|
||||
struct ftype proto;
|
||||
struct cu *cu;
|
||||
struct lexblock lexblock;
|
||||
struct list_head parameters;
|
||||
const char *name;
|
||||
Dwarf_Addr low_pc;
|
||||
Dwarf_Addr high_pc;
|
||||
uint16_t nr_parameters;
|
||||
uint16_t cu_total_nr_inline_expansions;
|
||||
size_t cu_total_size_inline_expansions;
|
||||
uint16_t cu_total_nr_inline_expansions;
|
||||
uint8_t inlined:2;
|
||||
uint8_t external:1;
|
||||
uint8_t unspecified_parameters:1;
|
||||
/* fields used by tools */
|
||||
struct list_head tool_node;
|
||||
int32_t diff;
|
||||
|
@ -147,7 +154,6 @@ struct function {
|
|||
struct parameter {
|
||||
struct tag tag;
|
||||
char *name;
|
||||
struct function *function;
|
||||
};
|
||||
|
||||
struct variable {
|
||||
|
@ -196,8 +202,8 @@ extern struct cu *cus__find_cu_by_name(const struct cus *self,
|
|||
const char *name);
|
||||
extern struct function *cus__find_function_by_name(const struct cus *self,
|
||||
const char *name);
|
||||
extern int cus__emit_function_definitions(struct cus *self,
|
||||
struct function *function);
|
||||
extern int cus__emit_ftype_definitions(struct cus *self, struct cu *cu,
|
||||
struct ftype *ftype);
|
||||
extern int cus__emit_struct_definitions(struct cus *self, struct class *class,
|
||||
const char *prefix,
|
||||
const char *suffix);
|
||||
|
@ -280,6 +286,7 @@ extern const char *variable__type_name(const struct variable *self,
|
|||
extern const char *dwarf_tag_name(const uint32_t tag);
|
||||
|
||||
extern size_t parameter__names(const struct parameter *self,
|
||||
const struct cu *cu,
|
||||
char *class_name, size_t class_name_size,
|
||||
char *parameter_name,
|
||||
size_t parameter_name_size);
|
||||
|
|
4
codiff.c
4
codiff.c
|
@ -61,7 +61,7 @@ static void diff_function(const struct cu *new_cu, struct function *function)
|
|||
{
|
||||
struct function *new_function;
|
||||
|
||||
assert(function->tag.tag == DW_TAG_subprogram);
|
||||
assert(function->proto.tag.tag == DW_TAG_subprogram);
|
||||
|
||||
if (function->inlined)
|
||||
return;
|
||||
|
@ -222,7 +222,7 @@ static int find_new_functions_iterator(struct function *function, void *old_cu)
|
|||
{
|
||||
struct function *old_function;
|
||||
|
||||
assert(function->tag.tag == DW_TAG_subprogram);
|
||||
assert(function->proto.tag.tag == DW_TAG_subprogram);
|
||||
|
||||
if (function->inlined)
|
||||
return 0;
|
||||
|
|
14
ctracer.c
14
ctracer.c
|
@ -30,7 +30,7 @@ static struct function *function__filter(struct function *function,
|
|||
void *cookie)
|
||||
{
|
||||
if (function__inlined(function) ||
|
||||
!function__has_parameter_of_type(function, cookie))
|
||||
!ftype__has_parm_of_type(&function->proto, cookie))
|
||||
return NULL;
|
||||
|
||||
return function;
|
||||
|
@ -61,7 +61,7 @@ static int function__emit_kprobes(const struct function *self,
|
|||
char body[bodyl], *bodyp = body;
|
||||
char class_name[128], parm_name[256];
|
||||
struct parameter *pos;
|
||||
struct tag *type = cu__find_tag_by_id(self->cu, self->tag.type);
|
||||
struct tag *type = cu__find_tag_by_id(self->cu, self->proto.tag.type);
|
||||
const char *stype = tag__name(type, self->cu, bf, sizeof(bf));
|
||||
int first = 1;
|
||||
|
||||
|
@ -69,9 +69,9 @@ static int function__emit_kprobes(const struct function *self,
|
|||
|
||||
printf("static %s jprobe_entry__%s(", stype, self->name);
|
||||
|
||||
list_for_each_entry(pos, &self->parameters, tag.node) {
|
||||
list_for_each_entry(pos, &self->proto.parms, tag.node) {
|
||||
type = cu__find_tag_by_id(self->cu, pos->tag.type);
|
||||
parameter__names(pos, class_name, sizeof(class_name),
|
||||
parameter__names(pos, self->cu, class_name, sizeof(class_name),
|
||||
parm_name, sizeof(parm_name));
|
||||
|
||||
if (!first)
|
||||
|
@ -95,7 +95,7 @@ static int function__emit_kprobes(const struct function *self,
|
|||
bodyl -= printed;
|
||||
}
|
||||
printf(")\n{\n%s\n\tjprobe_return();\n\t/* NOTREACHED */%s\n}\n\n",
|
||||
body, self->tag.type != 0 ? "\n\treturn 0;" : "");
|
||||
body, self->proto.tag.type != 0 ? "\n\treturn 0;" : "");
|
||||
printf("static struct jprobe jprobe__%s = {\n"
|
||||
"\t.kp = { .symbol_name = \"%s\", },\n"
|
||||
"\t.entry = (kprobe_opcode_t *)jprobe_entry__%s,\n"
|
||||
|
@ -109,7 +109,7 @@ static int cu_emit_kprobes_iterator(struct cu *cu, void *cookie)
|
|||
struct function *pos;
|
||||
|
||||
list_for_each_entry(pos, &cu->tool_list, tool_node) {
|
||||
cus__emit_function_definitions(cus, pos);
|
||||
cus__emit_ftype_definitions(cus, pos->cu, &pos->proto);
|
||||
function__emit_kprobes(pos, &target->tag);
|
||||
}
|
||||
|
||||
|
@ -166,7 +166,7 @@ static void emit_function_defs(const char *fn)
|
|||
struct function *f = cus__find_function_by_name(kprobes_cus, fn);
|
||||
|
||||
if (f != NULL) {
|
||||
cus__emit_function_definitions(kprobes_cus, f);
|
||||
cus__emit_ftype_definitions(kprobes_cus, f->cu, &f->proto);
|
||||
function__print(f, 0, 0, 0);
|
||||
putchar('\n');
|
||||
}
|
||||
|
|
17
pfunct.c
17
pfunct.c
|
@ -87,7 +87,8 @@ static void fn_stats_variables_fmtr(const struct fn_stats *self)
|
|||
|
||||
static void fn_stats_nr_parms_fmtr(const struct fn_stats *self)
|
||||
{
|
||||
printf("%s: %u\n", self->function->name, self->function->nr_parameters);
|
||||
printf("%s: %u\n", self->function->name,
|
||||
self->function->proto.nr_parms);
|
||||
}
|
||||
|
||||
static void fn_stats_name_len_fmtr(const struct fn_stats *self)
|
||||
|
@ -163,11 +164,9 @@ static void fn_stats__chkdupdef(const struct function *self,
|
|||
fn_stats__dupmsg(self, dup, &hdr, "size: %zd != %zd\n",
|
||||
self_size, dup_size);
|
||||
|
||||
if (self->nr_parameters != dup->nr_parameters)
|
||||
fn_stats__dupmsg(self, dup, &hdr,
|
||||
"nr_parameters: %u != %u\n",
|
||||
self->nr_parameters,
|
||||
dup->nr_parameters);
|
||||
if (self->proto.nr_parms != dup->proto.nr_parms)
|
||||
fn_stats__dupmsg(self, dup, &hdr, "nr_parms: %u != %u\n",
|
||||
self->proto.nr_parms, dup->proto.nr_parms);
|
||||
|
||||
/* XXX put more checks here: member types, member ordering, etc */
|
||||
|
||||
|
@ -223,7 +222,7 @@ static int class_iterator(struct function *function, void *cookie)
|
|||
if (function->inlined)
|
||||
return 0;
|
||||
|
||||
if (function__has_parameter_of_type(function, cookie)) {
|
||||
if (ftype__has_parm_of_type(&function->proto, cookie)) {
|
||||
if (verbose)
|
||||
function__print(function, 1, 0, 0);
|
||||
else
|
||||
|
@ -269,7 +268,7 @@ static struct option long_options[] = {
|
|||
{ "inline_expansions_stats", no_argument, NULL, 'I' },
|
||||
{ "total_inline_stats", no_argument, NULL, 't' },
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "nr_parameters", no_argument, NULL, 'p' },
|
||||
{ "nr_parms", no_argument, NULL, 'p' },
|
||||
{ "sizes", no_argument, NULL, 's' },
|
||||
{ "nr_variables", no_argument, NULL, 'S' },
|
||||
{ "variables", no_argument, NULL, 'T' },
|
||||
|
@ -301,7 +300,7 @@ static void usage(void)
|
|||
"stats\n"
|
||||
" -s, --sizes show size of functions\n"
|
||||
" -N, --function_name_len show size of functions\n"
|
||||
" -p, --nr_parameters show number of "
|
||||
" -p, --nr_parms show number of "
|
||||
"parameters\n"
|
||||
" -S, --nr_variables show number of "
|
||||
"variables\n"
|
||||
|
|
16
prefcnt.c
16
prefcnt.c
|
@ -44,11 +44,11 @@ static void refcnt_member(struct class_member *member)
|
|||
}
|
||||
}
|
||||
|
||||
static void refcnt_parameter(const struct parameter *parameter)
|
||||
static void refcnt_parameter(const struct parameter *parameter,
|
||||
const struct cu *cu)
|
||||
{
|
||||
if (parameter->tag.type != 0) { /* if not void */
|
||||
struct tag *type = cu__find_tag_by_id(parameter->function->cu,
|
||||
parameter->tag.type);
|
||||
struct tag *type = cu__find_tag_by_id(cu, parameter->tag.type);
|
||||
if (type != NULL)
|
||||
refcnt_tag(type);
|
||||
}
|
||||
|
@ -92,17 +92,17 @@ static void refcnt_function(struct function *function)
|
|||
struct inline_expansion *exp;
|
||||
struct variable *variable;
|
||||
|
||||
function->tag.refcnt++;
|
||||
function->proto.tag.refcnt++;
|
||||
|
||||
if (function->tag.type != 0) /* if not void */ {
|
||||
if (function->proto.tag.type != 0) /* if not void */ {
|
||||
struct tag *type = cu__find_tag_by_id(function->cu,
|
||||
function->tag.type);
|
||||
function->proto.tag.type);
|
||||
if (type != NULL)
|
||||
refcnt_tag(type);
|
||||
}
|
||||
|
||||
list_for_each_entry(parameter, &function->parameters, tag.node)
|
||||
refcnt_parameter(parameter);
|
||||
list_for_each_entry(parameter, &function->proto.parms, tag.node)
|
||||
refcnt_parameter(parameter, function->cu);
|
||||
|
||||
list_for_each_entry(variable, &function->lexblock.variables, tag.node)
|
||||
refcnt_variable(variable);
|
||||
|
|
Loading…
Reference in New Issue