NEWS: Add missing list of changes for v1.25
[dwarves.git] / prefcnt.c
blob37ca18fd1a21b5e1264fe64be5a436c5e16be628
1 /*
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>
6 */
8 #include <assert.h>
9 #include <dwarf.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
14 #include "dwarves.h"
15 #include "dutil.h"
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)
27 if (member->visited)
28 return;
29 member->visited = 1;
30 if (member->tag.type != 0) { /* if not void */
31 struct tag *type = cu__type(cu, member->tag.type);
32 if (type != NULL)
33 refcnt_tag(type, cu);
37 static void refcnt_parameter(const struct parameter *parameter,
38 const struct cu *cu)
40 if (parameter->tag.type != 0) { /* if not void */
41 struct tag *type = cu__type(cu, parameter->tag.type);
42 if (type != NULL)
43 refcnt_tag(type, cu);
47 static void refcnt_variable(const struct variable *variable,
48 const struct cu *cu)
50 if (variable->ip.tag.type != 0) { /* if not void */
51 struct tag *type = cu__type(cu, variable->ip.tag.type);
52 if (type != NULL)
53 refcnt_tag(type, cu);
57 static void refcnt_inline_expansion(const struct inline_expansion *exp,
58 const struct cu *cu)
60 if (exp->ip.tag.type != 0) { /* if not void */
61 struct tag *type = cu__function(cu, exp->ip.tag.type);
62 if (type != NULL)
63 refcnt_tag(type, cu);
67 static void refcnt_tag(struct tag *tag, const struct cu *cu)
69 struct class_member *member;
71 tag->visited = 1;
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)
81 struct tag *pos;
83 list_for_each_entry(pos, &lexblock->tags, node)
84 switch (pos->tag) {
85 case DW_TAG_variable:
86 refcnt_variable(tag__variable(pos), cu);
87 break;
88 case DW_TAG_inlined_subroutine:
89 refcnt_inline_expansion(tag__inline_expansion(pos), cu);
90 break;
91 case DW_TAG_lexical_block:
92 refcnt_lexblock(tag__lexblock(pos), cu);
93 break;
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);
105 if (type != NULL)
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;
118 uint32_t id;
120 cu__for_each_function(cu, id, pos)
121 refcnt_function(pos, cu);
122 return 0;
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);
130 puts(";\n");
132 return 0;
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[])
142 int err;
143 struct cus *cus = cus__new();
145 if (dwarves__init() || cus == NULL) {
146 fputs("prefcnt: insufficient memory\n", stderr);
147 return EXIT_FAILURE;
150 dwarves__resolve_cacheline_size(NULL, 0);
152 err = cus__load_files(cus, &conf_load, argv + 1);
153 if (err != 0) {
154 cus__fprintf_load_files_err(cus, "prefcnt", argv + 1, err, stderr);
155 return EXIT_FAILURE;
158 cus__for_each_cu(cus, cu_refcnt_iterator, NULL, NULL);
159 cus__for_each_cu(cus, cu_lost_iterator, NULL, NULL);
161 return EXIT_SUCCESS;