1 /* C declarator syntax glue.
2 Copyright (C) 2019 Free Software Foundation, Inc.
4 This file is part of libctf.
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
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.
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/>. */
20 /* CTF Declaration Stack
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:
28 CTF_K_POINTER -> CTF_K_FUNCTION -> CTF_K_INTEGER : int (*)()
29 CTF_K_POINTER -> CTF_K_ARRAY -> CTF_K_INTEGER : int (*)[]
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.
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. */
44 ctf_decl_init (ctf_decl_t
*cd
)
48 memset (cd
, 0, sizeof (ctf_decl_t
));
50 for (i
= CTF_PREC_BASE
; i
< CTF_PREC_MAX
; i
++)
51 cd
->cd_order
[i
] = CTF_PREC_BASE
- 1;
53 cd
->cd_qualp
= CTF_PREC_BASE
;
54 cd
->cd_ordp
= CTF_PREC_BASE
;
58 ctf_decl_fini (ctf_decl_t
*cd
)
60 ctf_decl_node_t
*cdp
, *ndp
;
63 for (i
= CTF_PREC_BASE
; i
< CTF_PREC_MAX
; i
++)
65 for (cdp
= ctf_list_next (&cd
->cd_nodes
[i
]); cdp
!= NULL
; cdp
= ndp
)
67 ndp
= ctf_list_next (cdp
);
74 ctf_decl_push (ctf_decl_t
*cd
, ctf_file_t
*fp
, ctf_id_t type
)
84 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
86 cd
->cd_err
= fp
->ctf_errno
;
90 switch (kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
))
93 (void) ctf_array_info (fp
, type
, &ar
);
94 ctf_decl_push (cd
, fp
, ar
.ctr_contents
);
96 prec
= CTF_PREC_ARRAY
;
100 if (ctf_strptr (fp
, tp
->ctt_name
)[0] == '\0')
102 ctf_decl_push (cd
, fp
, tp
->ctt_type
);
105 prec
= CTF_PREC_BASE
;
109 ctf_decl_push (cd
, fp
, tp
->ctt_type
);
110 prec
= CTF_PREC_FUNCTION
;
114 ctf_decl_push (cd
, fp
, tp
->ctt_type
);
115 prec
= CTF_PREC_POINTER
;
119 ctf_decl_push (cd
, fp
, ctf_type_reference (fp
, type
));
120 prec
= CTF_PREC_BASE
;
126 ctf_decl_push (cd
, fp
, tp
->ctt_type
);
132 prec
= CTF_PREC_BASE
;
135 if ((cdp
= ctf_alloc (sizeof (ctf_decl_node_t
))) == NULL
)
145 if (ctf_list_next (&cd
->cd_nodes
[prec
]) == NULL
)
146 cd
->cd_order
[prec
] = cd
->cd_ordp
++;
148 /* Reset cd_qualp to the highest precedence level that we've seen so
149 far that can be qualified (CTF_PREC_BASE or CTF_PREC_POINTER). */
151 if (prec
> cd
->cd_qualp
&& prec
< CTF_PREC_ARRAY
)
154 /* C array declarators are ordered inside out so prepend them. Also by
155 convention qualifiers of base types precede the type specifier (e.g.
156 const int vs. int const) even though the two forms are equivalent. */
158 if (kind
== CTF_K_ARRAY
|| (is_qual
&& prec
== CTF_PREC_BASE
))
159 ctf_list_prepend (&cd
->cd_nodes
[prec
], cdp
);
161 ctf_list_append (&cd
->cd_nodes
[prec
], cdp
);
164 _libctf_printflike_ (2, 3)
165 void ctf_decl_sprintf (ctf_decl_t
*cd
, const char *format
, ...)
174 va_start (ap
, format
);
175 n
= vasprintf (&str
, format
, ap
);
179 cd
->cd_buf
= ctf_str_append (cd
->cd_buf
, str
);
181 /* Sticky error condition. */
192 char *ctf_decl_buf (ctf_decl_t
*cd
)
This page took 0.033852 seconds and 4 git commands to generate.