]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - libctf/ctf-decl.c
Update year range in copyright notice of binutils files
[thirdparty/binutils-gdb.git] / libctf / ctf-decl.c
CommitLineData
316afdb1 1/* C declarator syntax glue.
250d07de 2 Copyright (C) 2019-2021 Free Software Foundation, Inc.
316afdb1
NA
3
4 This file is part of libctf.
5
6 libctf is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
9 version.
10
11 This program is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 See the GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; see the file COPYING. If not see
18 <http://www.gnu.org/licenses/>. */
19
20/* CTF Declaration Stack
21
22 In order to implement ctf_type_name(), we must convert a type graph back
23 into a C type declaration. Unfortunately, a type graph represents a storage
24 class ordering of the type whereas a type declaration must obey the C rules
25 for operator precedence, and the two orderings are frequently in conflict.
26 For example, consider these CTF type graphs and their C declarations:
27
28 CTF_K_POINTER -> CTF_K_FUNCTION -> CTF_K_INTEGER : int (*)()
29 CTF_K_POINTER -> CTF_K_ARRAY -> CTF_K_INTEGER : int (*)[]
30
31 In each case, parentheses are used to raise operator * to higher lexical
32 precedence, so the string form of the C declaration cannot be constructed by
33 walking the type graph links and forming the string from left to right.
34
35 The functions in this file build a set of stacks from the type graph nodes
36 corresponding to the C operator precedence levels in the appropriate order.
37 The code in ctf_type_name() can then iterate over the levels and nodes in
38 lexical precedence order and construct the final C declaration string. */
39
40#include <ctf-impl.h>
41#include <string.h>
42
43void
44ctf_decl_init (ctf_decl_t *cd)
45{
46 int i;
47
48 memset (cd, 0, sizeof (ctf_decl_t));
49
50 for (i = CTF_PREC_BASE; i < CTF_PREC_MAX; i++)
51 cd->cd_order[i] = CTF_PREC_BASE - 1;
52
53 cd->cd_qualp = CTF_PREC_BASE;
54 cd->cd_ordp = CTF_PREC_BASE;
55}
56
57void
58ctf_decl_fini (ctf_decl_t *cd)
59{
60 ctf_decl_node_t *cdp, *ndp;
61 int i;
62
63 for (i = CTF_PREC_BASE; i < CTF_PREC_MAX; i++)
64 {
65 for (cdp = ctf_list_next (&cd->cd_nodes[i]); cdp != NULL; cdp = ndp)
66 {
67 ndp = ctf_list_next (cdp);
de07e349 68 free (cdp);
316afdb1
NA
69 }
70 }
b255b35f 71 free (cd->cd_buf);
316afdb1
NA
72}
73
74void
139633c3 75ctf_decl_push (ctf_decl_t *cd, ctf_dict_t *fp, ctf_id_t type)
316afdb1
NA
76{
77 ctf_decl_node_t *cdp;
78 ctf_decl_prec_t prec;
79 uint32_t kind, n = 1;
80 int is_qual = 0;
81
82 const ctf_type_t *tp;
83 ctf_arinfo_t ar;
84
85 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
86 {
87 cd->cd_err = fp->ctf_errno;
88 return;
89 }
90
91 switch (kind = LCTF_INFO_KIND (fp, tp->ctt_info))
92 {
93 case CTF_K_ARRAY:
94 (void) ctf_array_info (fp, type, &ar);
95 ctf_decl_push (cd, fp, ar.ctr_contents);
96 n = ar.ctr_nelems;
97 prec = CTF_PREC_ARRAY;
98 break;
99
100 case CTF_K_TYPEDEF:
101 if (ctf_strptr (fp, tp->ctt_name)[0] == '\0')
102 {
103 ctf_decl_push (cd, fp, tp->ctt_type);
104 return;
105 }
106 prec = CTF_PREC_BASE;
107 break;
108
109 case CTF_K_FUNCTION:
110 ctf_decl_push (cd, fp, tp->ctt_type);
111 prec = CTF_PREC_FUNCTION;
112 break;
113
114 case CTF_K_POINTER:
115 ctf_decl_push (cd, fp, tp->ctt_type);
116 prec = CTF_PREC_POINTER;
117 break;
118
119 case CTF_K_SLICE:
120 ctf_decl_push (cd, fp, ctf_type_reference (fp, type));
121 prec = CTF_PREC_BASE;
122 break;
123
124 case CTF_K_VOLATILE:
125 case CTF_K_CONST:
126 case CTF_K_RESTRICT:
127 ctf_decl_push (cd, fp, tp->ctt_type);
128 prec = cd->cd_qualp;
129 is_qual++;
130 break;
131
132 default:
133 prec = CTF_PREC_BASE;
134 }
135
de07e349 136 if ((cdp = malloc (sizeof (ctf_decl_node_t))) == NULL)
316afdb1
NA
137 {
138 cd->cd_err = EAGAIN;
139 return;
140 }
141
142 cdp->cd_type = type;
143 cdp->cd_kind = kind;
144 cdp->cd_n = n;
145
146 if (ctf_list_next (&cd->cd_nodes[prec]) == NULL)
147 cd->cd_order[prec] = cd->cd_ordp++;
148
149 /* Reset cd_qualp to the highest precedence level that we've seen so
150 far that can be qualified (CTF_PREC_BASE or CTF_PREC_POINTER). */
151
152 if (prec > cd->cd_qualp && prec < CTF_PREC_ARRAY)
153 cd->cd_qualp = prec;
154
155 /* C array declarators are ordered inside out so prepend them. Also by
156 convention qualifiers of base types precede the type specifier (e.g.
157 const int vs. int const) even though the two forms are equivalent. */
158
159 if (kind == CTF_K_ARRAY || (is_qual && prec == CTF_PREC_BASE))
160 ctf_list_prepend (&cd->cd_nodes[prec], cdp);
161 else
162 ctf_list_append (&cd->cd_nodes[prec], cdp);
163}
164
165_libctf_printflike_ (2, 3)
166void ctf_decl_sprintf (ctf_decl_t *cd, const char *format, ...)
167{
168 va_list ap;
169 char *str;
170 int n;
171
172 if (cd->cd_enomem)
173 return;
174
175 va_start (ap, format);
176 n = vasprintf (&str, format, ap);
177 va_end (ap);
178
179 if (n > 0)
de07e349
NA
180 {
181 char *newbuf;
182 if ((newbuf = ctf_str_append (cd->cd_buf, str)) != NULL)
183 cd->cd_buf = newbuf;
184 }
316afdb1
NA
185
186 /* Sticky error condition. */
de07e349 187 if (n < 0 || cd->cd_buf == NULL)
316afdb1
NA
188 {
189 free (cd->cd_buf);
190 cd->cd_buf = NULL;
191 cd->cd_enomem = 1;
192 }
193
194 free (str);
195}
196
197char *ctf_decl_buf (ctf_decl_t *cd)
198{
b255b35f
NA
199 char *buf = cd->cd_buf;
200 cd->cd_buf = NULL;
201 return buf;
316afdb1 202}