4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
30 * CTF Declaration Stack
32 * In order to implement ctf_type_name(), we must convert a type graph back
33 * into a C type declaration. Unfortunately, a type graph represents a storage
34 * class ordering of the type whereas a type declaration must obey the C rules
35 * for operator precedence, and the two orderings are frequently in conflict.
36 * For example, consider these CTF type graphs and their C declarations:
38 * CTF_K_POINTER -> CTF_K_FUNCTION -> CTF_K_INTEGER : int (*)()
39 * CTF_K_POINTER -> CTF_K_ARRAY -> CTF_K_INTEGER : int (*)[]
41 * In each case, parentheses are used to raise operator * to higher lexical
42 * precedence, so the string form of the C declaration cannot be constructed by
43 * walking the type graph links and forming the string from left to right.
45 * The functions in this file build a set of stacks from the type graph nodes
46 * corresponding to the C operator precedence levels in the appropriate order.
47 * The code in ctf_type_name() can then iterate over the levels and nodes in
48 * lexical precedence order and construct the final C declaration string.
54 ctf_decl_init(ctf_decl_t
*cd
, char *buf
, size_t len
)
58 bzero(cd
, sizeof (ctf_decl_t
));
60 for (i
= CTF_PREC_BASE
; i
< CTF_PREC_MAX
; i
++)
61 cd
->cd_order
[i
] = CTF_PREC_BASE
- 1;
63 cd
->cd_qualp
= CTF_PREC_BASE
;
64 cd
->cd_ordp
= CTF_PREC_BASE
;
68 cd
->cd_end
= buf
+ len
;
72 ctf_decl_fini(ctf_decl_t
*cd
)
74 ctf_decl_node_t
*cdp
, *ndp
;
77 for (i
= CTF_PREC_BASE
; i
< CTF_PREC_MAX
; i
++) {
78 for (cdp
= ctf_list_next(&cd
->cd_nodes
[i
]);
79 cdp
!= NULL
; cdp
= ndp
) {
80 ndp
= ctf_list_next(cdp
);
81 ctf_free(cdp
, sizeof (ctf_decl_node_t
));
87 ctf_decl_push(ctf_decl_t
*cd
, ctf_file_t
*fp
, ctf_id_t type
)
97 if ((tp
= ctf_lookup_by_id(&fp
, type
)) == NULL
) {
98 cd
->cd_err
= fp
->ctf_errno
;
102 switch (kind
= LCTF_INFO_KIND(fp
, tp
->ctt_info
)) {
104 (void) ctf_array_info(fp
, type
, &ar
);
105 ctf_decl_push(cd
, fp
, ar
.ctr_contents
);
107 prec
= CTF_PREC_ARRAY
;
111 if (ctf_strptr(fp
, tp
->ctt_name
)[0] == '\0') {
112 ctf_decl_push(cd
, fp
, tp
->ctt_type
);
115 prec
= CTF_PREC_BASE
;
119 ctf_decl_push(cd
, fp
, tp
->ctt_type
);
120 prec
= CTF_PREC_FUNCTION
;
124 ctf_decl_push(cd
, fp
, tp
->ctt_type
);
125 prec
= CTF_PREC_POINTER
;
131 ctf_decl_push(cd
, fp
, tp
->ctt_type
);
137 prec
= CTF_PREC_BASE
;
140 if ((cdp
= ctf_alloc(sizeof (ctf_decl_node_t
))) == NULL
) {
149 if (ctf_list_next(&cd
->cd_nodes
[prec
]) == NULL
)
150 cd
->cd_order
[prec
] = cd
->cd_ordp
++;
153 * Reset cd_qualp to the highest precedence level that we've seen so
154 * far that can be qualified (CTF_PREC_BASE or CTF_PREC_POINTER).
156 if (prec
> cd
->cd_qualp
&& prec
< CTF_PREC_ARRAY
)
160 * C array declarators are ordered inside out so prepend them. Also by
161 * convention qualifiers of base types precede the type specifier (e.g.
162 * const int vs. int const) even though the two forms are equivalent.
164 if (kind
== CTF_K_ARRAY
|| (is_qual
&& prec
== CTF_PREC_BASE
))
165 ctf_list_prepend(&cd
->cd_nodes
[prec
], cdp
);
167 ctf_list_append(&cd
->cd_nodes
[prec
], cdp
);
172 ctf_decl_sprintf(ctf_decl_t
*cd
, const char *format
, ...)
174 size_t len
= (size_t)(cd
->cd_end
- cd
->cd_ptr
);
178 va_start(ap
, format
);
179 n
= vsnprintf(cd
->cd_ptr
, len
, format
, ap
);
182 cd
->cd_ptr
+= MIN(n
, len
);