1*753d2d2eSraf %{
2*753d2d2eSraf /*
3*753d2d2eSraf * CDDL HEADER START
4*753d2d2eSraf *
5*753d2d2eSraf * The contents of this file are subject to the terms of the
6*753d2d2eSraf * Common Development and Distribution License, Version 1.0 only
7*753d2d2eSraf * (the "License"). You may not use this file except in compliance
8*753d2d2eSraf * with the License.
9*753d2d2eSraf *
10*753d2d2eSraf * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
11*753d2d2eSraf * or http://www.opensolaris.org/os/licensing.
12*753d2d2eSraf * See the License for the specific language governing permissions
13*753d2d2eSraf * and limitations under the License.
14*753d2d2eSraf *
15*753d2d2eSraf * When distributing Covered Code, include this CDDL HEADER in each
16*753d2d2eSraf * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
17*753d2d2eSraf * If applicable, add the following below this CDDL HEADER, with the
18*753d2d2eSraf * fields enclosed by brackets "[]" replaced with your own identifying
19*753d2d2eSraf * information: Portions Copyright [yyyy] [name of copyright owner]
20*753d2d2eSraf *
21*753d2d2eSraf * CDDL HEADER END
22*753d2d2eSraf */
23*753d2d2eSraf
24*753d2d2eSraf /*
25*753d2d2eSraf * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
26*753d2d2eSraf * Use is subject to license terms.
27*753d2d2eSraf */
28*753d2d2eSraf
29*753d2d2eSraf #pragma ident "%Z%%M% %I% %E% SMI"
30*753d2d2eSraf
31*753d2d2eSraf #include "parseproto.h"
32*753d2d2eSraf #include <assert.h>
33*753d2d2eSraf
34*753d2d2eSraf static decl_spec_t *declspec_Construct(void);
35*753d2d2eSraf static void declspec_Destroy(decl_spec_t *);
36*753d2d2eSraf static decl_spec_t *declspec_Init(stt_t, char *);
37*753d2d2eSraf static char *declspec_VerifySTT(stt_t, stt_t);
38*753d2d2eSraf static decl_spec_t *declspec_AddSTT(decl_spec_t *, stt_t, const char **);
39*753d2d2eSraf static decl_spec_t *declspec_AddDS(decl_spec_t *,
40*753d2d2eSraf decl_spec_t *, const char **);
41*753d2d2eSraf static stt_t declspec_GetSTT(decl_spec_t *);
42*753d2d2eSraf static char *declspec_GetTag(decl_spec_t *);
43*753d2d2eSraf static type_t *type_Construct(void);
44*753d2d2eSraf static void type_Destroy(type_t *);
45*753d2d2eSraf static type_t *type_SetPtr(type_t *, stt_t);
46*753d2d2eSraf static type_t *type_SetFun(type_t *, decl_t *);
47*753d2d2eSraf static type_t *type_AddTail(type_t *, type_t *);
48*753d2d2eSraf static const char *type_Verify(type_t *);
49*753d2d2eSraf
50*753d2d2eSraf static decl_t *decl_Construct(void);
51*753d2d2eSraf static decl_t *decl_AddArg(decl_t *, decl_t *);
52*753d2d2eSraf static int decl_IsVoid(decl_t *);
53*753d2d2eSraf static int decl_IsVoidArray(decl_t *);
54*753d2d2eSraf static const char *decl_VerifyArgs(decl_t *);
55*753d2d2eSraf static decl_t *decl_AddDS(decl_t *, decl_spec_t *, const char **);
56*753d2d2eSraf static decl_t *decl_AddTypeTail(decl_t *, type_t *);
57*753d2d2eSraf static decl_t *decl_addptr(decl_t *, type_t *);
58*753d2d2eSraf static decl_t *decl_addary(decl_t *, char *);
59*753d2d2eSraf static decl_t *decl_addfun(decl_t *, decl_t *);
60*753d2d2eSraf static decl_t *decl_addellipsis(decl_t *);
61*753d2d2eSraf
62*753d2d2eSraf #if defined(DEBUG)
63*753d2d2eSraf static void type_PrintType(type_t *, int);
64*753d2d2eSraf static void decl_PrintDecl(decl_t *, int);
65*753d2d2eSraf static void decl_PrintTraceInfo(decl_t *);
66*753d2d2eSraf static char *de_const(char *);
67*753d2d2eSraf #endif
68*753d2d2eSraf
69*753d2d2eSraf
70*753d2d2eSraf
71*753d2d2eSraf static int yylex(void);
72*753d2d2eSraf static void yyerror(const char *);
73*753d2d2eSraf static int yyparse(void);
74*753d2d2eSraf
75*753d2d2eSraf #if defined(MEM_DEBUG)
76*753d2d2eSraf static int declspec_Construct_calls;
77*753d2d2eSraf static int type_Construct_calls;
78*753d2d2eSraf static int decl_Construct_calls;
79*753d2d2eSraf #endif
80*753d2d2eSraf
81*753d2d2eSraf #if defined(DEBUG)
82*753d2d2eSraf static char *de_const(char *);
83*753d2d2eSraf #endif
84*753d2d2eSraf %}
85*753d2d2eSraf
86*753d2d2eSraf %union {
87*753d2d2eSraf char *s_val;
88*753d2d2eSraf int i_val;
89*753d2d2eSraf stt_t stt_val;
90*753d2d2eSraf decl_spec_t *ds_val;
91*753d2d2eSraf type_t *t_val;
92*753d2d2eSraf decl_t *d_val;
93*753d2d2eSraf }
94*753d2d2eSraf
95*753d2d2eSraf %token <i_val> ELLIPSIS
96*753d2d2eSraf
97*753d2d2eSraf %token <s_val> INTEGER
98*753d2d2eSraf %token <s_val> IDENTIFIER
99*753d2d2eSraf %token <s_val> TYPEDEF_NAME
100*753d2d2eSraf %type <s_val> constant_expression
101*753d2d2eSraf
102*753d2d2eSraf %token <stt_val> REGISTER
103*753d2d2eSraf %token <stt_val> TYPEDEF EXTERN AUTO STATIC
104*753d2d2eSraf %token <stt_val> VOID CHAR SHORT INT LONG
105*753d2d2eSraf %token <stt_val> FLOAT DOUBLE SIGNED UNSIGNED
106*753d2d2eSraf %token <stt_val> CONST VOLATILE RESTRICT RESTRICT_KYWD
107*753d2d2eSraf %type <stt_val> struct_or_union
108*753d2d2eSraf %type <ds_val> storage_class_specifier
109*753d2d2eSraf %type <ds_val> type_qualifier
110*753d2d2eSraf %type <ds_val> type_qualifier_list
111*753d2d2eSraf
112*753d2d2eSraf %token <ds_val> STRUCT UNION
113*753d2d2eSraf %token <ds_val> ENUM
114*753d2d2eSraf %type <ds_val> declaration_specifiers
115*753d2d2eSraf %type <ds_val> type_specifier
116*753d2d2eSraf %type <ds_val> struct_or_union_specifier enum_specifier
117*753d2d2eSraf %type <ds_val> typedef_name
118*753d2d2eSraf
119*753d2d2eSraf %type <t_val> pointer
120*753d2d2eSraf
121*753d2d2eSraf %type <d_val> declaration
122*753d2d2eSraf %type <d_val> init_declarator_list init_declarator
123*753d2d2eSraf %type <d_val> declarator
124*753d2d2eSraf %type <d_val> direct_declarator
125*753d2d2eSraf %type <d_val> parameter_type_list parameter_list
126*753d2d2eSraf %type <d_val> parameter_declaration
127*753d2d2eSraf %type <d_val> abstract_declarator
128*753d2d2eSraf %type <d_val> direct_abstract_declarator
129*753d2d2eSraf
130*753d2d2eSraf %start declaration
131*753d2d2eSraf
132*753d2d2eSraf %%
133*753d2d2eSraf
134*753d2d2eSraf /*
135*753d2d2eSraf * The grammar is derived from ANSI/ISO 9899-1990.
136*753d2d2eSraf */
137*753d2d2eSraf
138*753d2d2eSraf declaration
139*753d2d2eSraf : declaration_specifiers init_declarator_list ';'
140*753d2d2eSraf {
141*753d2d2eSraf decl_t *dp;
142*753d2d2eSraf
143*753d2d2eSraf protop = $$ = $2;
144*753d2d2eSraf
145*753d2d2eSraf /* only one declaration allowed */
146*753d2d2eSraf assert(protop->d_next == NULL);
147*753d2d2eSraf
148*753d2d2eSraf for (dp = $2; dp && (errstr == NULL);
149*753d2d2eSraf dp = dp->d_next) {
150*753d2d2eSraf const char *sp;
151*753d2d2eSraf
152*753d2d2eSraf decl_AddDS(dp, $1, &errstr);
153*753d2d2eSraf if (sp = decl_Verify(dp))
154*753d2d2eSraf errstr = sp;
155*753d2d2eSraf }
156*753d2d2eSraf declspec_Destroy($1);
157*753d2d2eSraf }
158*753d2d2eSraf | error ';'
159*753d2d2eSraf {
160*753d2d2eSraf protop = $$ = NULL;
161*753d2d2eSraf errstr = "function prototype syntax error";
162*753d2d2eSraf }
163*753d2d2eSraf /*
164*753d2d2eSraf * XXX - Does not support a "stand-alone" declaration specifier. It is
165*753d2d2eSraf * essentially a type declaration, for example:
166*753d2d2eSraf *
167*753d2d2eSraf * typedef enum { FALSE = 0, TRUE = 1 } boolean_t;
168*753d2d2eSraf * or
169*753d2d2eSraf * struct _name { char *first; char *last };
170*753d2d2eSraf */
171*753d2d2eSraf
172*753d2d2eSraf /* XXX | declaration_specifiers */
173*753d2d2eSraf ;
174*753d2d2eSraf
175*753d2d2eSraf declaration_specifiers
176*753d2d2eSraf : storage_class_specifier declaration_specifiers
177*753d2d2eSraf {
178*753d2d2eSraf char const *ep;
179*753d2d2eSraf
180*753d2d2eSraf $$ = declspec_AddDS($2, $1, &ep);
181*753d2d2eSraf declspec_Destroy($1);
182*753d2d2eSraf
183*753d2d2eSraf if (errstr == NULL)
184*753d2d2eSraf errstr = ep;
185*753d2d2eSraf }
186*753d2d2eSraf | storage_class_specifier
187*753d2d2eSraf | type_specifier declaration_specifiers
188*753d2d2eSraf {
189*753d2d2eSraf const char *ep;
190*753d2d2eSraf
191*753d2d2eSraf $$ = declspec_AddDS($2, $1, &ep);
192*753d2d2eSraf declspec_Destroy($1);
193*753d2d2eSraf
194*753d2d2eSraf if (errstr == NULL)
195*753d2d2eSraf errstr = ep;
196*753d2d2eSraf }
197*753d2d2eSraf | type_specifier
198*753d2d2eSraf | type_qualifier declaration_specifiers
199*753d2d2eSraf {
200*753d2d2eSraf const char *ep;
201*753d2d2eSraf
202*753d2d2eSraf $$ = declspec_AddDS($2, $1, &ep);
203*753d2d2eSraf declspec_Destroy($1);
204*753d2d2eSraf
205*753d2d2eSraf if (errstr == NULL)
206*753d2d2eSraf errstr = ep;
207*753d2d2eSraf }
208*753d2d2eSraf | type_qualifier
209*753d2d2eSraf ;
210*753d2d2eSraf
211*753d2d2eSraf storage_class_specifier
212*753d2d2eSraf : REGISTER
213*753d2d2eSraf {
214*753d2d2eSraf $$ = declspec_Init(SCS_REGISTER, NULL);
215*753d2d2eSraf }
216*753d2d2eSraf /*
217*753d2d2eSraf * XXX - Does not support any storage class specifier other than
218*753d2d2eSraf * register, and then only for function arguments.
219*753d2d2eSraf *
220*753d2d2eSraf | TYPEDEF
221*753d2d2eSraf {
222*753d2d2eSraf $$ = declspec_Init(SCS_TYPEDEF, NULL);
223*753d2d2eSraf }
224*753d2d2eSraf | EXTERN
225*753d2d2eSraf {
226*753d2d2eSraf $$ = declspec_Init(SCS_EXTERN, NULL);
227*753d2d2eSraf }
228*753d2d2eSraf | STATIC
229*753d2d2eSraf {
230*753d2d2eSraf $$ = declspec_Init(SCS_STATIC, NULL);
231*753d2d2eSraf }
232*753d2d2eSraf | AUTO
233*753d2d2eSraf {
234*753d2d2eSraf $$ = declspec_Init(SCS_AUTO, NULL);
235*753d2d2eSraf }
236*753d2d2eSraf */
237*753d2d2eSraf ;
238*753d2d2eSraf
239*753d2d2eSraf type_specifier
240*753d2d2eSraf : VOID
241*753d2d2eSraf {
242*753d2d2eSraf $$ = declspec_Init(TS_VOID, NULL);
243*753d2d2eSraf atIDENT = 1;
244*753d2d2eSraf }
245*753d2d2eSraf | CHAR
246*753d2d2eSraf {
247*753d2d2eSraf $$ = declspec_Init(TS_CHAR, NULL);
248*753d2d2eSraf atIDENT = 1;
249*753d2d2eSraf }
250*753d2d2eSraf | SHORT
251*753d2d2eSraf {
252*753d2d2eSraf $$ = declspec_Init(TS_SHORT, NULL);
253*753d2d2eSraf atIDENT = 1;
254*753d2d2eSraf }
255*753d2d2eSraf | INT
256*753d2d2eSraf {
257*753d2d2eSraf $$ = declspec_Init(TS_INT, NULL);
258*753d2d2eSraf atIDENT = 1;
259*753d2d2eSraf }
260*753d2d2eSraf | LONG
261*753d2d2eSraf {
262*753d2d2eSraf $$ = declspec_Init(TS_LONG, NULL);
263*753d2d2eSraf atIDENT = 1;
264*753d2d2eSraf }
265*753d2d2eSraf | FLOAT
266*753d2d2eSraf {
267*753d2d2eSraf $$ = declspec_Init(TS_FLOAT, NULL);
268*753d2d2eSraf atIDENT = 1;
269*753d2d2eSraf }
270*753d2d2eSraf | DOUBLE
271*753d2d2eSraf {
272*753d2d2eSraf $$ = declspec_Init(TS_DOUBLE, NULL);
273*753d2d2eSraf atIDENT = 1;
274*753d2d2eSraf }
275*753d2d2eSraf | SIGNED
276*753d2d2eSraf {
277*753d2d2eSraf $$ = declspec_Init(TS_SIGNED, NULL);
278*753d2d2eSraf atIDENT = 1;
279*753d2d2eSraf }
280*753d2d2eSraf | UNSIGNED
281*753d2d2eSraf {
282*753d2d2eSraf $$ = declspec_Init(TS_UNSIGNED, NULL);
283*753d2d2eSraf atIDENT = 1;
284*753d2d2eSraf }
285*753d2d2eSraf | struct_or_union_specifier
286*753d2d2eSraf | enum_specifier
287*753d2d2eSraf | typedef_name
288*753d2d2eSraf ;
289*753d2d2eSraf
290*753d2d2eSraf typedef_name
291*753d2d2eSraf : TYPEDEF_NAME
292*753d2d2eSraf {
293*753d2d2eSraf $$ = declspec_Init(TS_TYPEDEF, $1);
294*753d2d2eSraf atIDENT = 1;
295*753d2d2eSraf free($1);
296*753d2d2eSraf }
297*753d2d2eSraf ;
298*753d2d2eSraf
299*753d2d2eSraf /*
300*753d2d2eSraf * The "restrict" keyword is new in the C99 standard.
301*753d2d2eSraf * It is type qualifier like const and volatile.
302*753d2d2eSraf * We are using "_RESTRICT_KYWD" in headers and source code so
303*753d2d2eSraf * it is easily turned on and off by various macros at compile time.
304*753d2d2eSraf * In order for the "restrict" keyword to be recognized you must
305*753d2d2eSraf * be using a C99 compliant compiler in its native mode.
306*753d2d2eSraf */
307*753d2d2eSraf type_qualifier
308*753d2d2eSraf : CONST
309*753d2d2eSraf {
310*753d2d2eSraf $$ = declspec_Init(TQ_CONST, NULL);
311*753d2d2eSraf }
312*753d2d2eSraf | VOLATILE
313*753d2d2eSraf {
314*753d2d2eSraf $$ = declspec_Init(TQ_VOLATILE, NULL);
315*753d2d2eSraf }
316*753d2d2eSraf | RESTRICT
317*753d2d2eSraf {
318*753d2d2eSraf $$ = declspec_Init(TQ_RESTRICT, NULL);
319*753d2d2eSraf }
320*753d2d2eSraf | RESTRICT_KYWD
321*753d2d2eSraf {
322*753d2d2eSraf $$ = declspec_Init(TQ_RESTRICT_KYWD, NULL);
323*753d2d2eSraf }
324*753d2d2eSraf ;
325*753d2d2eSraf
326*753d2d2eSraf struct_or_union_specifier
327*753d2d2eSraf : struct_or_union { atIDENT = 1; } IDENTIFIER
328*753d2d2eSraf {
329*753d2d2eSraf $$ = declspec_Init($1, $3);
330*753d2d2eSraf free($3);
331*753d2d2eSraf }
332*753d2d2eSraf /*
333*753d2d2eSraf * XXX - struct or union definitions are not supported. It is generally
334*753d2d2eSraf * not done within the context of a function declaration (prototype) or
335*753d2d2eSraf * variable definition.
336*753d2d2eSraf
337*753d2d2eSraf | struct_or_union IDENTIFIER '{' struct_declaration_list '}'
338*753d2d2eSraf | struct_or_union '{' struct_declaration_list '}'
339*753d2d2eSraf */
340*753d2d2eSraf ;
341*753d2d2eSraf
342*753d2d2eSraf struct_or_union
343*753d2d2eSraf : STRUCT
344*753d2d2eSraf {
345*753d2d2eSraf $$ = TS_STRUCT;
346*753d2d2eSraf }
347*753d2d2eSraf | UNION
348*753d2d2eSraf {
349*753d2d2eSraf $$ = TS_UNION;
350*753d2d2eSraf }
351*753d2d2eSraf ;
352*753d2d2eSraf
353*753d2d2eSraf init_declarator_list
354*753d2d2eSraf : init_declarator
355*753d2d2eSraf {
356*753d2d2eSraf $$ = $1;
357*753d2d2eSraf atIDENT = 1;
358*753d2d2eSraf }
359*753d2d2eSraf /*
360*753d2d2eSraf * XXX - Does not support a comma separated list of declarations or
361*753d2d2eSraf * definitions. Function prototypes or variable definitions must be
362*753d2d2eSraf * given as one per C statement.
363*753d2d2eSraf
364*753d2d2eSraf | init_declarator_list ',' init_declarator
365*753d2d2eSraf {
366*753d2d2eSraf $$ = decl_AddArg($1, $3);
367*753d2d2eSraf atIDENT = 1;
368*753d2d2eSraf }
369*753d2d2eSraf */
370*753d2d2eSraf ;
371*753d2d2eSraf
372*753d2d2eSraf init_declarator
373*753d2d2eSraf : declarator
374*753d2d2eSraf /*
375*753d2d2eSraf * XXX - Initialization is not supported.
376*753d2d2eSraf
377*753d2d2eSraf | declarator '=' initializer
378*753d2d2eSraf */
379*753d2d2eSraf ;
380*753d2d2eSraf
381*753d2d2eSraf
382*753d2d2eSraf enum_specifier
383*753d2d2eSraf : ENUM { atIDENT = 1; } IDENTIFIER
384*753d2d2eSraf {
385*753d2d2eSraf $$ = declspec_Init(TS_ENUM, $3);
386*753d2d2eSraf free($3);
387*753d2d2eSraf }
388*753d2d2eSraf /*
389*753d2d2eSraf * XXX - enumerator definition is not supported for the same reasons
390*753d2d2eSraf * struct|union definition is not supported.
391*753d2d2eSraf
392*753d2d2eSraf | ENUM IDENTIFIER '{' enumerator_list '}'
393*753d2d2eSraf | ENUM '{' enumerator_list '}'
394*753d2d2eSraf */
395*753d2d2eSraf ;
396*753d2d2eSraf
397*753d2d2eSraf
398*753d2d2eSraf declarator
399*753d2d2eSraf : pointer direct_declarator
400*753d2d2eSraf {
401*753d2d2eSraf $$ = decl_addptr($2, $1);
402*753d2d2eSraf }
403*753d2d2eSraf | direct_declarator
404*753d2d2eSraf ;
405*753d2d2eSraf
406*753d2d2eSraf direct_declarator
407*753d2d2eSraf : IDENTIFIER
408*753d2d2eSraf {
409*753d2d2eSraf $$ = decl_SetName(decl_Construct(), $1);
410*753d2d2eSraf atIDENT = 0;
411*753d2d2eSraf free($1);
412*753d2d2eSraf }
413*753d2d2eSraf | '(' declarator ')'
414*753d2d2eSraf {
415*753d2d2eSraf $$ = $2;
416*753d2d2eSraf }
417*753d2d2eSraf | direct_declarator '[' constant_expression ']'
418*753d2d2eSraf {
419*753d2d2eSraf $$ = decl_addary($1, $3);
420*753d2d2eSraf free($3);
421*753d2d2eSraf }
422*753d2d2eSraf | direct_declarator '[' ']'
423*753d2d2eSraf {
424*753d2d2eSraf $$ = decl_addary($1, NULL);
425*753d2d2eSraf }
426*753d2d2eSraf | direct_declarator '(' parameter_type_list ')'
427*753d2d2eSraf {
428*753d2d2eSraf $$ = decl_addfun($1, $3);
429*753d2d2eSraf }
430*753d2d2eSraf | direct_declarator '(' ')'
431*753d2d2eSraf {
432*753d2d2eSraf $$ = decl_addfun($1, NULL);
433*753d2d2eSraf }
434*753d2d2eSraf ;
435*753d2d2eSraf
436*753d2d2eSraf pointer
437*753d2d2eSraf : '*' type_qualifier_list
438*753d2d2eSraf {
439*753d2d2eSraf $$ = type_SetPtr(type_Construct(), ($2)->ds_stt);
440*753d2d2eSraf declspec_Destroy($2);
441*753d2d2eSraf }
442*753d2d2eSraf | '*'
443*753d2d2eSraf {
444*753d2d2eSraf $$ = type_SetPtr(type_Construct(), TQ_NONE);
445*753d2d2eSraf }
446*753d2d2eSraf | '*' type_qualifier_list pointer
447*753d2d2eSraf {
448*753d2d2eSraf type_t *tp = type_Construct();
449*753d2d2eSraf
450*753d2d2eSraf type_SetPtr(tp, ($2)->ds_stt);
451*753d2d2eSraf declspec_Destroy($2);
452*753d2d2eSraf $$ = type_AddTail($3, tp);
453*753d2d2eSraf }
454*753d2d2eSraf | '*' pointer
455*753d2d2eSraf {
456*753d2d2eSraf type_t *tp = type_Construct();
457*753d2d2eSraf
458*753d2d2eSraf type_SetPtr(tp, TQ_NONE);
459*753d2d2eSraf $$ = type_AddTail($2, tp);
460*753d2d2eSraf }
461*753d2d2eSraf ;
462*753d2d2eSraf
463*753d2d2eSraf type_qualifier_list
464*753d2d2eSraf : type_qualifier
465*753d2d2eSraf | type_qualifier_list type_qualifier
466*753d2d2eSraf {
467*753d2d2eSraf const char *ep;
468*753d2d2eSraf
469*753d2d2eSraf /* XXX - ignore any error */
470*753d2d2eSraf $$ = declspec_AddDS($1, $2, &ep);
471*753d2d2eSraf declspec_Destroy($2);
472*753d2d2eSraf }
473*753d2d2eSraf ;
474*753d2d2eSraf
475*753d2d2eSraf parameter_type_list
476*753d2d2eSraf : parameter_list
477*753d2d2eSraf | parameter_list ',' ELLIPSIS
478*753d2d2eSraf {
479*753d2d2eSraf $$ = decl_addellipsis($1);
480*753d2d2eSraf }
481*753d2d2eSraf ;
482*753d2d2eSraf
483*753d2d2eSraf parameter_list
484*753d2d2eSraf : parameter_declaration
485*753d2d2eSraf {
486*753d2d2eSraf const char *sp = type_Verify($1->d_type);
487*753d2d2eSraf
488*753d2d2eSraf if (sp)
489*753d2d2eSraf errstr = sp;
490*753d2d2eSraf
491*753d2d2eSraf $$ = $1;
492*753d2d2eSraf atIDENT = 0;
493*753d2d2eSraf }
494*753d2d2eSraf | parameter_list ',' parameter_declaration
495*753d2d2eSraf {
496*753d2d2eSraf const char *sp = type_Verify($3->d_type);
497*753d2d2eSraf
498*753d2d2eSraf if (sp)
499*753d2d2eSraf errstr = sp;
500*753d2d2eSraf
501*753d2d2eSraf $$ = decl_AddArg($1, $3);
502*753d2d2eSraf atIDENT = 0;
503*753d2d2eSraf }
504*753d2d2eSraf ;
505*753d2d2eSraf
506*753d2d2eSraf parameter_declaration
507*753d2d2eSraf : declaration_specifiers declarator
508*753d2d2eSraf {
509*753d2d2eSraf const char *ep;
510*753d2d2eSraf
511*753d2d2eSraf $$ = decl_AddDS($2, $1, &ep);
512*753d2d2eSraf declspec_Destroy($1);
513*753d2d2eSraf
514*753d2d2eSraf if (errstr == NULL)
515*753d2d2eSraf errstr = ep;
516*753d2d2eSraf }
517*753d2d2eSraf | declaration_specifiers abstract_declarator
518*753d2d2eSraf {
519*753d2d2eSraf const char *ep;
520*753d2d2eSraf
521*753d2d2eSraf $$ = decl_AddDS($2, $1, &ep);
522*753d2d2eSraf declspec_Destroy($1);
523*753d2d2eSraf
524*753d2d2eSraf if (errstr == NULL)
525*753d2d2eSraf errstr = ep;
526*753d2d2eSraf }
527*753d2d2eSraf | declaration_specifiers
528*753d2d2eSraf {
529*753d2d2eSraf const char *ep;
530*753d2d2eSraf
531*753d2d2eSraf $$ = decl_AddDS(decl_Construct(), $1, &ep);
532*753d2d2eSraf declspec_Destroy($1);
533*753d2d2eSraf
534*753d2d2eSraf if (errstr == NULL)
535*753d2d2eSraf errstr = ep;
536*753d2d2eSraf }
537*753d2d2eSraf ;
538*753d2d2eSraf
539*753d2d2eSraf abstract_declarator
540*753d2d2eSraf : pointer
541*753d2d2eSraf {
542*753d2d2eSraf $$ = decl_addptr(decl_Construct(), $1);
543*753d2d2eSraf }
544*753d2d2eSraf | pointer direct_abstract_declarator
545*753d2d2eSraf {
546*753d2d2eSraf $$ = decl_addptr($2, $1);
547*753d2d2eSraf }
548*753d2d2eSraf | direct_abstract_declarator
549*753d2d2eSraf ;
550*753d2d2eSraf
551*753d2d2eSraf direct_abstract_declarator
552*753d2d2eSraf : '(' abstract_declarator ')'
553*753d2d2eSraf {
554*753d2d2eSraf $$ = $2;
555*753d2d2eSraf }
556*753d2d2eSraf | direct_abstract_declarator '[' constant_expression ']'
557*753d2d2eSraf {
558*753d2d2eSraf $$ = decl_addary($1, $3);
559*753d2d2eSraf free($3);
560*753d2d2eSraf }
561*753d2d2eSraf | '[' constant_expression ']'
562*753d2d2eSraf {
563*753d2d2eSraf $$ = decl_addary(decl_Construct(), $2);
564*753d2d2eSraf free($2);
565*753d2d2eSraf }
566*753d2d2eSraf | direct_abstract_declarator '[' ']'
567*753d2d2eSraf {
568*753d2d2eSraf $$ = decl_addary($1, NULL);
569*753d2d2eSraf }
570*753d2d2eSraf | '[' ']'
571*753d2d2eSraf {
572*753d2d2eSraf $$ = decl_addary(decl_Construct(), NULL);
573*753d2d2eSraf }
574*753d2d2eSraf | direct_abstract_declarator '(' parameter_type_list ')'
575*753d2d2eSraf {
576*753d2d2eSraf $$ = decl_addfun($1, $3);
577*753d2d2eSraf }
578*753d2d2eSraf | '(' parameter_type_list ')'
579*753d2d2eSraf {
580*753d2d2eSraf $$ = decl_addfun(decl_Construct(), $2);
581*753d2d2eSraf }
582*753d2d2eSraf | direct_abstract_declarator '(' ')'
583*753d2d2eSraf {
584*753d2d2eSraf $$ = decl_addfun($1, NULL);
585*753d2d2eSraf }
586*753d2d2eSraf | '(' ')'
587*753d2d2eSraf {
588*753d2d2eSraf $$ = decl_addfun(decl_Construct(), NULL);
589*753d2d2eSraf }
590*753d2d2eSraf ;
591*753d2d2eSraf
592*753d2d2eSraf /*
593*753d2d2eSraf * XXX - General case constant expressions are not supported. It would
594*753d2d2eSraf * be easy to implement (for the most part), but there are no cases to
595*753d2d2eSraf * date that require such a facility. The grammar does allow an
596*753d2d2eSraf * identifier (or typedef name) to be used since the prototype is not
597*753d2d2eSraf * processed by CPP. The only integer constant that is supported is
598*753d2d2eSraf * decimal.
599*753d2d2eSraf */
600*753d2d2eSraf
601*753d2d2eSraf constant_expression
602*753d2d2eSraf : INTEGER
603*753d2d2eSraf | IDENTIFIER
604*753d2d2eSraf | TYPEDEF_NAME
605*753d2d2eSraf ;
606*753d2d2eSraf
607*753d2d2eSraf %%
608*753d2d2eSraf
609*753d2d2eSraf /* Data Declarations */
610*753d2d2eSraf
611*753d2d2eSraf typedef struct {
612*753d2d2eSraf char *name;
613*753d2d2eSraf int token;
614*753d2d2eSraf stt_t stt;
615*753d2d2eSraf } keyword_t;
616*753d2d2eSraf
617*753d2d2eSraf typedef struct {
618*753d2d2eSraf stt_t s_stt;
619*753d2d2eSraf char *s_str;
620*753d2d2eSraf } sttpair_t;
621*753d2d2eSraf
622*753d2d2eSraf /* External Declarations */
623*753d2d2eSraf
624*753d2d2eSraf static const keyword_t *lookup_keyword(const char *);
625*753d2d2eSraf static const char *lookup_sttpair(stt_t);
626*753d2d2eSraf static int getch(void);
627*753d2d2eSraf static void ungetch(int);
628*753d2d2eSraf static void skipwhitespace(void);
629*753d2d2eSraf static int lookahead(int);
630*753d2d2eSraf static void skipcomment(void);
631*753d2d2eSraf
632*753d2d2eSraf /* External Definitions */
633*753d2d2eSraf
634*753d2d2eSraf static char *input = NULL; /* current place in the input stream */
635*753d2d2eSraf /* at point in stream were identifier is expected */
636*753d2d2eSraf static int atIDENT = 0;
637*753d2d2eSraf static decl_t *protop = NULL; /* pointer to prototype */
638*753d2d2eSraf static const char *errstr = NULL; /* error message */
639*753d2d2eSraf
640*753d2d2eSraf /*
641*753d2d2eSraf * lookup_keyword - Given a string, return the keyword_t or NULL.
642*753d2d2eSraf */
643*753d2d2eSraf
644*753d2d2eSraf static const keyword_t *
lookup_keyword(const char * name)645*753d2d2eSraf lookup_keyword(const char *name) {
646*753d2d2eSraf static const keyword_t keytbl[] = {
647*753d2d2eSraf { "register", REGISTER, SCS_REGISTER },
648*753d2d2eSraf #if UNSUPPORTED
649*753d2d2eSraf { "typedef", TYPEDEF, SCS_TYPEDEF },
650*753d2d2eSraf { "auto", AUTO, SCS_AUTO },
651*753d2d2eSraf { "static", STATIC, SCS_STATIC },
652*753d2d2eSraf { "extern", EXTERN, SCS_EXTERN },
653*753d2d2eSraf #endif /* UNSUPPORTED */
654*753d2d2eSraf { "void", VOID, TS_VOID },
655*753d2d2eSraf { "char", CHAR, TS_CHAR },
656*753d2d2eSraf { "short", SHORT, TS_SHORT },
657*753d2d2eSraf { "int", INT, TS_INT },
658*753d2d2eSraf { "long", LONG, TS_LONG },
659*753d2d2eSraf { "float", FLOAT, TS_FLOAT },
660*753d2d2eSraf { "double", DOUBLE, TS_DOUBLE },
661*753d2d2eSraf { "signed", SIGNED, TS_SIGNED },
662*753d2d2eSraf { "unsigned", UNSIGNED, TS_UNSIGNED },
663*753d2d2eSraf { "struct", STRUCT, TS_STRUCT },
664*753d2d2eSraf { "union", UNION, TS_UNION },
665*753d2d2eSraf { "enum", ENUM, TS_ENUM },
666*753d2d2eSraf
667*753d2d2eSraf { "const", CONST, TQ_CONST },
668*753d2d2eSraf { "volatile", VOLATILE, TQ_VOLATILE },
669*753d2d2eSraf { "restrict", RESTRICT, TQ_RESTRICT },
670*753d2d2eSraf { "_RESTRICT_KYWD",RESTRICT_KYWD, TQ_RESTRICT_KYWD},
671*753d2d2eSraf };
672*753d2d2eSraf #define NKEYWORD (sizeof (keytbl)/sizeof (keyword_t))
673*753d2d2eSraf
674*753d2d2eSraf int i;
675*753d2d2eSraf
676*753d2d2eSraf for (i = 0; i < NKEYWORD; ++i) {
677*753d2d2eSraf char *s = keytbl[i].name;
678*753d2d2eSraf
679*753d2d2eSraf if ((*s == *name) && (strcmp(s, name) == 0))
680*753d2d2eSraf return (&keytbl[i]);
681*753d2d2eSraf }
682*753d2d2eSraf
683*753d2d2eSraf return (NULL);
684*753d2d2eSraf }
685*753d2d2eSraf
686*753d2d2eSraf /*
687*753d2d2eSraf * lookup_sttpair - Given an stt_t return a string or NULL.
688*753d2d2eSraf *
689*753d2d2eSraf */
690*753d2d2eSraf
691*753d2d2eSraf static const char *
lookup_sttpair(stt_t s)692*753d2d2eSraf lookup_sttpair(stt_t s) {
693*753d2d2eSraf /* valid type specifier combinations */
694*753d2d2eSraf static const sttpair_t stttbl[] = {
695*753d2d2eSraf { TS_VOID, "void" },
696*753d2d2eSraf { TS_CHAR, "char" },
697*753d2d2eSraf { TS_SIGNED | TS_CHAR, "signed char" },
698*753d2d2eSraf { TS_UNSIGNED | TS_CHAR, "unsigned char" },
699*753d2d2eSraf { TS_SHORT, "short" },
700*753d2d2eSraf { TS_SIGNED | TS_SHORT, "signed short" },
701*753d2d2eSraf { TS_SHORT | TS_INT, "short int" },
702*753d2d2eSraf { TS_SIGNED | TS_SHORT | TS_INT,
703*753d2d2eSraf "signed short int" },
704*753d2d2eSraf { TS_UNSIGNED | TS_SHORT,
705*753d2d2eSraf "unsigned short" },
706*753d2d2eSraf { TS_UNSIGNED | TS_SHORT | TS_INT,
707*753d2d2eSraf "unsigned short int" },
708*753d2d2eSraf { TS_INT, "int" },
709*753d2d2eSraf { TS_SIGNED, "signed" },
710*753d2d2eSraf { TS_SIGNED | TS_INT, "signed int" },
711*753d2d2eSraf { TS_NO_TS, "" },
712*753d2d2eSraf { TS_UNSIGNED, "unsigned" },
713*753d2d2eSraf { TS_UNSIGNED | TS_INT, "unsigned int" },
714*753d2d2eSraf { TS_LONG, "long" },
715*753d2d2eSraf { TS_SIGNED | TS_LONG, "signed long" },
716*753d2d2eSraf { TS_LONG | TS_INT, "long int" },
717*753d2d2eSraf { TS_SIGNED | TS_LONG | TS_INT,
718*753d2d2eSraf "signed long int" },
719*753d2d2eSraf { TS_UNSIGNED | TS_LONG, "unsigned long" },
720*753d2d2eSraf { TS_UNSIGNED | TS_LONG | TS_INT,
721*753d2d2eSraf "unsigned long int" },
722*753d2d2eSraf { TS_FLOAT, "float" },
723*753d2d2eSraf { TS_DOUBLE, "double" },
724*753d2d2eSraf { TS_LONG | TS_DOUBLE, "long double" },
725*753d2d2eSraf { TS_STRUCT, "struct" },
726*753d2d2eSraf { TS_UNION, "union" },
727*753d2d2eSraf { TS_ENUM, "enum" },
728*753d2d2eSraf { TS_TYPEDEF, "" },
729*753d2d2eSraf /* non-ANSI type: long long */
730*753d2d2eSraf { TS_LONGLONG, "long long" },
731*753d2d2eSraf { TS_LONGLONG | TS_INT, "long long int" },
732*753d2d2eSraf { TS_SIGNED | TS_LONGLONG,
733*753d2d2eSraf "signed long long" },
734*753d2d2eSraf { TS_UNSIGNED | TS_LONGLONG,
735*753d2d2eSraf "unsigned long long" },
736*753d2d2eSraf { TS_SIGNED | TS_LONGLONG | TS_INT,
737*753d2d2eSraf "signed long long int" },
738*753d2d2eSraf { TS_UNSIGNED | TS_LONGLONG | TS_INT,
739*753d2d2eSraf "unsigned long long int" },
740*753d2d2eSraf };
741*753d2d2eSraf
742*753d2d2eSraf #define NDECLSPEC (sizeof (stttbl)/sizeof (sttpair_t))
743*753d2d2eSraf
744*753d2d2eSraf int i;
745*753d2d2eSraf
746*753d2d2eSraf for (i = 0; i < NDECLSPEC; ++i)
747*753d2d2eSraf if (s == stttbl[i].s_stt)
748*753d2d2eSraf return (stttbl[i].s_str);
749*753d2d2eSraf
750*753d2d2eSraf return (NULL);
751*753d2d2eSraf }
752*753d2d2eSraf
753*753d2d2eSraf /*
754*753d2d2eSraf * yylex - return next token from the the input stream.
755*753d2d2eSraf *
756*753d2d2eSraf * The lexical analyzer does not recognize all possible C lexical
757*753d2d2eSraf * elements. It only recognizes those associated with function
758*753d2d2eSraf * declarations (read: prototypes) and data definitions.
759*753d2d2eSraf */
760*753d2d2eSraf
761*753d2d2eSraf static int
yylex(void)762*753d2d2eSraf yylex(void) {
763*753d2d2eSraf char buf[BUFSIZ]; /* string version of token */
764*753d2d2eSraf int c;
765*753d2d2eSraf int i = 0;
766*753d2d2eSraf
767*753d2d2eSraf restart:
768*753d2d2eSraf skipwhitespace();
769*753d2d2eSraf
770*753d2d2eSraf switch (c = getch()) {
771*753d2d2eSraf case '/':
772*753d2d2eSraf if (lookahead('*')) {
773*753d2d2eSraf skipcomment();
774*753d2d2eSraf goto restart;
775*753d2d2eSraf }
776*753d2d2eSraf
777*753d2d2eSraf case '.':
778*753d2d2eSraf if (lookahead('.')) {
779*753d2d2eSraf if (lookahead('.'))
780*753d2d2eSraf return (ELLIPSIS);
781*753d2d2eSraf }
782*753d2d2eSraf
783*753d2d2eSraf case EOF:
784*753d2d2eSraf case '(':
785*753d2d2eSraf case ')':
786*753d2d2eSraf case ',':
787*753d2d2eSraf case '[':
788*753d2d2eSraf case ']':
789*753d2d2eSraf case ';':
790*753d2d2eSraf case '*':
791*753d2d2eSraf return (c);
792*753d2d2eSraf
793*753d2d2eSraf default:
794*753d2d2eSraf if ((c == '_') || isalpha(c)) {
795*753d2d2eSraf const keyword_t *kp;
796*753d2d2eSraf
797*753d2d2eSraf do {
798*753d2d2eSraf buf[i++] = c;
799*753d2d2eSraf c = getch();
800*753d2d2eSraf } while ((c == '_') || isalnum(c));
801*753d2d2eSraf
802*753d2d2eSraf ungetch(c);
803*753d2d2eSraf
804*753d2d2eSraf buf[i] = '\0';
805*753d2d2eSraf
806*753d2d2eSraf if ((kp = lookup_keyword(buf)) != NULL) {
807*753d2d2eSraf yylval.stt_val = kp->stt;
808*753d2d2eSraf return (kp->token);
809*753d2d2eSraf } else {
810*753d2d2eSraf yylval.s_val = strdup(buf);
811*753d2d2eSraf
812*753d2d2eSraf return ((atIDENT) ? IDENTIFIER : TYPEDEF_NAME);
813*753d2d2eSraf }
814*753d2d2eSraf } else if (isdigit(c)) {
815*753d2d2eSraf do {
816*753d2d2eSraf buf[i++] = c;
817*753d2d2eSraf } while (isdigit(c = getch()));
818*753d2d2eSraf
819*753d2d2eSraf ungetch(c);
820*753d2d2eSraf
821*753d2d2eSraf buf[i] = '\0';
822*753d2d2eSraf yylval.s_val = strdup(buf);
823*753d2d2eSraf
824*753d2d2eSraf return (INTEGER);
825*753d2d2eSraf } else
826*753d2d2eSraf return (c);
827*753d2d2eSraf }
828*753d2d2eSraf /* NOTREACHED */
829*753d2d2eSraf }
830*753d2d2eSraf
831*753d2d2eSraf /* getch - return the next character from the input stream. */
832*753d2d2eSraf
833*753d2d2eSraf static int
getch(void)834*753d2d2eSraf getch(void) {
835*753d2d2eSraf int c;
836*753d2d2eSraf
837*753d2d2eSraf if ((c = *input) == '\0')
838*753d2d2eSraf c = EOF;
839*753d2d2eSraf else /* only advance on non-NULL */
840*753d2d2eSraf input++;
841*753d2d2eSraf
842*753d2d2eSraf return (c);
843*753d2d2eSraf }
844*753d2d2eSraf
845*753d2d2eSraf /* ungetch - return a character to the input stream. */
846*753d2d2eSraf
847*753d2d2eSraf static void
ungetch(int c)848*753d2d2eSraf ungetch(int c) {
849*753d2d2eSraf *(--input) = c;
850*753d2d2eSraf }
851*753d2d2eSraf
852*753d2d2eSraf /* skipwhitespace - skip over whitespace in the input stream. */
853*753d2d2eSraf
854*753d2d2eSraf static void
skipwhitespace(void)855*753d2d2eSraf skipwhitespace(void) {
856*753d2d2eSraf int c;
857*753d2d2eSraf
858*753d2d2eSraf while (isspace(c = getch()))
859*753d2d2eSraf ;
860*753d2d2eSraf
861*753d2d2eSraf ungetch(c);
862*753d2d2eSraf }
863*753d2d2eSraf
864*753d2d2eSraf /* skipcomment - scan ahead to the next end of comment. */
865*753d2d2eSraf
866*753d2d2eSraf static void
skipcomment(void)867*753d2d2eSraf skipcomment(void) {
868*753d2d2eSraf loop {
869*753d2d2eSraf int c;
870*753d2d2eSraf
871*753d2d2eSraf switch (c = getch()) {
872*753d2d2eSraf case EOF:
873*753d2d2eSraf return;
874*753d2d2eSraf
875*753d2d2eSraf case '*':
876*753d2d2eSraf if (lookahead('/'))
877*753d2d2eSraf return;
878*753d2d2eSraf }
879*753d2d2eSraf }
880*753d2d2eSraf /* NOTREACHED */
881*753d2d2eSraf }
882*753d2d2eSraf
883*753d2d2eSraf /* lookahead - does next character match 'c'? */
884*753d2d2eSraf
885*753d2d2eSraf static int
lookahead(int c)886*753d2d2eSraf lookahead(int c) {
887*753d2d2eSraf int ch = getch();
888*753d2d2eSraf int match;
889*753d2d2eSraf
890*753d2d2eSraf if (!(match = (ch == c)))
891*753d2d2eSraf ungetch(ch);
892*753d2d2eSraf
893*753d2d2eSraf return (match);
894*753d2d2eSraf }
895*753d2d2eSraf
896*753d2d2eSraf /* putNtabs - write N '\t' to standard output. */
897*753d2d2eSraf
898*753d2d2eSraf #if defined(DEBUG)
899*753d2d2eSraf
900*753d2d2eSraf static void
putNTabs(int n)901*753d2d2eSraf putNTabs(int n) {
902*753d2d2eSraf int i;
903*753d2d2eSraf
904*753d2d2eSraf for (i = 0; i < n; ++i)
905*753d2d2eSraf putchar('\t');
906*753d2d2eSraf }
907*753d2d2eSraf #endif /* DEBUG */
908*753d2d2eSraf
909*753d2d2eSraf /* D E C L A R A T I O N S P E C I F I E R S */
910*753d2d2eSraf
911*753d2d2eSraf /*
912*753d2d2eSraf * Declaration specifiers encode storage class, type specifier and type
913*753d2d2eSraf * qualifier information. This includes any identifiers associated with
914*753d2d2eSraf * struct, union or enum declarations. Typedef names are also encoded
915*753d2d2eSraf * in declaration specifiers.
916*753d2d2eSraf */
917*753d2d2eSraf
918*753d2d2eSraf /* declspec_Construct - allocate and initialize a declspec_t. */
919*753d2d2eSraf
920*753d2d2eSraf static decl_spec_t *
declspec_Construct(void)921*753d2d2eSraf declspec_Construct(void) {
922*753d2d2eSraf decl_spec_t *dsp = malloc(sizeof (decl_spec_t));
923*753d2d2eSraf
924*753d2d2eSraf assert(dsp != NULL);
925*753d2d2eSraf dsp->ds_stt = SCS_NONE | TS_NO_TS | TQ_NONE;
926*753d2d2eSraf dsp->ds_id = NULL;
927*753d2d2eSraf #if defined(MEM_DEBUG)
928*753d2d2eSraf ++declspec_Construct_calls;
929*753d2d2eSraf #endif
930*753d2d2eSraf return (dsp);
931*753d2d2eSraf }
932*753d2d2eSraf
933*753d2d2eSraf /* declspec_Destroy - free a declspec_t. */
934*753d2d2eSraf
935*753d2d2eSraf static void
declspec_Destroy(decl_spec_t * dsp)936*753d2d2eSraf declspec_Destroy(decl_spec_t *dsp) {
937*753d2d2eSraf free(dsp->ds_id);
938*753d2d2eSraf free(dsp);
939*753d2d2eSraf #if defined(MEM_DEBUG)
940*753d2d2eSraf --declspec_Construct_calls;
941*753d2d2eSraf #endif
942*753d2d2eSraf }
943*753d2d2eSraf
944*753d2d2eSraf /*
945*753d2d2eSraf * declspec_Init - allocate and initialize a declspec_t given an
946*753d2d2eSraf * stt_t and identifier.
947*753d2d2eSraf *
948*753d2d2eSraf * Note:
949*753d2d2eSraf * 1) identifier can be NULL.
950*753d2d2eSraf * 2) errors resulting in the stt_t and identifier are ignored.
951*753d2d2eSraf */
952*753d2d2eSraf
953*753d2d2eSraf static decl_spec_t *
declspec_Init(stt_t s,char * tagp)954*753d2d2eSraf declspec_Init(stt_t s, char *tagp) {
955*753d2d2eSraf const char *p;
956*753d2d2eSraf decl_spec_t *dsp = declspec_Construct();
957*753d2d2eSraf decl_spec_t tmp;
958*753d2d2eSraf
959*753d2d2eSraf tmp.ds_stt = s;
960*753d2d2eSraf tmp.ds_id = tagp;
961*753d2d2eSraf
962*753d2d2eSraf declspec_AddDS(dsp, &tmp, &p); /* XXX ignore any error */
963*753d2d2eSraf
964*753d2d2eSraf return (dsp);
965*753d2d2eSraf }
966*753d2d2eSraf
967*753d2d2eSraf /*
968*753d2d2eSraf * declspec_VerifySTT - verify that the two given stt_t can be combined.
969*753d2d2eSraf *
970*753d2d2eSraf * Note:
971*753d2d2eSraf * 1) The return value is a const char *, non-NULL to indicate an error.
972*753d2d2eSraf */
973*753d2d2eSraf
974*753d2d2eSraf static char *
declspec_VerifySTT(stt_t s1,stt_t s2)975*753d2d2eSraf declspec_VerifySTT(stt_t s1, stt_t s2) {
976*753d2d2eSraf stt_t result;
977*753d2d2eSraf
978*753d2d2eSraf if ((s1 | s2) != (s1 ^ s2))
979*753d2d2eSraf return ("attempt to add declaration specifier "
980*753d2d2eSraf "that is already present");
981*753d2d2eSraf
982*753d2d2eSraf result = (s1 | s2) & TS_MASK;
983*753d2d2eSraf
984*753d2d2eSraf if (lookup_sttpair(result) == NULL) {
985*753d2d2eSraf if (STT_isbasic(result) && STT_isderived(result))
986*753d2d2eSraf return ("attempt to combine basic and "
987*753d2d2eSraf "derived types");
988*753d2d2eSraf
989*753d2d2eSraf if (STT_isvoid(result) &&
990*753d2d2eSraf (STT_isbasic(result) || STT_isderived(result)))
991*753d2d2eSraf return ("attempt to combine void with "
992*753d2d2eSraf "other type specifiers");
993*753d2d2eSraf
994*753d2d2eSraf if (STT_isfloat(result) && STT_isint(result))
995*753d2d2eSraf return ("attempt to combine floating and "
996*753d2d2eSraf "integer type specifiers");
997*753d2d2eSraf
998*753d2d2eSraf if (STT_ischar(result) && STT_isint(result))
999*753d2d2eSraf return ("attempt to combine character and "
1000*753d2d2eSraf "integer type specifiers");
1001*753d2d2eSraf
1002*753d2d2eSraf if (STT_has_explicit_sign(result) &&
1003*753d2d2eSraf (STT_isfloat(result) || STT_isderived(result)))
1004*753d2d2eSraf return ("attempt to combine signed or "
1005*753d2d2eSraf "unsigned with float or derived type");
1006*753d2d2eSraf
1007*753d2d2eSraf return ("invalid declaration specifier");
1008*753d2d2eSraf }
1009*753d2d2eSraf
1010*753d2d2eSraf return (NULL);
1011*753d2d2eSraf }
1012*753d2d2eSraf
1013*753d2d2eSraf /*
1014*753d2d2eSraf * declspec_AddSTT - add an stt_t to a decl_spec_t.
1015*753d2d2eSraf *
1016*753d2d2eSraf * Note:
1017*753d2d2eSraf * 1) The "long long" type is handled here.
1018*753d2d2eSraf * If both stt_t include TS_LONG then this is an attempt to use
1019*753d2d2eSraf * "long long". The TS_LONG is cleared from the s1 and s2 and
1020*753d2d2eSraf * then TS_LONGLONG is added to s2. The resulting s1 and s2 are
1021*753d2d2eSraf * passed to declspec_VerifySTT to determine if the result is valid.
1022*753d2d2eSraf *
1023*753d2d2eSraf * 2) This method of handling "long long" does detect the case of
1024*753d2d2eSraf * "long double long" and all it's variant forms.
1025*753d2d2eSraf */
1026*753d2d2eSraf
1027*753d2d2eSraf static decl_spec_t *
declspec_AddSTT(decl_spec_t * dsp,stt_t s2,const char ** err)1028*753d2d2eSraf declspec_AddSTT(decl_spec_t *dsp, stt_t s2, const char **err) {
1029*753d2d2eSraf stt_t s1 = dsp->ds_stt;
1030*753d2d2eSraf
1031*753d2d2eSraf /* non-ANSI type: long long */
1032*753d2d2eSraf if ((s1 & TS_LONG) && (s2 & TS_LONG)) {
1033*753d2d2eSraf s1 &= ~(TS_LONG);
1034*753d2d2eSraf dsp->ds_stt = s1;
1035*753d2d2eSraf s2 &= ~(TS_LONG);
1036*753d2d2eSraf s2 |= TS_LONGLONG;
1037*753d2d2eSraf }
1038*753d2d2eSraf
1039*753d2d2eSraf if ((*err = declspec_VerifySTT(s1, s2)) == NULL)
1040*753d2d2eSraf dsp->ds_stt |= s2;
1041*753d2d2eSraf
1042*753d2d2eSraf return (dsp);
1043*753d2d2eSraf }
1044*753d2d2eSraf
1045*753d2d2eSraf /*
1046*753d2d2eSraf * declpec_AddDS - add a decl_spec_t to an existing decl_spec_t.
1047*753d2d2eSraf */
1048*753d2d2eSraf
1049*753d2d2eSraf static decl_spec_t *
declspec_AddDS(decl_spec_t * dsp,decl_spec_t * tsp,const char ** err)1050*753d2d2eSraf declspec_AddDS(decl_spec_t *dsp, decl_spec_t *tsp, const char **err) {
1051*753d2d2eSraf declspec_AddSTT(dsp, tsp->ds_stt, err);
1052*753d2d2eSraf
1053*753d2d2eSraf if ((*err == NULL) && tsp->ds_id) {
1054*753d2d2eSraf free(dsp->ds_id);
1055*753d2d2eSraf dsp->ds_id = strdup(tsp->ds_id);
1056*753d2d2eSraf
1057*753d2d2eSraf assert(dsp->ds_id != NULL);
1058*753d2d2eSraf }
1059*753d2d2eSraf
1060*753d2d2eSraf return (dsp);
1061*753d2d2eSraf }
1062*753d2d2eSraf
1063*753d2d2eSraf /*
1064*753d2d2eSraf * declspec_GetSTT - return the stt_t within a decl_spec_t.
1065*753d2d2eSraf */
1066*753d2d2eSraf
1067*753d2d2eSraf static stt_t
declspec_GetSTT(decl_spec_t * dsp)1068*753d2d2eSraf declspec_GetSTT(decl_spec_t *dsp) {
1069*753d2d2eSraf return (dsp->ds_stt);
1070*753d2d2eSraf }
1071*753d2d2eSraf
1072*753d2d2eSraf /*
1073*753d2d2eSraf * declspec_GetTag - return the identifier within a decl_spec_t.
1074*753d2d2eSraf */
1075*753d2d2eSraf
1076*753d2d2eSraf static char *
declspec_GetTag(decl_spec_t * dsp)1077*753d2d2eSraf declspec_GetTag(decl_spec_t *dsp) {
1078*753d2d2eSraf return (dsp->ds_id);
1079*753d2d2eSraf }
1080*753d2d2eSraf
1081*753d2d2eSraf /*
1082*753d2d2eSraf * declspec_ToString - convert a decl_spec_t into a string.
1083*753d2d2eSraf *
1084*753d2d2eSraf * Note:
1085*753d2d2eSraf * 1) The form of the resulting string is always the same, i.e.
1086*753d2d2eSraf *
1087*753d2d2eSraf * [register] [type_specifier] [const] [volatile]
1088*753d2d2eSraf *
1089*753d2d2eSraf * dsp must be correct
1090*753d2d2eSraf *
1091*753d2d2eSraf */
1092*753d2d2eSraf
1093*753d2d2eSraf char *
declspec_ToString(char * bufp,decl_spec_t * dsp)1094*753d2d2eSraf declspec_ToString(char *bufp, decl_spec_t *dsp) {
1095*753d2d2eSraf const char *s;
1096*753d2d2eSraf int something = 0;
1097*753d2d2eSraf
1098*753d2d2eSraf *bufp = '\0';
1099*753d2d2eSraf
1100*753d2d2eSraf /* storage class specifier */
1101*753d2d2eSraf switch (dsp->ds_stt & SCS_MASK) {
1102*753d2d2eSraf case SCS_REGISTER:
1103*753d2d2eSraf strcat(bufp, "register");
1104*753d2d2eSraf something = 1;
1105*753d2d2eSraf break;
1106*753d2d2eSraf }
1107*753d2d2eSraf
1108*753d2d2eSraf s = lookup_sttpair(dsp->ds_stt & TS_MASK);
1109*753d2d2eSraf
1110*753d2d2eSraf /* type specifier */
1111*753d2d2eSraf switch (dsp->ds_stt & TS_MASK) {
1112*753d2d2eSraf case TS_STRUCT:
1113*753d2d2eSraf case TS_UNION:
1114*753d2d2eSraf case TS_ENUM:
1115*753d2d2eSraf if (something)
1116*753d2d2eSraf strcat(bufp, " ");
1117*753d2d2eSraf
1118*753d2d2eSraf strcat(bufp, s);
1119*753d2d2eSraf strcat(bufp, " ");
1120*753d2d2eSraf strcat(bufp, dsp->ds_id);
1121*753d2d2eSraf break;
1122*753d2d2eSraf
1123*753d2d2eSraf case TS_TYPEDEF:
1124*753d2d2eSraf if (something)
1125*753d2d2eSraf strcat(bufp, " ");
1126*753d2d2eSraf
1127*753d2d2eSraf strcat(bufp, dsp->ds_id);
1128*753d2d2eSraf break;
1129*753d2d2eSraf
1130*753d2d2eSraf default:
1131*753d2d2eSraf if (something)
1132*753d2d2eSraf strcat(bufp, " ");
1133*753d2d2eSraf
1134*753d2d2eSraf strcat(bufp, s);
1135*753d2d2eSraf break;
1136*753d2d2eSraf }
1137*753d2d2eSraf
1138*753d2d2eSraf if (s)
1139*753d2d2eSraf something = 1;
1140*753d2d2eSraf
1141*753d2d2eSraf if (something && (dsp->ds_stt & TQ_MASK))
1142*753d2d2eSraf strcat(bufp, " ");
1143*753d2d2eSraf
1144*753d2d2eSraf if (dsp->ds_stt & TQ_CONST) /* type qualifier */
1145*753d2d2eSraf strcat(bufp, "const");
1146*753d2d2eSraf
1147*753d2d2eSraf if (dsp->ds_stt & TQ_VOLATILE) {
1148*753d2d2eSraf if (dsp->ds_stt & TQ_CONST)
1149*753d2d2eSraf strcat(bufp, " ");
1150*753d2d2eSraf
1151*753d2d2eSraf strcat(bufp, "volatile");
1152*753d2d2eSraf }
1153*753d2d2eSraf
1154*753d2d2eSraf /*
1155*753d2d2eSraf * It currently acknowledges and ignores restrict or _RESTRICT_KYWD
1156*753d2d2eSraf * in code generation because of the uncertain behavior of "restrict".
1157*753d2d2eSraf */
1158*753d2d2eSraf if (dsp->ds_stt & TQ_RESTRICT)
1159*753d2d2eSraf strcat(bufp, "");
1160*753d2d2eSraf
1161*753d2d2eSraf if (dsp->ds_stt & TQ_RESTRICT_KYWD)
1162*753d2d2eSraf strcat(bufp, "");
1163*753d2d2eSraf
1164*753d2d2eSraf return (bufp);
1165*753d2d2eSraf }
1166*753d2d2eSraf
1167*753d2d2eSraf /* T Y P E M O D I F I E R S */
1168*753d2d2eSraf
1169*753d2d2eSraf /*
1170*753d2d2eSraf * Type modifiers encode the "array of...", "pointer to ..." and
1171*753d2d2eSraf * "function returning ..." aspects of C types. The modifiers are kept
1172*753d2d2eSraf * as a linked list in precedence order. The grammar encodes the
1173*753d2d2eSraf * precedence order described by the standard.
1174*753d2d2eSraf *
1175*753d2d2eSraf * Type modifiers are always added at the end of list and the list is
1176*753d2d2eSraf * always traversed from head to tail.
1177*753d2d2eSraf */
1178*753d2d2eSraf
1179*753d2d2eSraf /* type_Construct - allocate and initialize a type_t. */
1180*753d2d2eSraf
1181*753d2d2eSraf static type_t *
type_Construct(void)1182*753d2d2eSraf type_Construct(void) {
1183*753d2d2eSraf type_t *tp = malloc(sizeof (type_t));
1184*753d2d2eSraf
1185*753d2d2eSraf assert(tp != NULL);
1186*753d2d2eSraf
1187*753d2d2eSraf tp->t_next = NULL; /* generic */
1188*753d2d2eSraf tp->t_dt = DD_NONE;
1189*753d2d2eSraf
1190*753d2d2eSraf tp->t_nargs = 0; /* DD_FUN */
1191*753d2d2eSraf tp->t_ellipsis = 0;
1192*753d2d2eSraf tp->t_args = NULL;
1193*753d2d2eSraf /* DD_PTR */
1194*753d2d2eSraf tp->t_stt = (SCS_NONE | TS_NO_TS | TQ_NONE);
1195*753d2d2eSraf
1196*753d2d2eSraf tp->t_sizestr = NULL; /* DD_ARY */
1197*753d2d2eSraf #if defined(MEM_DEBUG)
1198*753d2d2eSraf ++type_Construct_calls;
1199*753d2d2eSraf #endif
1200*753d2d2eSraf return (tp);
1201*753d2d2eSraf }
1202*753d2d2eSraf
1203*753d2d2eSraf /* type_Destroy - free a type_t list. */
1204*753d2d2eSraf
1205*753d2d2eSraf static void
type_Destroy(type_t * tp)1206*753d2d2eSraf type_Destroy(type_t *tp) {
1207*753d2d2eSraf while (tp) {
1208*753d2d2eSraf type_t *nextp = tp->t_next;
1209*753d2d2eSraf
1210*753d2d2eSraf switch (tp->t_dt) {
1211*753d2d2eSraf case DD_FUN:
1212*753d2d2eSraf decl_Destroy(tp->t_args);
1213*753d2d2eSraf break;
1214*753d2d2eSraf
1215*753d2d2eSraf case DD_PTR:
1216*753d2d2eSraf break;
1217*753d2d2eSraf
1218*753d2d2eSraf case DD_ARY:
1219*753d2d2eSraf free(tp->t_sizestr);
1220*753d2d2eSraf break;
1221*753d2d2eSraf }
1222*753d2d2eSraf
1223*753d2d2eSraf free(tp);
1224*753d2d2eSraf
1225*753d2d2eSraf tp = nextp;
1226*753d2d2eSraf #if defined(MEM_DEBUG)
1227*753d2d2eSraf --type_Construct_calls;
1228*753d2d2eSraf #endif
1229*753d2d2eSraf }
1230*753d2d2eSraf }
1231*753d2d2eSraf
1232*753d2d2eSraf /*
1233*753d2d2eSraf * type_SetPtr - make a type_t into a "pointer to ..." variant.
1234*753d2d2eSraf *
1235*753d2d2eSraf * Note:
1236*753d2d2eSraf * 1) The stt_t will encode any type qualifiers (const, volatile).
1237*753d2d2eSraf */
1238*753d2d2eSraf
1239*753d2d2eSraf static type_t *
type_SetPtr(type_t * tp,stt_t s)1240*753d2d2eSraf type_SetPtr(type_t *tp, stt_t s) {
1241*753d2d2eSraf assert(tp->t_dt == DD_NONE);
1242*753d2d2eSraf
1243*753d2d2eSraf tp->t_dt = DD_PTR;
1244*753d2d2eSraf tp->t_stt = s & TQ_MASK;
1245*753d2d2eSraf
1246*753d2d2eSraf return (tp);
1247*753d2d2eSraf }
1248*753d2d2eSraf
1249*753d2d2eSraf /*
1250*753d2d2eSraf * type_SetAry - make a type_t into an "array of ...", variant.
1251*753d2d2eSraf *
1252*753d2d2eSraf * Note:
1253*753d2d2eSraf * 1) The array dimension can be NULL to indicate undefined, i.e. [].
1254*753d2d2eSraf */
1255*753d2d2eSraf
1256*753d2d2eSraf static type_t *
type_SetAry(type_t * tp,char * dim)1257*753d2d2eSraf type_SetAry(type_t *tp, char *dim) {
1258*753d2d2eSraf assert(tp->t_dt == DD_NONE);
1259*753d2d2eSraf assert(tp->t_sizestr == NULL);
1260*753d2d2eSraf
1261*753d2d2eSraf tp->t_dt = DD_ARY;
1262*753d2d2eSraf
1263*753d2d2eSraf if (dim) {
1264*753d2d2eSraf tp->t_sizestr = strdup(dim);
1265*753d2d2eSraf assert(tp->t_sizestr != NULL);
1266*753d2d2eSraf } else
1267*753d2d2eSraf tp->t_sizestr = NULL;
1268*753d2d2eSraf
1269*753d2d2eSraf return (tp);
1270*753d2d2eSraf }
1271*753d2d2eSraf
1272*753d2d2eSraf /*
1273*753d2d2eSraf * type_SetFun - make a type_t into a "function returning ..." variant.
1274*753d2d2eSraf *
1275*753d2d2eSraf * Note:
1276*753d2d2eSraf * 1) The argument list can be NULL to indicate undefined, i.e. ().
1277*753d2d2eSraf */
1278*753d2d2eSraf
1279*753d2d2eSraf static type_t *
type_SetFun(type_t * tp,decl_t * arglist)1280*753d2d2eSraf type_SetFun(type_t *tp, decl_t *arglist) {
1281*753d2d2eSraf assert(tp->t_dt == DD_NONE);
1282*753d2d2eSraf
1283*753d2d2eSraf tp->t_dt = DD_FUN;
1284*753d2d2eSraf
1285*753d2d2eSraf if (arglist) {
1286*753d2d2eSraf tp->t_nargs = decl_GetArgLength(arglist);
1287*753d2d2eSraf tp->t_args = arglist;
1288*753d2d2eSraf tp->t_ellipsis = arglist->d_ellipsis;
1289*753d2d2eSraf }
1290*753d2d2eSraf
1291*753d2d2eSraf return (tp);
1292*753d2d2eSraf }
1293*753d2d2eSraf
1294*753d2d2eSraf /*
1295*753d2d2eSraf * type_AddTail - add a type_t to the end of an existing type_t list.
1296*753d2d2eSraf *
1297*753d2d2eSraf * Note:
1298*753d2d2eSraf * 1) The type_t *tp is added to the end of the type_t *dp list.
1299*753d2d2eSraf */
1300*753d2d2eSraf
1301*753d2d2eSraf static type_t *
type_AddTail(type_t * dp,type_t * tp)1302*753d2d2eSraf type_AddTail(type_t *dp, type_t *tp) {
1303*753d2d2eSraf type_t *lastp = dp;
1304*753d2d2eSraf type_t *p;
1305*753d2d2eSraf
1306*753d2d2eSraf while (p = lastp->t_next)
1307*753d2d2eSraf lastp = p;
1308*753d2d2eSraf
1309*753d2d2eSraf lastp->t_next = tp;
1310*753d2d2eSraf
1311*753d2d2eSraf return (dp);
1312*753d2d2eSraf }
1313*753d2d2eSraf
1314*753d2d2eSraf #if defined(DEBUG)
1315*753d2d2eSraf
1316*753d2d2eSraf /* type_PrintType - print a type_t list onto standard output. */
1317*753d2d2eSraf
1318*753d2d2eSraf static void
type_PrintType(type_t * tp,int lvl)1319*753d2d2eSraf type_PrintType(type_t *tp, int lvl) {
1320*753d2d2eSraf decl_spec_t tmp;
1321*753d2d2eSraf char buf[BUFSIZ];
1322*753d2d2eSraf
1323*753d2d2eSraf while (tp) {
1324*753d2d2eSraf putNTabs(lvl);
1325*753d2d2eSraf
1326*753d2d2eSraf switch (tp->t_dt) {
1327*753d2d2eSraf case DD_PTR:
1328*753d2d2eSraf tmp.ds_stt = tp->t_stt;
1329*753d2d2eSraf tmp.ds_id = NULL;
1330*753d2d2eSraf
1331*753d2d2eSraf printf("[%s] ptr to\n", declspec_ToString(buf, &tmp));
1332*753d2d2eSraf break;
1333*753d2d2eSraf
1334*753d2d2eSraf case DD_FUN:
1335*753d2d2eSraf printf("fun [%d%c] %s\n",
1336*753d2d2eSraf tp->t_nargs,
1337*753d2d2eSraf (tp->t_ellipsis)? '+' : '=',
1338*753d2d2eSraf (tp->t_args)? "with arguments" :
1339*753d2d2eSraf "undefined arguments");
1340*753d2d2eSraf
1341*753d2d2eSraf if (tp->t_args) {
1342*753d2d2eSraf decl_PrintDecl(tp->t_args, lvl + 1);
1343*753d2d2eSraf
1344*753d2d2eSraf if (tp->t_ellipsis) {
1345*753d2d2eSraf putNTabs(lvl + 1);
1346*753d2d2eSraf printf("...\n");
1347*753d2d2eSraf }
1348*753d2d2eSraf }
1349*753d2d2eSraf break;
1350*753d2d2eSraf
1351*753d2d2eSraf case DD_ARY:
1352*753d2d2eSraf printf("ary [%s] of\n",
1353*753d2d2eSraf (tp->t_sizestr)? tp->t_sizestr : "");
1354*753d2d2eSraf break;
1355*753d2d2eSraf }
1356*753d2d2eSraf
1357*753d2d2eSraf tp = tp->t_next;
1358*753d2d2eSraf }
1359*753d2d2eSraf }
1360*753d2d2eSraf #endif /* DEBUG */
1361*753d2d2eSraf
1362*753d2d2eSraf /*
1363*753d2d2eSraf * type_Verify - verify a type_t list for semantic correctness.
1364*753d2d2eSraf *
1365*753d2d2eSraf * Note:
1366*753d2d2eSraf * 1) C supports most combinations of type modifiers.
1367*753d2d2eSraf * It does not support three combinations, they are:
1368*753d2d2eSraf *
1369*753d2d2eSraf * function returning array
1370*753d2d2eSraf * array of functions
1371*753d2d2eSraf * function returning function
1372*753d2d2eSraf *
1373*753d2d2eSraf * 2) The enum values associated with type modifiers (i.e. DD_*)
1374*753d2d2eSraf * cannot be modified without changing the table included within the
1375*753d2d2eSraf * function.
1376*753d2d2eSraf *
1377*753d2d2eSraf * 3) The function returns NULL to indicate that the type modifier
1378*753d2d2eSraf * list is valid and non-NULL to indicate an error.
1379*753d2d2eSraf *
1380*753d2d2eSraf * 4) A type_t of NULL is permitted to indicate an empty type_t list.
1381*753d2d2eSraf */
1382*753d2d2eSraf
1383*753d2d2eSraf static const char *
type_Verify(type_t * tp)1384*753d2d2eSraf type_Verify(type_t *tp) {
1385*753d2d2eSraf static const char *dttbl[4][4] = {
1386*753d2d2eSraf /* NONE ARY FUN PTR */
1387*753d2d2eSraf /* NONE */ {NULL, NULL, NULL, NULL},
1388*753d2d2eSraf /* ARY */ {NULL, NULL, "array of functions", NULL},
1389*753d2d2eSraf /* FUN */ {NULL, "function returning array",
1390*753d2d2eSraf "function returning function", NULL},
1391*753d2d2eSraf /* PTR */ {NULL, NULL, NULL, NULL},
1392*753d2d2eSraf };
1393*753d2d2eSraf
1394*753d2d2eSraf if (tp) {
1395*753d2d2eSraf type_t *nextp;
1396*753d2d2eSraf
1397*753d2d2eSraf do {
1398*753d2d2eSraf const char *p;
1399*753d2d2eSraf decl_type_t nt;
1400*753d2d2eSraf
1401*753d2d2eSraf nt = (nextp = tp->t_next)? nextp->t_dt : DD_NONE;
1402*753d2d2eSraf
1403*753d2d2eSraf if ((p = dttbl[tp->t_dt][nt]) != NULL)
1404*753d2d2eSraf return (p);
1405*753d2d2eSraf
1406*753d2d2eSraf } while (tp = nextp);
1407*753d2d2eSraf }
1408*753d2d2eSraf
1409*753d2d2eSraf return (NULL);
1410*753d2d2eSraf }
1411*753d2d2eSraf
1412*753d2d2eSraf /* type_GetNext - return the next type_t in the list. */
1413*753d2d2eSraf
1414*753d2d2eSraf type_t *
type_GetNext(type_t * tp)1415*753d2d2eSraf type_GetNext(type_t *tp) {
1416*753d2d2eSraf return (tp->t_next);
1417*753d2d2eSraf }
1418*753d2d2eSraf
1419*753d2d2eSraf /*
1420*753d2d2eSraf * The following group of functions return and or
1421*753d2d2eSraf * test various aspects of type modifiers.
1422*753d2d2eSraf *
1423*753d2d2eSraf * 1) The three functions: type_IsPtrTo, type_IsFunction and
1424*753d2d2eSraf * type_IsArray will accept an argument of NULL.
1425*753d2d2eSraf *
1426*753d2d2eSraf * 2) All other functions require one of the above three to be true.
1427*753d2d2eSraf * Various asserts are in place to verify correct usage.
1428*753d2d2eSraf */
1429*753d2d2eSraf
1430*753d2d2eSraf int
type_IsArray(type_t * tp)1431*753d2d2eSraf type_IsArray(type_t *tp) {
1432*753d2d2eSraf return (tp && (tp->t_dt == DD_ARY));
1433*753d2d2eSraf }
1434*753d2d2eSraf
1435*753d2d2eSraf char *
type_GetArraySize(type_t * tp)1436*753d2d2eSraf type_GetArraySize(type_t *tp) {
1437*753d2d2eSraf assert(tp->t_dt == DD_ARY);
1438*753d2d2eSraf
1439*753d2d2eSraf return (tp->t_sizestr);
1440*753d2d2eSraf }
1441*753d2d2eSraf
1442*753d2d2eSraf int
type_IsPtrTo(type_t * tp)1443*753d2d2eSraf type_IsPtrTo(type_t *tp) {
1444*753d2d2eSraf return (tp && (tp->t_dt == DD_PTR));
1445*753d2d2eSraf }
1446*753d2d2eSraf
1447*753d2d2eSraf stt_t
type_GetPtrToTypeQual(type_t * tp)1448*753d2d2eSraf type_GetPtrToTypeQual(type_t *tp) {
1449*753d2d2eSraf assert(tp->t_dt == DD_PTR);
1450*753d2d2eSraf
1451*753d2d2eSraf return (tp->t_stt);
1452*753d2d2eSraf }
1453*753d2d2eSraf
1454*753d2d2eSraf int
type_IsFunction(type_t * tp)1455*753d2d2eSraf type_IsFunction(type_t *tp) {
1456*753d2d2eSraf return (tp && (tp->t_dt == DD_FUN));
1457*753d2d2eSraf }
1458*753d2d2eSraf
1459*753d2d2eSraf int
type_GetArgLength(type_t * tp)1460*753d2d2eSraf type_GetArgLength(type_t *tp) {
1461*753d2d2eSraf assert(tp->t_dt == DD_FUN);
1462*753d2d2eSraf
1463*753d2d2eSraf return (tp->t_nargs);
1464*753d2d2eSraf }
1465*753d2d2eSraf
1466*753d2d2eSraf int
type_IsVarargs(type_t * tp)1467*753d2d2eSraf type_IsVarargs(type_t *tp) {
1468*753d2d2eSraf while (tp && tp->t_dt == DD_PTR)
1469*753d2d2eSraf tp = tp->t_next;
1470*753d2d2eSraf
1471*753d2d2eSraf assert(tp->t_dt == DD_FUN);
1472*753d2d2eSraf
1473*753d2d2eSraf return (tp->t_ellipsis);
1474*753d2d2eSraf }
1475*753d2d2eSraf
1476*753d2d2eSraf decl_t *
type_GetArg(type_t * tp)1477*753d2d2eSraf type_GetArg(type_t *tp) {
1478*753d2d2eSraf assert(tp->t_dt == DD_FUN);
1479*753d2d2eSraf
1480*753d2d2eSraf return (tp->t_args);
1481*753d2d2eSraf }
1482*753d2d2eSraf
1483*753d2d2eSraf /*
1484*753d2d2eSraf * type_IsPtrFun - determine if the type_t results in a call-able function.
1485*753d2d2eSraf *
1486*753d2d2eSraf * Note:
1487*753d2d2eSraf * 1) The argument can be NULL.
1488*753d2d2eSraf *
1489*753d2d2eSraf * 2) The test is true if the type_t list is number of DD_PTR followed
1490*753d2d2eSraf * by a DD_FUN.
1491*753d2d2eSraf */
1492*753d2d2eSraf
1493*753d2d2eSraf int
type_IsPtrFun(type_t * tp)1494*753d2d2eSraf type_IsPtrFun(type_t *tp) {
1495*753d2d2eSraf
1496*753d2d2eSraf if (! (tp && (tp->t_dt == DD_PTR)))
1497*753d2d2eSraf return (0);
1498*753d2d2eSraf
1499*753d2d2eSraf tp = tp->t_next;
1500*753d2d2eSraf
1501*753d2d2eSraf while (tp && (tp->t_dt == DD_PTR))
1502*753d2d2eSraf tp = tp->t_next;
1503*753d2d2eSraf
1504*753d2d2eSraf return (tp && (tp->t_dt == DD_FUN));
1505*753d2d2eSraf }
1506*753d2d2eSraf
1507*753d2d2eSraf /* D E C L A R A T O R */
1508*753d2d2eSraf
1509*753d2d2eSraf /*
1510*753d2d2eSraf * A decl_t encodes the name,
1511*753d2d2eSraf * declaration specifiers and type modifiers of an object.
1512*753d2d2eSraf */
1513*753d2d2eSraf
1514*753d2d2eSraf /* decl_Construct - allocate a decl_t. */
1515*753d2d2eSraf
1516*753d2d2eSraf static decl_t *
decl_Construct(void)1517*753d2d2eSraf decl_Construct(void) {
1518*753d2d2eSraf decl_t *dp = malloc(sizeof (decl_t));
1519*753d2d2eSraf
1520*753d2d2eSraf assert(dp != NULL);
1521*753d2d2eSraf
1522*753d2d2eSraf dp->d_name = NULL;
1523*753d2d2eSraf dp->d_type = NULL;
1524*753d2d2eSraf dp->d_next = NULL;
1525*753d2d2eSraf dp->d_ds = declspec_Construct();
1526*753d2d2eSraf dp->d_ellipsis = 0;
1527*753d2d2eSraf #if defined(MEM_DEBUG)
1528*753d2d2eSraf ++decl_Construct_calls;
1529*753d2d2eSraf #endif
1530*753d2d2eSraf return (dp);
1531*753d2d2eSraf }
1532*753d2d2eSraf
1533*753d2d2eSraf /* decl_Destroy - free a decl_t list. */
1534*753d2d2eSraf
1535*753d2d2eSraf void
decl_Destroy(decl_t * dp)1536*753d2d2eSraf decl_Destroy(decl_t *dp) {
1537*753d2d2eSraf while (dp) {
1538*753d2d2eSraf decl_t *nextp = dp->d_next;
1539*753d2d2eSraf
1540*753d2d2eSraf type_Destroy(dp->d_type);
1541*753d2d2eSraf declspec_Destroy(dp->d_ds);
1542*753d2d2eSraf free(dp->d_name);
1543*753d2d2eSraf free(dp);
1544*753d2d2eSraf
1545*753d2d2eSraf dp = nextp;
1546*753d2d2eSraf #if defined(MEM_DEBUG)
1547*753d2d2eSraf --decl_Construct_calls;
1548*753d2d2eSraf #endif
1549*753d2d2eSraf }
1550*753d2d2eSraf }
1551*753d2d2eSraf
1552*753d2d2eSraf /*
1553*753d2d2eSraf * decl_GetArgLength - return the length of a decl_t list.
1554*753d2d2eSraf *
1555*753d2d2eSraf * Note:
1556*753d2d2eSraf * 1) The argument may be NULL to indicate an empty list, len == 0.
1557*753d2d2eSraf */
1558*753d2d2eSraf
1559*753d2d2eSraf int
decl_GetArgLength(decl_t * dp)1560*753d2d2eSraf decl_GetArgLength(decl_t *dp) {
1561*753d2d2eSraf int len;
1562*753d2d2eSraf
1563*753d2d2eSraf for (len = 0; dp; dp = dp->d_next)
1564*753d2d2eSraf ++len;
1565*753d2d2eSraf
1566*753d2d2eSraf return (len);
1567*753d2d2eSraf }
1568*753d2d2eSraf
1569*753d2d2eSraf /*
1570*753d2d2eSraf * The following group of functions get or test various aspects of a decl_t.
1571*753d2d2eSraf */
1572*753d2d2eSraf
1573*753d2d2eSraf decl_t *
decl_GetNext(decl_t * dp)1574*753d2d2eSraf decl_GetNext(decl_t *dp) {
1575*753d2d2eSraf return (dp->d_next);
1576*753d2d2eSraf }
1577*753d2d2eSraf
1578*753d2d2eSraf stt_t
decl_GetDeclSpec(decl_t * dp)1579*753d2d2eSraf decl_GetDeclSpec(decl_t *dp) {
1580*753d2d2eSraf return (declspec_GetSTT(dp->d_ds));
1581*753d2d2eSraf }
1582*753d2d2eSraf
1583*753d2d2eSraf char *
decl_GetDSName(decl_t * dp)1584*753d2d2eSraf decl_GetDSName(decl_t *dp) {
1585*753d2d2eSraf return (declspec_GetTag(dp->d_ds));
1586*753d2d2eSraf }
1587*753d2d2eSraf
1588*753d2d2eSraf type_t *
decl_GetType(decl_t * dp)1589*753d2d2eSraf decl_GetType(decl_t *dp) {
1590*753d2d2eSraf return (dp->d_type);
1591*753d2d2eSraf }
1592*753d2d2eSraf
1593*753d2d2eSraf int
decl_IsVarargs(decl_t * dp)1594*753d2d2eSraf decl_IsVarargs(decl_t *dp) {
1595*753d2d2eSraf return (dp->d_ellipsis);
1596*753d2d2eSraf }
1597*753d2d2eSraf
1598*753d2d2eSraf int
decl_IsFunction(decl_t * dp)1599*753d2d2eSraf decl_IsFunction(decl_t *dp) {
1600*753d2d2eSraf return (type_IsFunction(dp->d_type));
1601*753d2d2eSraf }
1602*753d2d2eSraf
1603*753d2d2eSraf char *
decl_GetName(decl_t * dp)1604*753d2d2eSraf decl_GetName(decl_t *dp) {
1605*753d2d2eSraf return (dp->d_name);
1606*753d2d2eSraf }
1607*753d2d2eSraf
1608*753d2d2eSraf /*
1609*753d2d2eSraf * decl_AddArg - add a decl_t to the end of an decl_t list.
1610*753d2d2eSraf */
1611*753d2d2eSraf
1612*753d2d2eSraf static decl_t *
decl_AddArg(decl_t * dp,decl_t * tp)1613*753d2d2eSraf decl_AddArg(decl_t *dp, decl_t *tp) {
1614*753d2d2eSraf decl_t *lastp = dp;
1615*753d2d2eSraf decl_t *p;
1616*753d2d2eSraf
1617*753d2d2eSraf while (p = lastp->d_next)
1618*753d2d2eSraf lastp = p;
1619*753d2d2eSraf
1620*753d2d2eSraf lastp->d_next = tp;
1621*753d2d2eSraf
1622*753d2d2eSraf return (dp);
1623*753d2d2eSraf }
1624*753d2d2eSraf
1625*753d2d2eSraf /*
1626*753d2d2eSraf * decl_IsVoid - return true if the decl_t is a "pure" void declaration.
1627*753d2d2eSraf */
1628*753d2d2eSraf
1629*753d2d2eSraf static int
decl_IsVoid(decl_t * dp)1630*753d2d2eSraf decl_IsVoid(decl_t *dp) {
1631*753d2d2eSraf return ((declspec_GetSTT(dp->d_ds) & TS_VOID) && (dp->d_type == NULL));
1632*753d2d2eSraf }
1633*753d2d2eSraf
1634*753d2d2eSraf /*
1635*753d2d2eSraf * decl_IsVoidArray - return true if the decl_t includes "void []".
1636*753d2d2eSraf */
1637*753d2d2eSraf
1638*753d2d2eSraf static int
decl_IsVoidArray(decl_t * dp)1639*753d2d2eSraf decl_IsVoidArray(decl_t *dp) {
1640*753d2d2eSraf int retval = 0;
1641*753d2d2eSraf type_t *tp = dp->d_type;
1642*753d2d2eSraf
1643*753d2d2eSraf if (tp) {
1644*753d2d2eSraf type_t *np;
1645*753d2d2eSraf
1646*753d2d2eSraf while (np = type_GetNext(tp))
1647*753d2d2eSraf tp = np;
1648*753d2d2eSraf
1649*753d2d2eSraf retval = type_IsArray(tp) &&
1650*753d2d2eSraf (declspec_GetSTT(dp->d_ds) & TS_VOID);
1651*753d2d2eSraf }
1652*753d2d2eSraf
1653*753d2d2eSraf return (retval);
1654*753d2d2eSraf }
1655*753d2d2eSraf
1656*753d2d2eSraf /*
1657*753d2d2eSraf * decl_Verify - verify a decl_t.
1658*753d2d2eSraf */
1659*753d2d2eSraf
1660*753d2d2eSraf static const char *
decl_Verify(decl_t * dp)1661*753d2d2eSraf decl_Verify(decl_t *dp) {
1662*753d2d2eSraf const char *ep = NULL;
1663*753d2d2eSraf
1664*753d2d2eSraf if (decl_IsVoid(dp))
1665*753d2d2eSraf ep = "type is void";
1666*753d2d2eSraf else if (decl_IsVoidArray(dp))
1667*753d2d2eSraf ep = "type is void []";
1668*753d2d2eSraf else
1669*753d2d2eSraf ep = type_Verify(dp->d_type);
1670*753d2d2eSraf
1671*753d2d2eSraf return (ep);
1672*753d2d2eSraf }
1673*753d2d2eSraf
1674*753d2d2eSraf /*
1675*753d2d2eSraf * decl_VerifyArgs - verify a decl_t list.
1676*753d2d2eSraf */
1677*753d2d2eSraf
1678*753d2d2eSraf static const char *
decl_VerifyArgs(decl_t * dp)1679*753d2d2eSraf decl_VerifyArgs(decl_t *dp) {
1680*753d2d2eSraf decl_t *tp = dp;
1681*753d2d2eSraf const char *ep = NULL;
1682*753d2d2eSraf
1683*753d2d2eSraf if (dp) {
1684*753d2d2eSraf int nv = 0;
1685*753d2d2eSraf int nargs = decl_GetArgLength(dp);
1686*753d2d2eSraf
1687*753d2d2eSraf for (; dp; dp = dp->d_next)
1688*753d2d2eSraf if (decl_IsVoid(dp)) {
1689*753d2d2eSraf ++nv;
1690*753d2d2eSraf
1691*753d2d2eSraf if (decl_GetName(dp))
1692*753d2d2eSraf ep = "argument list includes "
1693*753d2d2eSraf "void with identifier";
1694*753d2d2eSraf } else if (decl_IsVoidArray(dp))
1695*753d2d2eSraf ep = "argument list includes void []";
1696*753d2d2eSraf
1697*753d2d2eSraf if (nv) { /* there was some void */
1698*753d2d2eSraf if (nargs > 1)
1699*753d2d2eSraf ep = "argument list includes void";
1700*753d2d2eSraf
1701*753d2d2eSraf if (tp->d_ellipsis)
1702*753d2d2eSraf ep = "argument list includes void and \"...\"";
1703*753d2d2eSraf }
1704*753d2d2eSraf }
1705*753d2d2eSraf
1706*753d2d2eSraf return (ep);
1707*753d2d2eSraf }
1708*753d2d2eSraf
1709*753d2d2eSraf /* decl_AddDS - add a decl_spec_t to a decl_t. */
1710*753d2d2eSraf
1711*753d2d2eSraf static decl_t *
decl_AddDS(decl_t * dp,decl_spec_t * dsp,const char ** err)1712*753d2d2eSraf decl_AddDS(decl_t *dp, decl_spec_t *dsp, const char **err) {
1713*753d2d2eSraf declspec_AddDS(dp->d_ds, dsp, err);
1714*753d2d2eSraf
1715*753d2d2eSraf return (dp);
1716*753d2d2eSraf }
1717*753d2d2eSraf
1718*753d2d2eSraf /*
1719*753d2d2eSraf * decl_SetName - set the name associated with a decl_t.
1720*753d2d2eSraf *
1721*753d2d2eSraf * Note:
1722*753d2d2eSraf * 1) Any previously known name is free'd.
1723*753d2d2eSraf */
1724*753d2d2eSraf
1725*753d2d2eSraf decl_t *
decl_SetName(decl_t * dp,char * s)1726*753d2d2eSraf decl_SetName(decl_t *dp, char *s) {
1727*753d2d2eSraf free(dp->d_name);
1728*753d2d2eSraf dp->d_name = strdup(s);
1729*753d2d2eSraf assert(dp->d_name != NULL);
1730*753d2d2eSraf
1731*753d2d2eSraf return (dp);
1732*753d2d2eSraf }
1733*753d2d2eSraf
1734*753d2d2eSraf /*
1735*753d2d2eSraf * decl_AddTypeTail - add a type_t to the end of a decl_t type_t list.
1736*753d2d2eSraf */
1737*753d2d2eSraf
1738*753d2d2eSraf static decl_t *
decl_AddTypeTail(decl_t * dp,type_t * tp)1739*753d2d2eSraf decl_AddTypeTail(decl_t *dp, type_t *tp) {
1740*753d2d2eSraf if (dp->d_type)
1741*753d2d2eSraf type_AddTail(dp->d_type, tp);
1742*753d2d2eSraf else
1743*753d2d2eSraf dp->d_type = tp;
1744*753d2d2eSraf
1745*753d2d2eSraf return (dp);
1746*753d2d2eSraf }
1747*753d2d2eSraf
1748*753d2d2eSraf /*
1749*753d2d2eSraf * decl_addptr - add a DD_PTR type_t to the end of a decl_t type_t list.
1750*753d2d2eSraf */
1751*753d2d2eSraf
1752*753d2d2eSraf static decl_t *
decl_addptr(decl_t * dp,type_t * tp)1753*753d2d2eSraf decl_addptr(decl_t *dp, type_t *tp) {
1754*753d2d2eSraf decl_AddTypeTail(dp, tp);
1755*753d2d2eSraf
1756*753d2d2eSraf return (dp);
1757*753d2d2eSraf }
1758*753d2d2eSraf
1759*753d2d2eSraf /*
1760*753d2d2eSraf * decl_addary - allocate and add a DD_ARY type_t to the end of
1761*753d2d2eSraf * a decl_t type_t list.
1762*753d2d2eSraf */
1763*753d2d2eSraf
1764*753d2d2eSraf static decl_t *
decl_addary(decl_t * dp,char * sizep)1765*753d2d2eSraf decl_addary(decl_t *dp, char *sizep) {
1766*753d2d2eSraf type_t *tp = type_Construct();
1767*753d2d2eSraf
1768*753d2d2eSraf type_SetAry(tp, sizep);
1769*753d2d2eSraf decl_AddTypeTail(dp, tp);
1770*753d2d2eSraf
1771*753d2d2eSraf return (dp);
1772*753d2d2eSraf }
1773*753d2d2eSraf
1774*753d2d2eSraf /*
1775*753d2d2eSraf * decl_addfun - allocate and add a DD_FUN type_t to the end of a
1776*753d2d2eSraf * decl_t type_t list.
1777*753d2d2eSraf */
1778*753d2d2eSraf
1779*753d2d2eSraf static decl_t *
decl_addfun(decl_t * dp,decl_t * arglist)1780*753d2d2eSraf decl_addfun(decl_t *dp, decl_t *arglist) {
1781*753d2d2eSraf const char *sp;
1782*753d2d2eSraf type_t *tp = type_Construct();
1783*753d2d2eSraf
1784*753d2d2eSraf if (sp = decl_VerifyArgs(arglist))
1785*753d2d2eSraf yyerror(sp);
1786*753d2d2eSraf
1787*753d2d2eSraf type_SetFun(tp, arglist);
1788*753d2d2eSraf decl_AddTypeTail(dp, tp);
1789*753d2d2eSraf
1790*753d2d2eSraf return (dp);
1791*753d2d2eSraf }
1792*753d2d2eSraf
1793*753d2d2eSraf /*
1794*753d2d2eSraf * decl_addellipsis - set the ellipsis state in a decl_t.
1795*753d2d2eSraf *
1796*753d2d2eSraf * Note:
1797*753d2d2eSraf * 1) This function is only used in the grammar in the
1798*753d2d2eSraf * parameter list parsing.
1799*753d2d2eSraf */
1800*753d2d2eSraf
1801*753d2d2eSraf static decl_t *
decl_addellipsis(decl_t * dp)1802*753d2d2eSraf decl_addellipsis(decl_t *dp) {
1803*753d2d2eSraf dp->d_ellipsis = 1;
1804*753d2d2eSraf
1805*753d2d2eSraf return (dp);
1806*753d2d2eSraf }
1807*753d2d2eSraf
1808*753d2d2eSraf #if defined(DEBUG)
1809*753d2d2eSraf
1810*753d2d2eSraf static void
decl_PrintDecl(decl_t * dp,int lvl)1811*753d2d2eSraf decl_PrintDecl(decl_t *dp, int lvl) {
1812*753d2d2eSraf char buf[BUFSIZ];
1813*753d2d2eSraf
1814*753d2d2eSraf while (dp) {
1815*753d2d2eSraf putNTabs(lvl);
1816*753d2d2eSraf
1817*753d2d2eSraf printf("name = %s, ds = %s\n",
1818*753d2d2eSraf (dp->d_name)? dp->d_name : "<null>",
1819*753d2d2eSraf declspec_ToString(buf, dp->d_ds));
1820*753d2d2eSraf
1821*753d2d2eSraf if (dp->d_type)
1822*753d2d2eSraf type_PrintType(dp->d_type, lvl + 1);
1823*753d2d2eSraf
1824*753d2d2eSraf dp = dp->d_next;
1825*753d2d2eSraf }
1826*753d2d2eSraf }
1827*753d2d2eSraf #endif /* DEBUG */
1828*753d2d2eSraf
1829*753d2d2eSraf static char *
char_getend(char * s)1830*753d2d2eSraf char_getend(char *s) {
1831*753d2d2eSraf while (*s != '\0')
1832*753d2d2eSraf ++s;
1833*753d2d2eSraf
1834*753d2d2eSraf return (s);
1835*753d2d2eSraf }
1836*753d2d2eSraf
1837*753d2d2eSraf char *
decl_ToString(char * bufp,decl_dts_t out,decl_t * dp,const char * altname)1838*753d2d2eSraf decl_ToString(char *bufp, decl_dts_t out, decl_t *dp,
1839*753d2d2eSraf const char *altname) {
1840*753d2d2eSraf char tmp[BUFSIZ];
1841*753d2d2eSraf char tmp2[BUFSIZ];
1842*753d2d2eSraf const char *namep;
1843*753d2d2eSraf char *bend = bufp;
1844*753d2d2eSraf type_t *tp = dp->d_type;
1845*753d2d2eSraf int ffun = 1;
1846*753d2d2eSraf
1847*753d2d2eSraf switch (out) {
1848*753d2d2eSraf default:
1849*753d2d2eSraf out = DTS_DECL;
1850*753d2d2eSraf /* FALLTHRU */
1851*753d2d2eSraf case DTS_DECL:
1852*753d2d2eSraf if (altname == NULL) {
1853*753d2d2eSraf namep = dp->d_name;
1854*753d2d2eSraf } else {
1855*753d2d2eSraf namep = altname;
1856*753d2d2eSraf }
1857*753d2d2eSraf break;
1858*753d2d2eSraf case DTS_CAST:
1859*753d2d2eSraf namep = "(*)";
1860*753d2d2eSraf break;
1861*753d2d2eSraf case DTS_RET:
1862*753d2d2eSraf if (altname == NULL) {
1863*753d2d2eSraf namep = "_return";
1864*753d2d2eSraf } else {
1865*753d2d2eSraf namep = altname;
1866*753d2d2eSraf }
1867*753d2d2eSraf break;
1868*753d2d2eSraf }
1869*753d2d2eSraf
1870*753d2d2eSraf *bufp = '\0';
1871*753d2d2eSraf
1872*753d2d2eSraf strcpy(tmp, (namep) ? namep : "");
1873*753d2d2eSraf
1874*753d2d2eSraf while (tp) {
1875*753d2d2eSraf switch (tp->t_dt) {
1876*753d2d2eSraf case DD_PTR:
1877*753d2d2eSraf if (tp->t_next &&
1878*753d2d2eSraf ((tp->t_next->t_dt == DD_ARY) ||
1879*753d2d2eSraf (tp->t_next->t_dt == DD_FUN))) {
1880*753d2d2eSraf if (out == DTS_RET) {
1881*753d2d2eSraf sprintf(bufp, "(*%s)", namep);
1882*753d2d2eSraf } else {
1883*753d2d2eSraf sprintf(bufp, "(*%s)", tmp);
1884*753d2d2eSraf }
1885*753d2d2eSraf } else if (tp->t_stt == TQ_CONST) {
1886*753d2d2eSraf sprintf(bufp, "*const %s", tmp);
1887*753d2d2eSraf } else if (tp->t_stt == TQ_VOLATILE) {
1888*753d2d2eSraf sprintf(bufp, "*volatile %s", tmp);
1889*753d2d2eSraf /*
1890*753d2d2eSraf * It currently acknowledges and ignores restrict
1891*753d2d2eSraf * or _RESTRICT_KYWD in code generation because
1892*753d2d2eSraf * of the uncertain behavior of "restrict".
1893*753d2d2eSraf */
1894*753d2d2eSraf } else if (tp->t_stt == TQ_RESTRICT) {
1895*753d2d2eSraf sprintf(bufp, "*%s", tmp);
1896*753d2d2eSraf } else if (tp->t_stt == TQ_RESTRICT_KYWD) {
1897*753d2d2eSraf sprintf(bufp, "*%s", tmp);
1898*753d2d2eSraf } else {
1899*753d2d2eSraf sprintf(bufp, "*%s", tmp);
1900*753d2d2eSraf }
1901*753d2d2eSraf
1902*753d2d2eSraf break;
1903*753d2d2eSraf
1904*753d2d2eSraf case DD_ARY:
1905*753d2d2eSraf sprintf(bufp, "%s[%s]",
1906*753d2d2eSraf tmp, (tp->t_sizestr)? tp->t_sizestr : "");
1907*753d2d2eSraf break;
1908*753d2d2eSraf
1909*753d2d2eSraf case DD_FUN:
1910*753d2d2eSraf if (out == DTS_RET && ffun == 1) {
1911*753d2d2eSraf strcpy(bufp, namep);
1912*753d2d2eSraf ffun = 0;
1913*753d2d2eSraf } else if (tp->t_args == NULL) {
1914*753d2d2eSraf sprintf(bufp, "%s()", tmp);
1915*753d2d2eSraf } else {
1916*753d2d2eSraf char buf2[BUFSIZ];
1917*753d2d2eSraf decl_t *argp = tp->t_args;
1918*753d2d2eSraf
1919*753d2d2eSraf sprintf(bufp, "%s(", tmp);
1920*753d2d2eSraf bend = char_getend(bufp);
1921*753d2d2eSraf
1922*753d2d2eSraf for (argp = tp->t_args; argp; /* noinc */) {
1923*753d2d2eSraf decl_ToString(buf2, DTS_DECL, argp,
1924*753d2d2eSraf NULL);
1925*753d2d2eSraf sprintf(bend, " %s", buf2);
1926*753d2d2eSraf
1927*753d2d2eSraf bend = char_getend(bend);
1928*753d2d2eSraf
1929*753d2d2eSraf if (argp = argp->d_next) {
1930*753d2d2eSraf sprintf(bend, ",");
1931*753d2d2eSraf bend = char_getend(bend);
1932*753d2d2eSraf }
1933*753d2d2eSraf }
1934*753d2d2eSraf
1935*753d2d2eSraf if (tp->t_ellipsis) {
1936*753d2d2eSraf sprintf(bend, ", ...");
1937*753d2d2eSraf bend = char_getend(bend);
1938*753d2d2eSraf }
1939*753d2d2eSraf
1940*753d2d2eSraf sprintf(bend, ")");
1941*753d2d2eSraf }
1942*753d2d2eSraf break;
1943*753d2d2eSraf }
1944*753d2d2eSraf
1945*753d2d2eSraf tp = tp->t_next;
1946*753d2d2eSraf
1947*753d2d2eSraf strcpy(tmp, bufp);
1948*753d2d2eSraf }
1949*753d2d2eSraf
1950*753d2d2eSraf if (out == DTS_CAST) {
1951*753d2d2eSraf sprintf(bufp, "(%s %s)",
1952*753d2d2eSraf declspec_ToString(tmp2, dp->d_ds), tmp);
1953*753d2d2eSraf } else {
1954*753d2d2eSraf sprintf(bufp, "%s %s",
1955*753d2d2eSraf declspec_ToString(tmp2, dp->d_ds), tmp);
1956*753d2d2eSraf }
1957*753d2d2eSraf
1958*753d2d2eSraf return (bufp);
1959*753d2d2eSraf }
1960*753d2d2eSraf
1961*753d2d2eSraf decl_t *
decl_AddArgNames(decl_t * dp)1962*753d2d2eSraf decl_AddArgNames(decl_t *dp) {
1963*753d2d2eSraf int argno = 0;
1964*753d2d2eSraf decl_t *p = dp;
1965*753d2d2eSraf
1966*753d2d2eSraf if (decl_IsFunction(dp)) {
1967*753d2d2eSraf int argno = 0;
1968*753d2d2eSraf decl_t *p = dp->d_type->t_args;
1969*753d2d2eSraf
1970*753d2d2eSraf while (p) {
1971*753d2d2eSraf char *s = decl_GetName(p);
1972*753d2d2eSraf
1973*753d2d2eSraf if ((s == NULL) && !decl_IsVoid(p)) {
1974*753d2d2eSraf char buf[BUFSIZ];
1975*753d2d2eSraf
1976*753d2d2eSraf sprintf(buf, "arg%d", argno);
1977*753d2d2eSraf s = strdup(buf);
1978*753d2d2eSraf decl_SetName(p, s);
1979*753d2d2eSraf }
1980*753d2d2eSraf
1981*753d2d2eSraf p = p->d_next;
1982*753d2d2eSraf ++argno;
1983*753d2d2eSraf }
1984*753d2d2eSraf }
1985*753d2d2eSraf return (dp);
1986*753d2d2eSraf }
1987*753d2d2eSraf
1988*753d2d2eSraf const char *
decl_Parse(char * str,decl_t ** dpp)1989*753d2d2eSraf decl_Parse(char *str, decl_t **dpp) {
1990*753d2d2eSraf errstr = NULL; /* setup the (static) globals */
1991*753d2d2eSraf input = str;
1992*753d2d2eSraf atIDENT = 0;
1993*753d2d2eSraf protop = NULL;
1994*753d2d2eSraf
1995*753d2d2eSraf yyparse(); /* parse the prototype */
1996*753d2d2eSraf
1997*753d2d2eSraf if (errstr == NULL) { /* success */
1998*753d2d2eSraf *dpp = protop;
1999*753d2d2eSraf decl_AddArgNames(protop);
2000*753d2d2eSraf } else { /* failure */
2001*753d2d2eSraf *dpp = NULL;
2002*753d2d2eSraf decl_Destroy(protop);
2003*753d2d2eSraf }
2004*753d2d2eSraf
2005*753d2d2eSraf return (errstr);
2006*753d2d2eSraf }
2007*753d2d2eSraf
2008*753d2d2eSraf static void
yyerror(const char * err)2009*753d2d2eSraf yyerror(const char *err) {
2010*753d2d2eSraf errstr = err;
2011*753d2d2eSraf }
2012*753d2d2eSraf
2013*753d2d2eSraf #if defined(DEBUG)
2014*753d2d2eSraf
2015*753d2d2eSraf /* main */
2016*753d2d2eSraf
2017*753d2d2eSraf static int yydebug = 1;
2018*753d2d2eSraf
2019*753d2d2eSraf int
main(int argc,char * argv[])2020*753d2d2eSraf main(int argc, char *argv[]) {
2021*753d2d2eSraf int i;
2022*753d2d2eSraf
2023*753d2d2eSraf yydebug = 1;
2024*753d2d2eSraf
2025*753d2d2eSraf for (i = 1; i < argc; ++i) {
2026*753d2d2eSraf const char *es;
2027*753d2d2eSraf char buf[BUFSIZ];
2028*753d2d2eSraf decl_t *pp;
2029*753d2d2eSraf
2030*753d2d2eSraf if (es = decl_Parse(argv[i], &pp))
2031*753d2d2eSraf printf("parse failure: %s\n", es);
2032*753d2d2eSraf else {
2033*753d2d2eSraf #if GR_DEBUG
2034*753d2d2eSraf decl_PrintDecl(pp, 0);
2035*753d2d2eSraf decl_AddArgNames(pp);
2036*753d2d2eSraf #endif
2037*753d2d2eSraf printf("---\n%s;\n",
2038*753d2d2eSraf decl_ToString(buf, DTS_DECL, pp, NULL));
2039*753d2d2eSraf printf("%s\n",
2040*753d2d2eSraf decl_ToString(buf, DTS_CAST, pp, NULL));
2041*753d2d2eSraf printf("%s;\n",
2042*753d2d2eSraf decl_ToString(buf, DTS_RET, pp, "%s"));
2043*753d2d2eSraf
2044*753d2d2eSraf #ifdef TRACE
2045*753d2d2eSraf printf("\n\nTrace Info\n");
2046*753d2d2eSraf decl_PrintTraceInfo(pp);
2047*753d2d2eSraf #endif
2048*753d2d2eSraf }
2049*753d2d2eSraf
2050*753d2d2eSraf decl_Destroy(pp);
2051*753d2d2eSraf
2052*753d2d2eSraf #if defined(MEM_DEBUG)
2053*753d2d2eSraf printf("declspec : %d\n", declspec_Construct_calls);
2054*753d2d2eSraf printf("type : %d\n", type_Construct_calls);
2055*753d2d2eSraf printf("decl : %d\n", decl_Construct_calls);
2056*753d2d2eSraf #endif
2057*753d2d2eSraf }
2058*753d2d2eSraf
2059*753d2d2eSraf return (0);
2060*753d2d2eSraf }
2061*753d2d2eSraf
2062*753d2d2eSraf #ifdef TRACE
2063*753d2d2eSraf void
decl_PrintTraceInfo(decl_t * dp)2064*753d2d2eSraf decl_PrintTraceInfo(decl_t *dp) {
2065*753d2d2eSraf char buf[BUFSIZ];
2066*753d2d2eSraf char f_type[BUFSIZ];
2067*753d2d2eSraf char f_print[BUFSIZ];
2068*753d2d2eSraf char a_name[BUFSIZ];
2069*753d2d2eSraf char a_type[BUFSIZ];
2070*753d2d2eSraf char a_print[BUFSIZ];
2071*753d2d2eSraf decl_t *funargs;
2072*753d2d2eSraf type_t *tp;
2073*753d2d2eSraf int isptrfun;
2074*753d2d2eSraf
2075*753d2d2eSraf if (dp == NULL)
2076*753d2d2eSraf return;
2077*753d2d2eSraf
2078*753d2d2eSraf fprintf(stderr, "interface = %s\n",
2079*753d2d2eSraf (dp->d_name) ? dp->d_name : "<null>");
2080*753d2d2eSraf
2081*753d2d2eSraf isptrfun = type_IsPtrFun(dp->d_type);
2082*753d2d2eSraf if (type_IsFunction(dp->d_type) || isptrfun)
2083*753d2d2eSraf decl_GetTraceInfo(dp, f_type, f_print, &funargs);
2084*753d2d2eSraf else
2085*753d2d2eSraf return;
2086*753d2d2eSraf
2087*753d2d2eSraf fprintf(stderr, "return type = %s\n", f_type);
2088*753d2d2eSraf fprintf(stderr, "print function = %s\n", f_print);
2089*753d2d2eSraf
2090*753d2d2eSraf if (isptrfun)
2091*753d2d2eSraf fprintf(stderr, "function is function pointer\n");
2092*753d2d2eSraf
2093*753d2d2eSraf if (type_IsVarargs(dp->d_type))
2094*753d2d2eSraf fprintf(stderr, "function is varargs\n");
2095*753d2d2eSraf
2096*753d2d2eSraf while (funargs) {
2097*753d2d2eSraf snprintf(a_type, BUFSIZ, "%s ",
2098*753d2d2eSraf declspec_ToString(buf, funargs->d_ds));
2099*753d2d2eSraf snprintf(a_print, BUFSIZ, "%s",
2100*753d2d2eSraf de_const(declspec_ToString(buf, funargs->d_ds)));
2101*753d2d2eSraf
2102*753d2d2eSraf tp = funargs->d_type;
2103*753d2d2eSraf
2104*753d2d2eSraf while (tp) {
2105*753d2d2eSraf if (tp->t_dt == DD_PTR || tp->t_dt == DD_ARY) {
2106*753d2d2eSraf strcat(a_type, "*");
2107*753d2d2eSraf strcat(a_print, "_P");
2108*753d2d2eSraf }
2109*753d2d2eSraf tp = tp->t_next;
2110*753d2d2eSraf }
2111*753d2d2eSraf
2112*753d2d2eSraf if (funargs->d_name) {
2113*753d2d2eSraf snprintf(a_name, BUFSIZ, "%s",
2114*753d2d2eSraf funargs->d_name ? funargs->d_name : "<nil>");
2115*753d2d2eSraf fprintf(stderr, "arg name = %s\n", a_name);
2116*753d2d2eSraf fprintf(stderr, "arg type = %s\n", a_type);
2117*753d2d2eSraf fprintf(stderr, "print function = %s\n", a_print);
2118*753d2d2eSraf } else {
2119*753d2d2eSraf strcpy(a_name, "");
2120*753d2d2eSraf strcpy(a_print, "");
2121*753d2d2eSraf fprintf(stderr, "arg type = %s\n", a_type);
2122*753d2d2eSraf }
2123*753d2d2eSraf
2124*753d2d2eSraf funargs = funargs->d_next;
2125*753d2d2eSraf }
2126*753d2d2eSraf }
2127*753d2d2eSraf #endif /* TRACE */
2128*753d2d2eSraf #endif /* DEBUG */
2129*753d2d2eSraf
2130*753d2d2eSraf static char *
de_const(char * str)2131*753d2d2eSraf de_const(char *str)
2132*753d2d2eSraf {
2133*753d2d2eSraf return (str);
2134*753d2d2eSraf }
2135*753d2d2eSraf
2136*753d2d2eSraf
2137*753d2d2eSraf void
decl_GetTraceInfo(decl_t * dp,char * f_type,char * f_print,decl_t ** funargs)2138*753d2d2eSraf decl_GetTraceInfo(decl_t *dp, char *f_type, char *f_print, decl_t **funargs)
2139*753d2d2eSraf {
2140*753d2d2eSraf char buf[BUFSIZ];
2141*753d2d2eSraf type_t *tp;
2142*753d2d2eSraf
2143*753d2d2eSraf if (dp == NULL)
2144*753d2d2eSraf return;
2145*753d2d2eSraf
2146*753d2d2eSraf snprintf(f_type, BUFSIZ, "%s ",
2147*753d2d2eSraf declspec_ToString(buf, dp->d_ds));
2148*753d2d2eSraf snprintf(f_print, BUFSIZ, "%s",
2149*753d2d2eSraf de_const(declspec_ToString(buf, dp->d_ds)));
2150*753d2d2eSraf tp = dp->d_type;
2151*753d2d2eSraf while (tp) {
2152*753d2d2eSraf if (tp->t_dt == DD_PTR) {
2153*753d2d2eSraf strcat(f_type, "*");
2154*753d2d2eSraf strcat(f_print, "*");
2155*753d2d2eSraf }
2156*753d2d2eSraf tp = tp->t_next;
2157*753d2d2eSraf }
2158*753d2d2eSraf
2159*753d2d2eSraf strcat(f_type, "%s");
2160*753d2d2eSraf
2161*753d2d2eSraf tp = decl_GetType(dp);
2162*753d2d2eSraf if (type_IsPtrFun(tp)) {
2163*753d2d2eSraf while (tp->t_dt != DD_FUN)
2164*753d2d2eSraf tp = tp->t_next;
2165*753d2d2eSraf *funargs = tp->t_args;
2166*753d2d2eSraf } else {
2167*753d2d2eSraf *funargs = dp->d_type->t_args;
2168*753d2d2eSraf }
2169*753d2d2eSraf }
2170*753d2d2eSraf
2171*753d2d2eSraf char *
decl_ToFormal(decl_t * dp)2172*753d2d2eSraf decl_ToFormal(decl_t *dp)
2173*753d2d2eSraf {
2174*753d2d2eSraf char tmp[BUFSIZ];
2175*753d2d2eSraf static char bufp[BUFSIZ];
2176*753d2d2eSraf char *bend;
2177*753d2d2eSraf type_t *tp = dp->d_type;
2178*753d2d2eSraf
2179*753d2d2eSraf tmp[0] = 0;
2180*753d2d2eSraf bufp[0] = 0;
2181*753d2d2eSraf bend = bufp;
2182*753d2d2eSraf
2183*753d2d2eSraf while (tp) {
2184*753d2d2eSraf switch (tp->t_dt) {
2185*753d2d2eSraf case DD_ARY:
2186*753d2d2eSraf sprintf(bufp, "%s[%s]", tmp,
2187*753d2d2eSraf (tp->t_sizestr)? tp->t_sizestr : "");
2188*753d2d2eSraf break;
2189*753d2d2eSraf
2190*753d2d2eSraf case DD_FUN:
2191*753d2d2eSraf if (tp->t_args != NULL) {
2192*753d2d2eSraf char buf2[BUFSIZ];
2193*753d2d2eSraf decl_t *argp = tp->t_args;
2194*753d2d2eSraf
2195*753d2d2eSraf bend = char_getend(bufp);
2196*753d2d2eSraf
2197*753d2d2eSraf for (argp = tp->t_args; argp; /* noinc */) {
2198*753d2d2eSraf decl_ToString(buf2, DTS_DECL, argp,
2199*753d2d2eSraf NULL);
2200*753d2d2eSraf sprintf(bend, " %s", buf2);
2201*753d2d2eSraf
2202*753d2d2eSraf bend = char_getend(bend);
2203*753d2d2eSraf
2204*753d2d2eSraf if (argp = argp->d_next) {
2205*753d2d2eSraf sprintf(bend, ",");
2206*753d2d2eSraf bend = char_getend(bend);
2207*753d2d2eSraf }
2208*753d2d2eSraf }
2209*753d2d2eSraf if (tp->t_ellipsis) {
2210*753d2d2eSraf sprintf(bend, ", ...");
2211*753d2d2eSraf bend = char_getend(bend);
2212*753d2d2eSraf }
2213*753d2d2eSraf
2214*753d2d2eSraf sprintf(bend, "");
2215*753d2d2eSraf }
2216*753d2d2eSraf break;
2217*753d2d2eSraf }
2218*753d2d2eSraf
2219*753d2d2eSraf tp = tp->t_next;
2220*753d2d2eSraf
2221*753d2d2eSraf strcpy(tmp, bufp);
2222*753d2d2eSraf }
2223*753d2d2eSraf
2224*753d2d2eSraf sprintf(bufp, "%s", tmp);
2225*753d2d2eSraf
2226*753d2d2eSraf return (bufp);
2227*753d2d2eSraf }
2228