2 SPDX-License-Identifier: GPL-2.0-only
4 Copyright (C) 2006 Mandriva Conectiva S.A.
5 Copyright (C) 2006 Arnaldo Carvalho de Melo <acme@mandriva.com>
17 static struct conf_fprintf conf
;
19 static struct conf_load conf_load
= {
20 .conf_fprintf
= &conf
,
23 static void refcnt_tag(struct tag
*tag
, const struct cu
*cu
);
25 static void refcnt_member(struct class_member
*member
, const struct cu
*cu
)
30 if (member
->tag
.type
!= 0) { /* if not void */
31 struct tag
*type
= cu__type(cu
, member
->tag
.type
);
37 static void refcnt_parameter(const struct parameter
*parameter
,
40 if (parameter
->tag
.type
!= 0) { /* if not void */
41 struct tag
*type
= cu__type(cu
, parameter
->tag
.type
);
47 static void refcnt_variable(const struct variable
*variable
,
50 if (variable
->ip
.tag
.type
!= 0) { /* if not void */
51 struct tag
*type
= cu__type(cu
, variable
->ip
.tag
.type
);
57 static void refcnt_inline_expansion(const struct inline_expansion
*exp
,
60 if (exp
->ip
.tag
.type
!= 0) { /* if not void */
61 struct tag
*type
= cu__function(cu
, exp
->ip
.tag
.type
);
67 static void refcnt_tag(struct tag
*tag
, const struct cu
*cu
)
69 struct class_member
*member
;
73 if (tag__is_struct(tag
) || tag__is_union(tag
)) {
74 type__for_each_member(tag__type(tag
), member
)
75 refcnt_member(member
, cu
);
79 static void refcnt_lexblock(const struct lexblock
*lexblock
, const struct cu
*cu
)
83 list_for_each_entry(pos
, &lexblock
->tags
, node
)
86 refcnt_variable(tag__variable(pos
), cu
);
88 case DW_TAG_inlined_subroutine
:
89 refcnt_inline_expansion(tag__inline_expansion(pos
), cu
);
91 case DW_TAG_lexical_block
:
92 refcnt_lexblock(tag__lexblock(pos
), cu
);
97 static void refcnt_function(struct function
*function
, const struct cu
*cu
)
99 struct parameter
*parameter
;
101 function
->proto
.tag
.visited
= 1;
103 if (function
->proto
.tag
.type
!= 0) /* if not void */ {
104 struct tag
*type
= cu__type(cu
, function
->proto
.tag
.type
);
106 refcnt_tag(type
, cu
);
109 list_for_each_entry(parameter
, &function
->proto
.parms
, tag
.node
)
110 refcnt_parameter(parameter
, cu
);
112 refcnt_lexblock(&function
->lexblock
, cu
);
115 static int cu_refcnt_iterator(struct cu
*cu
, void *cookie __maybe_unused
)
117 struct function
*pos
;
120 cu__for_each_function(cu
, id
, pos
)
121 refcnt_function(pos
, cu
);
125 static int lost_iterator(struct tag
*tag
, struct cu
*cu
,
126 void *cookie __maybe_unused
)
128 if (!tag
->visited
&& tag__decl_file(tag
, cu
)) {
129 tag__fprintf(tag
, cu
, NULL
, stdout
);
135 static int cu_lost_iterator(struct cu
*cu
, void *cookie
)
137 return cu__for_all_tags(cu
, lost_iterator
, cookie
);
140 int main(int argc __maybe_unused
, char *argv
[])
143 struct cus
*cus
= cus__new();
145 if (dwarves__init() || cus
== NULL
) {
146 fputs("prefcnt: insufficient memory\n", stderr
);
150 dwarves__resolve_cacheline_size(NULL
, 0);
152 err
= cus__load_files(cus
, &conf_load
, argv
+ 1);
154 cus__fprintf_load_files_err(cus
, "prefcnt", argv
+ 1, err
, stderr
);
158 cus__for_each_cu(cus
, cu_refcnt_iterator
, NULL
, NULL
);
159 cus__for_each_cu(cus
, cu_lost_iterator
, NULL
, NULL
);