1 /* 2 * CDDL HEADER START 3 * 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 7 * with the License. 8 * 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. 13 * 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] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2003 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #ifndef _PARSEPROTO_H 28 #define _PARSEPROTO_H 29 30 #pragma ident "%Z%%M% %I% %E% SMI" 31 32 #ifdef __cplusplus 33 extern "C" { 34 #endif 35 36 /* 37 * DECL - parse C type declarations. 38 * 39 * 1) Does not understand struct, union or enum definitions. 40 * 2) Does not understand auto, static, extern or typedef storage class 41 * specifiers. 42 * 3) Does not support initialization. 43 * 4) Does not support type definition. 44 * 5) Only understands array dimension specified as constant decimal 45 * integer or identifier. 46 * 47 * Supported Operations 48 * 49 * decl_Parse convert string to a decl_t. 50 * decl_Destroy Free space associated with a (previously returned) 51 * decl_t. The function follows the argument list. 52 * decl_SetName set identifier. 53 * decl_GetName return identifier. 54 * decl_ToString convert a (previously returned) decl_t into a 55 * printable representation. 56 * decl_GetArgLength return length of argument list. 57 * decl_GetNext return the next decl_t associated with the given 58 * decl_t. 59 * decl_GetDeclSpec return the declaration specifier. 60 * decl_GetDSName return identifier associated with a 61 * declaration specifier. 62 * decl_GetType return the type_t associated with a decl_t. 63 * decl_IsVarargs return true if the given decl_t is a varargs function. 64 * decl_IsFunction return true if the given decl_t is a function. 65 * 66 * type_GetNext return the next type_t associated with a given type_t. 67 * type_IsArray return true if the given type_t is an array. 68 * type_GetArraySize return size of array. 69 * 70 * type_IsPtrTo return true if the given type_t is a pointer to ... . 71 * type_GetPtrToTypeQual return type qualifiers for a pointer to ... . 72 * 73 * type_IsFunction return true if the given type_t is a function. 74 * type_GetArgLength return length of argument list. 75 * type_IsVarargs return true if function signature includes ... . 76 * type_GetArg return the decl_t associated with a given type_t. 77 * type_IsPtrFun return true if the given type_t is a pointer* to a 78 * function. 79 */ 80 81 /* Include Files */ 82 83 #include <stdio.h> 84 #include <ctype.h> 85 #include <string.h> 86 87 /* Macros and Constants */ 88 89 #define loop for (;;) 90 91 #define STT_isvoid(s) ((s) & (TS_VOID)) 92 #define STT_isfloat(s) ((s) & (TS_FLOAT | TS_DOUBLE)) 93 #define STT_ischar(s) ((s) & (TS_CHAR)) 94 #define STT_isint(s) ((s) & \ 95 (TS_SHORT | TS_INT | TS_LONG | TS_LONGLONG | TS_CHAR)) 96 #define STT_isarith(s) (STT_isfloat(s) || STT_isint(s)) 97 #define STT_isbasic(s) (STT_isarith(s) || STT_isvoid(s)) 98 #define STT_isderived(s) ((s) & (TS_STRUCT | TS_UNION | TS_ENUM | TS_TYPEDEF)) 99 #define STT_has_explicit_sign(s) ((s) & (TS_SIGNED | TS_UNSIGNED)) 100 101 /* Data Declarations */ 102 103 /* 104 * The overall type encoding is thus: 105 * 106 * decl_t encodes a declaration which consists of: 107 * identifier 108 * declaration specifier (storage class specifier, type specifier, 109 * type qualifier) 110 * type modifiers (array, function, pointer to) 111 * ancillary (varargs?, argument list) 112 * 113 * The argument list is an ordered, NULL terminated, linked list. 114 * 115 * An empty argument list (== NULL) indicates an unknown argument 116 * list, i.e. "()". 117 * 118 * declaration specifiers are encoded as bits in an enum (stt_t). 119 * 120 * type modifiers are encoded as a linked list of variant records, 121 * i.e. "array of ..." 122 * "function returning ..." and "pointer to ...". 123 * 124 * An empty list of type modifiers (== NULL) indicates a "plain" type. 125 * 126 * 127 * OK, here goes some ASCII art... 128 * 129 * 130 * base object 131 * | 132 * | 133 * V 134 * 135 * ---------- ---------- ---------- ---------- 136 * | | | | | | | | 137 * | decl_t | --> | type_t | --> | type_t | ... | type_t | --> NULL 138 * | | | | |(DD_FUN)| | | 139 * ---------- ---------- ---------- ---------- 140 * | | 141 * | | 142 * V V 143 * A ---------- ---------- 144 * NULL r | | | | 145 * g | decl_t | --> | type_t | ... --> NULL 146 * u | | | | 147 * m ---------- ---------- 148 * e | 149 * n | 150 * t V 151 * ---------- 152 * L | | 153 * i | decl_t | ... --> NULL 154 * s | | 155 * t ---------- 156 * 157 * ... 158 * 159 * | 160 * | 161 * V 162 * 163 * NULL 164 */ 165 166 /* 167 * The encoding of a declaration specifier is done primarily with an 168 * stt_t type. 169 * This type must support bit-wise operations. 170 */ 171 172 typedef enum { 173 SCS_MASK = 0x000000ff, /* storage class specifiers */ 174 SCS_NONE = 0x00000000, 175 SCS_REGISTER = 0x00000001, 176 SCS_TYPEDEF = 0x00000002, 177 SCS_EXTERN = 0x00000004, 178 SCS_AUTO = 0x00000008, 179 SCS_STATIC = 0x00000010, 180 181 TS_MASK = 0x00ffff00, /* type specifiers */ 182 TS_NO_TS = 0x00000000, 183 TS_CHAR = 0x00000100, 184 TS_SHORT = 0x00000200, 185 TS_INT = 0x00000400, 186 TS_LONG = 0x00000800, 187 TS_SIGNED = 0x00001000, 188 TS_UNSIGNED = 0x00002000, 189 TS_ENUM = 0x00004000, 190 TS_FLOAT = 0x00010000, 191 TS_DOUBLE = 0x00020000, 192 TS_STRUCT = 0x00040000, 193 TS_UNION = 0x00080000, 194 TS_TYPEDEF = 0x00100000, 195 TS_VOID = 0x00200000, 196 TS_LONGLONG = 0x00400000, /* non-ANSI type: long long */ 197 198 TQ_MASK = 0x0f000000, /* type qualifiers */ 199 TQ_NONE = 0x00000000, 200 TQ_CONST = 0x01000000, 201 TQ_VOLATILE = 0x02000000, 202 TQ_RESTRICT = 0x04000000, 203 TQ_RESTRICT_KYWD = 0x08000000 204 } stt_t; 205 206 typedef enum { /* declarator options */ 207 DD_NONE = 0, 208 DD_ARY = 1, /* array of [size] ... */ 209 DD_FUN = 2, /* function [taking and] returning ... */ 210 DD_PTR = 3 /* [tq] pointer to ... */ 211 } decl_type_t; 212 213 typedef enum { 214 DTS_DECL = 0, 215 DTS_CAST = 1, 216 DTS_RET = 3 217 } decl_dts_t; 218 219 typedef struct { 220 stt_t ds_stt; /* scs|ts|tq */ 221 char *ds_id; /* id for struct|union|enum|typedef */ 222 } decl_spec_t; 223 224 typedef struct _declarator decl_t; 225 226 typedef struct _type { 227 struct _type *t_next; /* next type_t or NULL */ 228 decl_type_t t_dt; /* oneof DD_* */ 229 /* DD_FUN */ 230 int t_nargs; /* number of arguments */ 231 int t_ellipsis; /* a varargs? */ 232 decl_t *t_args; /* list of arguments */ 233 /* DD_PTR */ 234 stt_t t_stt; /* type qualifier, TQ_* */ 235 /* DD_ARY */ 236 char *t_sizestr; /* size as a string */ 237 } type_t; 238 239 struct _declarator { 240 char *d_name; /* name of declarator */ 241 decl_spec_t *d_ds; /* ts|scs|tq */ 242 type_t *d_type; /* list of attributes or NULL */ 243 int d_ellipsis; /* a varargs? */ 244 decl_t *d_next; /* next link in chain (arglist) */ 245 }; 246 247 /* External Declarations */ 248 249 extern char *declspec_ToString(char *, decl_spec_t *); 250 251 extern void decl_Destroy(decl_t *); 252 extern int decl_GetArgLength(decl_t *); 253 extern decl_t *decl_SetName(decl_t *, char *); 254 extern char *decl_GetName(decl_t *); 255 extern type_t *decl_GetType(decl_t *); 256 extern int decl_IsVarargs(decl_t *dp); 257 extern char *decl_ToString(char *, decl_dts_t, decl_t *, 258 const char *); 259 extern const char *decl_Parse(char *, decl_t **); 260 extern void decl_GetTraceInfo(decl_t *, char *, char *, decl_t **); 261 extern char *decl_ToFormal(decl_t *); 262 extern int type_IsArray(type_t *); 263 extern int type_IsPtrTo(type_t *); 264 extern int type_IsFunction(type_t *); 265 extern int type_IsVarargs(type_t *); 266 extern int type_IsPtrFun(type_t *); 267 extern decl_t *decl_AddArgNames(decl_t *); 268 269 #ifdef __cplusplus 270 } 271 #endif 272 273 #endif /* _PARSEPROTO_H */ 274