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
33extern "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
172typedef 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
206typedef 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
213typedef enum {
214	DTS_DECL = 0,
215	DTS_CAST = 1,
216	DTS_RET  = 3
217} decl_dts_t;
218
219typedef struct {
220	stt_t	 ds_stt;	/* scs|ts|tq */
221	char	*ds_id;		/* id for struct|union|enum|typedef */
222} decl_spec_t;
223
224typedef struct _declarator	decl_t;
225
226typedef 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
239struct _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
249extern	char		*declspec_ToString(char *, decl_spec_t *);
250
251extern	void		decl_Destroy(decl_t *);
252extern	int		decl_GetArgLength(decl_t *);
253extern	decl_t		*decl_SetName(decl_t *, char *);
254extern	char		*decl_GetName(decl_t *);
255extern	type_t		*decl_GetType(decl_t *);
256extern	int		decl_IsVarargs(decl_t *dp);
257extern	char		*decl_ToString(char *, decl_dts_t, decl_t *,
258			    const char *);
259extern	const char	*decl_Parse(char *, decl_t **);
260extern	void		decl_GetTraceInfo(decl_t *, char *, char *, decl_t **);
261extern	char 		*decl_ToFormal(decl_t *);
262extern	int		type_IsArray(type_t *);
263extern	int		type_IsPtrTo(type_t *);
264extern	int		type_IsFunction(type_t *);
265extern	int		type_IsVarargs(type_t *);
266extern	int		type_IsPtrFun(type_t *);
267extern	decl_t		*decl_AddArgNames(decl_t *);
268
269#ifdef	__cplusplus
270}
271#endif
272
273#endif	/* _PARSEPROTO_H */
274