diff --git a/classes.c b/classes.c index f161f48..4b14500 100644 --- a/classes.c +++ b/classes.c @@ -763,7 +763,7 @@ void function__print(struct function *self) } printf("/* %s:%u */\n", self->tag.decl_file, self->tag.decl_line); - printf("%s%s %s(", self->inlined ? "inline " : "", + printf("%s%s %s(", function__declared_inline(self) ? "inline " : "", type, self->name ?: ""); list_for_each_entry(pos, &self->parameters, tag.node) { if (!first_parameter) @@ -1127,9 +1127,10 @@ static void cu__process_die(Dwarf *dwarf, Dwarf_Die *die) if (cu__current_function != NULL) function__add_variable(cu__current_function, variable); cu__add_variable(current_cu, variable); - } else if (tag == DW_TAG_label) - ++cu__current_function->nr_labels; - else if (tag == DW_TAG_inlined_subroutine) { + } else if (tag == DW_TAG_label) { + if (cu__current_function != NULL) + ++cu__current_function->nr_labels; + } else if (tag == DW_TAG_inlined_subroutine) { Dwarf_Addr high_pc, low_pc; if (dwarf_highpc(die, &high_pc)) high_pc = 0; if (dwarf_lowpc(die, &low_pc)) low_pc = 0; diff --git a/classes.h b/classes.h index 770d2e0..f083f43 100644 --- a/classes.h +++ b/classes.h @@ -11,6 +11,7 @@ #include +#include #include "list.h" @@ -159,6 +160,18 @@ static inline uint32_t function__size(const struct function *self) return self->high_pc - self->low_pc; } +static inline int function__declared_inline(const struct function *self) +{ + return (self->inlined == DW_INL_declared_inlined || + self->inlined == DW_INL_declared_not_inlined); +} + +static inline int function__inlined(const struct function *self) +{ + return (self->inlined == DW_INL_inlined || + self->inlined == DW_INL_declared_inlined); +} + extern struct class_member *class__find_member_by_name(const struct class *self, const char *name); diff --git a/pfunct.c b/pfunct.c index ae9ab9b..4a687dc 100644 --- a/pfunct.c +++ b/pfunct.c @@ -90,6 +90,7 @@ static void print_total_inline_stats(void) static struct option long_options[] = { { "class", required_argument, NULL, 'c' }, { "externals", no_argument, NULL, 'e' }, + { "cc_inlined", no_argument, NULL, 'H' }, { "cu_inline_expansions_stats", no_argument, NULL, 'C' }, { "function_name_len", no_argument, NULL, 'N' }, { "goto_labels", no_argument, NULL, 'g' }, @@ -114,6 +115,7 @@ static void usage(void) "pointer parameters\n" " -e, --externals show just external functions\n" " -g, --goto_labels show number of goto labels\n" + " -H, --cc_inlined not declared inline, inlined by compiler\n" " -i, --inline_expansions show inline expansions\n" " -I, --inline_expansions_stats show inline expansions stats\n" " -C, --cu_inline_expansions_stats show CU inline expansions stats\n" @@ -227,9 +229,6 @@ static int cu_goto_labels_iterator(struct cu *cu, void *cookie) static int function_iterator(struct function *function, void *cookie) { - if (function->inlined) - return 0; - if (cookie == NULL) { if (function->nr_inline_expansions > 0) printf("%s: %u %u\n", function->name ?: "", @@ -254,7 +253,7 @@ static int cu_function_iterator(struct cu *cu, void *cookie) static int inlines_iterator(struct function *function, void *cookie) { - if (!function->inlined) + if (!function__inlined(function)) return 0; if (function->name != NULL) @@ -300,7 +299,7 @@ static int cu_function_name_len_iterator(struct cu *cu, void *cookie) static int total_inlines_iterator(struct function *function, void *cookie) { - if (function->inlined) + if (function__inlined(function)) inlines__add(function); return 0; } @@ -313,6 +312,18 @@ static int cu_total_inlines_iterator(struct cu *cu, void *cookie) return 0; } +static int cc_inlined_iterator(struct function *function, void *cookie) +{ + if (function->inlined == DW_INL_inlined) + puts(function->name); + return 0; +} + +static int cu_cc_inlined_iterator(struct cu *cu, void *cookie) +{ + return cu__for_each_function(cu, cc_inlined_iterator, cookie); +} + int main(int argc, char *argv[]) { int option, option_index; @@ -329,8 +340,9 @@ int main(int argc, char *argv[]) int show_inline_expansions_stats = 0; int show_inline_stats = 0; int show_total_inline_expansion_stats = 0; + int show_cc_inlined = 0; - while ((option = getopt_long(argc, argv, "c:CegiINpsStTV", + while ((option = getopt_long(argc, argv, "c:CegHiINpsStTV", long_options, &option_index)) >= 0) switch (option) { case 'c': class_name = optarg; break; @@ -340,6 +352,7 @@ int main(int argc, char *argv[]) case 'S': show_nr_variables = 1; break; case 'p': show_nr_parameters = 1; break; case 'g': show_goto_labels = 1; break; + case 'H': show_cc_inlined = 1; break; case 'i': show_inline_expansions = 1; break; case 'I': show_inline_expansions_stats = 1; break; case 't': show_total_inline_expansion_stats = 1;break; @@ -379,6 +392,8 @@ int main(int argc, char *argv[]) print_total_inline_stats(); } else if (show_inline_stats) cus__for_each_cu(cus, cu_inlines_iterator, NULL); + else if (show_cc_inlined) + cus__for_each_cu(cus, cu_cc_inlined_iterator, NULL); else if (show_nr_parameters) cus__for_each_cu(cus, cu_nr_parameters_iterator, NULL); else if (show_nr_variables)