1178525Sjb/* 2178525Sjb * CDDL HEADER START 3178525Sjb * 4178525Sjb * The contents of this file are subject to the terms of the 5178525Sjb * Common Development and Distribution License, Version 1.0 only 6178525Sjb * (the "License"). You may not use this file except in compliance 7178525Sjb * with the License. 8178525Sjb * 9178525Sjb * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10178525Sjb * or http://www.opensolaris.org/os/licensing. 11178525Sjb * See the License for the specific language governing permissions 12178525Sjb * and limitations under the License. 13178525Sjb * 14178525Sjb * When distributing Covered Code, include this CDDL HEADER in each 15178525Sjb * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16178525Sjb * If applicable, add the following below this CDDL HEADER, with the 17178525Sjb * fields enclosed by brackets "[]" replaced with your own identifying 18178525Sjb * information: Portions Copyright [yyyy] [name of copyright owner] 19178525Sjb * 20178525Sjb * CDDL HEADER END 21178525Sjb */ 22178525Sjb/* 23178525Sjb * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24178525Sjb * Use is subject to license terms. 25178525Sjb */ 26178525Sjb 27178525Sjb#pragma ident "%Z%%M% %I% %E% SMI" 28178525Sjb 29178525Sjb/* 30178525Sjb * CTF Declaration Stack 31178525Sjb * 32178525Sjb * In order to implement ctf_type_name(), we must convert a type graph back 33178525Sjb * into a C type declaration. Unfortunately, a type graph represents a storage 34178525Sjb * class ordering of the type whereas a type declaration must obey the C rules 35178525Sjb * for operator precedence, and the two orderings are frequently in conflict. 36178525Sjb * For example, consider these CTF type graphs and their C declarations: 37178525Sjb * 38178525Sjb * CTF_K_POINTER -> CTF_K_FUNCTION -> CTF_K_INTEGER : int (*)() 39178525Sjb * CTF_K_POINTER -> CTF_K_ARRAY -> CTF_K_INTEGER : int (*)[] 40178525Sjb * 41178525Sjb * In each case, parentheses are used to raise operator * to higher lexical 42178525Sjb * precedence, so the string form of the C declaration cannot be constructed by 43178525Sjb * walking the type graph links and forming the string from left to right. 44178525Sjb * 45178525Sjb * The functions in this file build a set of stacks from the type graph nodes 46178525Sjb * corresponding to the C operator precedence levels in the appropriate order. 47178525Sjb * The code in ctf_type_name() can then iterate over the levels and nodes in 48178525Sjb * lexical precedence order and construct the final C declaration string. 49178525Sjb */ 50178525Sjb 51178525Sjb#include <ctf_impl.h> 52178525Sjb 53178525Sjbvoid 54178525Sjbctf_decl_init(ctf_decl_t *cd, char *buf, size_t len) 55178525Sjb{ 56178525Sjb int i; 57178525Sjb 58178525Sjb bzero(cd, sizeof (ctf_decl_t)); 59178525Sjb 60178525Sjb for (i = CTF_PREC_BASE; i < CTF_PREC_MAX; i++) 61178525Sjb cd->cd_order[i] = CTF_PREC_BASE - 1; 62178525Sjb 63178525Sjb cd->cd_qualp = CTF_PREC_BASE; 64178525Sjb cd->cd_ordp = CTF_PREC_BASE; 65178525Sjb 66178525Sjb cd->cd_buf = buf; 67178525Sjb cd->cd_ptr = buf; 68178525Sjb cd->cd_end = buf + len; 69178525Sjb} 70178525Sjb 71178525Sjbvoid 72178525Sjbctf_decl_fini(ctf_decl_t *cd) 73178525Sjb{ 74178525Sjb ctf_decl_node_t *cdp, *ndp; 75178525Sjb int i; 76178525Sjb 77178525Sjb for (i = CTF_PREC_BASE; i < CTF_PREC_MAX; i++) { 78178525Sjb for (cdp = ctf_list_next(&cd->cd_nodes[i]); 79178525Sjb cdp != NULL; cdp = ndp) { 80178525Sjb ndp = ctf_list_next(cdp); 81178525Sjb ctf_free(cdp, sizeof (ctf_decl_node_t)); 82178525Sjb } 83178525Sjb } 84178525Sjb} 85178525Sjb 86178525Sjbvoid 87178525Sjbctf_decl_push(ctf_decl_t *cd, ctf_file_t *fp, ctf_id_t type) 88178525Sjb{ 89178525Sjb ctf_decl_node_t *cdp; 90178525Sjb ctf_decl_prec_t prec; 91178525Sjb uint_t kind, n = 1; 92178525Sjb int is_qual = 0; 93178525Sjb 94178525Sjb const ctf_type_t *tp; 95178525Sjb ctf_arinfo_t ar; 96178525Sjb 97178525Sjb if ((tp = ctf_lookup_by_id(&fp, type)) == NULL) { 98178525Sjb cd->cd_err = fp->ctf_errno; 99178525Sjb return; 100178525Sjb } 101178525Sjb 102178525Sjb switch (kind = LCTF_INFO_KIND(fp, tp->ctt_info)) { 103178525Sjb case CTF_K_ARRAY: 104178525Sjb (void) ctf_array_info(fp, type, &ar); 105178525Sjb ctf_decl_push(cd, fp, ar.ctr_contents); 106178525Sjb n = ar.ctr_nelems; 107178525Sjb prec = CTF_PREC_ARRAY; 108178525Sjb break; 109178525Sjb 110178525Sjb case CTF_K_TYPEDEF: 111178525Sjb if (ctf_strptr(fp, tp->ctt_name)[0] == '\0') { 112178525Sjb ctf_decl_push(cd, fp, tp->ctt_type); 113178525Sjb return; 114178525Sjb } 115178525Sjb prec = CTF_PREC_BASE; 116178525Sjb break; 117178525Sjb 118178525Sjb case CTF_K_FUNCTION: 119178525Sjb ctf_decl_push(cd, fp, tp->ctt_type); 120178525Sjb prec = CTF_PREC_FUNCTION; 121178525Sjb break; 122178525Sjb 123178525Sjb case CTF_K_POINTER: 124178525Sjb ctf_decl_push(cd, fp, tp->ctt_type); 125178525Sjb prec = CTF_PREC_POINTER; 126178525Sjb break; 127178525Sjb 128178525Sjb case CTF_K_VOLATILE: 129178525Sjb case CTF_K_CONST: 130178525Sjb case CTF_K_RESTRICT: 131178525Sjb ctf_decl_push(cd, fp, tp->ctt_type); 132178525Sjb prec = cd->cd_qualp; 133178525Sjb is_qual++; 134178525Sjb break; 135178525Sjb 136178525Sjb default: 137178525Sjb prec = CTF_PREC_BASE; 138178525Sjb } 139178525Sjb 140178525Sjb if ((cdp = ctf_alloc(sizeof (ctf_decl_node_t))) == NULL) { 141178525Sjb cd->cd_err = EAGAIN; 142178525Sjb return; 143178525Sjb } 144178525Sjb 145178525Sjb cdp->cd_type = type; 146178525Sjb cdp->cd_kind = kind; 147178525Sjb cdp->cd_n = n; 148178525Sjb 149178525Sjb if (ctf_list_next(&cd->cd_nodes[prec]) == NULL) 150178525Sjb cd->cd_order[prec] = cd->cd_ordp++; 151178525Sjb 152178525Sjb /* 153178525Sjb * Reset cd_qualp to the highest precedence level that we've seen so 154178525Sjb * far that can be qualified (CTF_PREC_BASE or CTF_PREC_POINTER). 155178525Sjb */ 156178525Sjb if (prec > cd->cd_qualp && prec < CTF_PREC_ARRAY) 157178525Sjb cd->cd_qualp = prec; 158178525Sjb 159178525Sjb /* 160178525Sjb * C array declarators are ordered inside out so prepend them. Also by 161178525Sjb * convention qualifiers of base types precede the type specifier (e.g. 162178525Sjb * const int vs. int const) even though the two forms are equivalent. 163178525Sjb */ 164178525Sjb if (kind == CTF_K_ARRAY || (is_qual && prec == CTF_PREC_BASE)) 165178525Sjb ctf_list_prepend(&cd->cd_nodes[prec], cdp); 166178525Sjb else 167178525Sjb ctf_list_append(&cd->cd_nodes[prec], cdp); 168178525Sjb} 169178525Sjb 170178525Sjb/*PRINTFLIKE2*/ 171178525Sjbvoid 172178525Sjbctf_decl_sprintf(ctf_decl_t *cd, const char *format, ...) 173178525Sjb{ 174178525Sjb size_t len = (size_t)(cd->cd_end - cd->cd_ptr); 175178525Sjb va_list ap; 176178525Sjb size_t n; 177178525Sjb 178178525Sjb va_start(ap, format); 179178525Sjb n = vsnprintf(cd->cd_ptr, len, format, ap); 180178525Sjb va_end(ap); 181178525Sjb 182178525Sjb cd->cd_ptr += MIN(n, len); 183178525Sjb cd->cd_len += n; 184178525Sjb} 185