parseproto.y revision f07a2a2ef3832ccd4e9e1584966c139773495d2d
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * CDDL HEADER START
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * The contents of this file are subject to the terms of the
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * Common Development and Distribution License, Version 1.0 only
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * (the "License"). You may not use this file except in compliance
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * with the License.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * See the License for the specific language governing permissions
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * and limitations under the License.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * When distributing Covered Code, include this CDDL HEADER in each
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * If applicable, add the following below this CDDL HEADER, with the
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * fields enclosed by brackets "[]" replaced with your own identifying
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * information: Portions Copyright [yyyy] [name of copyright owner]
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * CDDL HEADER END
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * Use is subject to license terms.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang#pragma ident "%Z%%M% %I% %E% SMI"
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fangstatic decl_spec_t *declspec_Init(stt_t, char *);
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fangstatic decl_spec_t *declspec_AddSTT(decl_spec_t *, stt_t, const char **);
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fangstatic decl_spec_t *declspec_AddDS(decl_spec_t *,
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang decl_spec_t *, const char **);
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fangstatic decl_t *decl_AddDS(decl_t *, decl_spec_t *, const char **);
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fangstatic decl_t *decl_AddTypeTail(decl_t *, type_t *);
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fangstatic char *de_const(char *);
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fangstatic int yylex(void);
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fangstatic void yyerror(const char *);
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fangstatic int yyparse(void);
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fangstatic char *de_const(char *);
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang%token <stt_val> CONST VOLATILE RESTRICT RESTRICT_KYWD
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang%type <ds_val> struct_or_union_specifier enum_specifier
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang%type <d_val> init_declarator_list init_declarator
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * The grammar is derived from ANSI/ISO 9899-1990.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang : declaration_specifiers init_declarator_list ';'
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang /* only one declaration allowed */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang const char *sp;
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * XXX - Does not support a "stand-alone" declaration specifier. It is
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * essentially a type declaration, for example:
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * typedef enum { FALSE = 0, TRUE = 1 } boolean_t;
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * struct _name { char *first; char *last };
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang/* XXX | declaration_specifiers */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang : storage_class_specifier declaration_specifiers
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang char const *ep;
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang const char *ep;
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang const char *ep;
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * XXX - Does not support any storage class specifier other than
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * register, and then only for function arguments.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang $$ = declspec_Init(SCS_TYPEDEF, NULL);
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang $$ = declspec_Init(SCS_EXTERN, NULL);
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang $$ = declspec_Init(SCS_STATIC, NULL);
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang $$ = declspec_Init(SCS_AUTO, NULL);
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * The "restrict" keyword is new in the C99 standard.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * It is type qualifier like const and volatile.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * We are using "_RESTRICT_KYWD" in headers and source code so
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * it is easily turned on and off by various macros at compile time.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * In order for the "restrict" keyword to be recognized you must
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * be using a C99 compliant compiler in its native mode.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * XXX - struct or union definitions are not supported. It is generally
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * not done within the context of a function declaration (prototype) or
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * variable definition.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang | struct_or_union IDENTIFIER '{' struct_declaration_list '}'
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang | struct_or_union '{' struct_declaration_list '}'
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * XXX - Does not support a comma separated list of declarations or
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * definitions. Function prototypes or variable definitions must be
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * given as one per C statement.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang | init_declarator_list ',' init_declarator
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang $$ = decl_AddArg($1, $3);
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang atIDENT = 1;
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * XXX - Initialization is not supported.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang | declarator '=' initializer
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * XXX - enumerator definition is not supported for the same reasons
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * struct|union definition is not supported.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang | ENUM IDENTIFIER '{' enumerator_list '}'
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang | ENUM '{' enumerator_list '}'
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang $$ = type_SetPtr(type_Construct(), ($2)->ds_stt);
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang const char *ep;
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang /* XXX - ignore any error */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang const char *ep;
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang const char *ep;
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang const char *ep;
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang | direct_abstract_declarator '[' constant_expression ']'
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang | direct_abstract_declarator '(' parameter_type_list ')'
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * XXX - General case constant expressions are not supported. It would
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * be easy to implement (for the most part), but there are no cases to
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * date that require such a facility. The grammar does allow an
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * identifier (or typedef name) to be used since the prototype is not
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * processed by CPP. The only integer constant that is supported is
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang/* Data Declarations */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fangtypedef struct {
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fangtypedef struct {
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang/* External Declarations */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fangstatic const keyword_t *lookup_keyword(const char *);
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fangstatic int getch(void);
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fangstatic void ungetch(int);
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fangstatic void skipwhitespace(void);
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fangstatic int lookahead(int);
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fangstatic void skipcomment(void);
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang/* External Definitions */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fangstatic char *input = NULL; /* current place in the input stream */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang/* at point in stream were identifier is expected */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fangstatic int atIDENT = 0;
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fangstatic decl_t *protop = NULL; /* pointer to prototype */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fangstatic const char *errstr = NULL; /* error message */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * lookup_keyword - Given a string, return the keyword_t or NULL.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fangstatic const keyword_t *
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang#endif /* UNSUPPORTED */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang { "_RESTRICT_KYWD",RESTRICT_KYWD, TQ_RESTRICT_KYWD},
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang#define NKEYWORD (sizeof (keytbl)/sizeof (keyword_t))
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang for (i = 0; i < NKEYWORD; ++i) {
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang return (&keytbl[i]);
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * lookup_sttpair - Given an stt_t return a string or NULL.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fangstatic const char *
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang /* valid type specifier combinations */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang "signed short int" },
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang "unsigned short" },
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang "unsigned short int" },
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang "signed long int" },
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang "unsigned long int" },
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang /* non-ANSI type: long long */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang "signed long long" },
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang "unsigned long long" },
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang "signed long long int" },
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang "unsigned long long int" },
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang#define NDECLSPEC (sizeof (stttbl)/sizeof (sttpair_t))
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang for (i = 0; i < NDECLSPEC; ++i)
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * yylex - return next token from the the input stream.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * The lexical analyzer does not recognize all possible C lexical
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * elements. It only recognizes those associated with function
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * declarations (read: prototypes) and data definitions.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang switch (c = getch()) {
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang } else if (isdigit(c)) {
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang/* NOTREACHED */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang/* getch - return the next character from the input stream. */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang else /* only advance on non-NULL */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang/* ungetch - return a character to the input stream. */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang/* skipwhitespace - skip over whitespace in the input stream. */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang/* skipcomment - scan ahead to the next end of comment. */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang switch (c = getch()) {
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang/* NOTREACHED */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang/* lookahead - does next character match 'c'? */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang/* putNtabs - write N '\t' to standard output. */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang for (i = 0; i < n; ++i)
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang#endif /* DEBUG */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang/* D E C L A R A T I O N S P E C I F I E R S */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * Declaration specifiers encode storage class, type specifier and type
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * qualifier information. This includes any identifiers associated with
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * struct, union or enum declarations. Typedef names are also encoded
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * in declaration specifiers.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang/* declspec_Construct - allocate and initialize a declspec_t. */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang decl_spec_t *dsp = malloc(sizeof (decl_spec_t));
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang/* declspec_Destroy - free a declspec_t. */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * declspec_Init - allocate and initialize a declspec_t given an
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * stt_t and identifier.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * 1) identifier can be NULL.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * 2) errors resulting in the stt_t and identifier are ignored.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang const char *p;
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang declspec_AddDS(dsp, &tmp, &p); /* XXX ignore any error */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * declspec_VerifySTT - verify that the two given stt_t can be combined.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * 1) The return value is a const char *, non-NULL to indicate an error.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fangstatic char *
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang return ("attempt to add declaration specifier "
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang "that is already present");
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang if (STT_isbasic(result) && STT_isderived(result))
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang return ("attempt to combine basic and "
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang "derived types");
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang return ("attempt to combine void with "
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang "other type specifiers");
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang return ("attempt to combine floating and "
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang "integer type specifiers");
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang return ("attempt to combine character and "
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang "integer type specifiers");
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang return ("attempt to combine signed or "
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang "unsigned with float or derived type");
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang return ("invalid declaration specifier");
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * declspec_AddSTT - add an stt_t to a decl_spec_t.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * 1) The "long long" type is handled here.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * If both stt_t include TS_LONG then this is an attempt to use
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * "long long". The TS_LONG is cleared from the s1 and s2 and
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * then TS_LONGLONG is added to s2. The resulting s1 and s2 are
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * passed to declspec_VerifySTT to determine if the result is valid.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * 2) This method of handling "long long" does detect the case of
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * "long double long" and all it's variant forms.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fangdeclspec_AddSTT(decl_spec_t *dsp, stt_t s2, const char **err) {
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang /* non-ANSI type: long long */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang if ((*err = declspec_VerifySTT(s1, s2)) == NULL)
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * declpec_AddDS - add a decl_spec_t to an existing decl_spec_t.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fangdeclspec_AddDS(decl_spec_t *dsp, decl_spec_t *tsp, const char **err) {
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * declspec_GetSTT - return the stt_t within a decl_spec_t.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * declspec_GetTag - return the identifier within a decl_spec_t.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fangstatic char *
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * declspec_ToString - convert a decl_spec_t into a string.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * 1) The form of the resulting string is always the same, i.e.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * [register] [type_specifier] [const] [volatile]
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * dsp must be correct
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fangdeclspec_ToString(char *bufp, decl_spec_t *dsp) {
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang const char *s;
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang /* storage class specifier */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang /* type specifier */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang if (dsp->ds_stt & TQ_CONST) /* type qualifier */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * It currently acknowledges and ignores restrict or _RESTRICT_KYWD
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * in code generation because of the uncertain behavior of "restrict".
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang/* T Y P E M O D I F I E R S */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * Type modifiers encode the "array of...", "pointer to ..." and
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * "function returning ..." aspects of C types. The modifiers are kept
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * as a linked list in precedence order. The grammar encodes the
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * precedence order described by the standard.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * Type modifiers are always added at the end of list and the list is
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * always traversed from head to tail.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang/* type_Construct - allocate and initialize a type_t. */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang /* DD_PTR */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang/* type_Destroy - free a type_t list. */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * type_SetPtr - make a type_t into a "pointer to ..." variant.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * 1) The stt_t will encode any type qualifiers (const, volatile).
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * type_SetAry - make a type_t into an "array of ...", variant.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * 1) The array dimension can be NULL to indicate undefined, i.e. [].
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * type_SetFun - make a type_t into a "function returning ..." variant.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * 1) The argument list can be NULL to indicate undefined, i.e. ().
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * type_AddTail - add a type_t to the end of an existing type_t list.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * 1) The type_t *tp is added to the end of the type_t *dp list.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang/* type_PrintType - print a type_t list onto standard output. */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang printf("[%s] ptr to\n", declspec_ToString(buf, &tmp));
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang "undefined arguments");
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang#endif /* DEBUG */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * type_Verify - verify a type_t list for semantic correctness.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * 1) C supports most combinations of type modifiers.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * It does not support three combinations, they are:
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * function returning array
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * array of functions
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * function returning function
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * 2) The enum values associated with type modifiers (i.e. DD_*)
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * cannot be modified without changing the table included within the
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * 3) The function returns NULL to indicate that the type modifier
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * list is valid and non-NULL to indicate an error.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * 4) A type_t of NULL is permitted to indicate an empty type_t list.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fangstatic const char *
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang /* NONE ARY FUN PTR */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang/* ARY */ {NULL, NULL, "array of functions", NULL},
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang const char *p;
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang nt = (nextp = tp->t_next)? nextp->t_dt : DD_NONE;
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang/* type_GetNext - return the next type_t in the list. */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * The following group of functions return and or
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * test various aspects of type modifiers.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * 1) The three functions: type_IsPtrTo, type_IsFunction and
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * type_IsArray will accept an argument of NULL.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * 2) All other functions require one of the above three to be true.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * Various asserts are in place to verify correct usage.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * type_IsPtrFun - determine if the type_t results in a call-able function.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * 1) The argument can be NULL.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * 2) The test is true if the type_t list is number of DD_PTR followed
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * by a DD_FUN.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang/* D E C L A R A T O R */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * A decl_t encodes the name,
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * declaration specifiers and type modifiers of an object.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang/* decl_Construct - allocate a decl_t. */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang/* decl_Destroy - free a decl_t list. */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * decl_GetArgLength - return the length of a decl_t list.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * 1) The argument may be NULL to indicate an empty list, len == 0.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * The following group of functions get or test various aspects of a decl_t.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * decl_AddArg - add a decl_t to the end of an decl_t list.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * decl_IsVoid - return true if the decl_t is a "pure" void declaration.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang return ((declspec_GetSTT(dp->d_ds) & TS_VOID) && (dp->d_type == NULL));
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * decl_IsVoidArray - return true if the decl_t includes "void []".
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * decl_Verify - verify a decl_t.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fangstatic const char *
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * decl_VerifyArgs - verify a decl_t list.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fangstatic const char *
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang "void with identifier";
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang/* decl_AddDS - add a decl_spec_t to a decl_t. */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fangdecl_AddDS(decl_t *dp, decl_spec_t *dsp, const char **err) {
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * decl_SetName - set the name associated with a decl_t.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * 1) Any previously known name is free'd.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * decl_AddTypeTail - add a type_t to the end of a decl_t type_t list.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * decl_addptr - add a DD_PTR type_t to the end of a decl_t type_t list.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * decl_addary - allocate and add a DD_ARY type_t to the end of
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * a decl_t type_t list.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * decl_addfun - allocate and add a DD_FUN type_t to the end of a
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * decl_t type_t list.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang const char *sp;
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * decl_addellipsis - set the ellipsis state in a decl_t.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * 1) This function is only used in the grammar in the
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * parameter list parsing.
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang#endif /* DEBUG */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fangstatic char *
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang while (*s != '\0')
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fangdecl_ToString(char *bufp, decl_dts_t out, decl_t *dp,
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang const char *altname) {
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang const char *namep;
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang /* FALLTHRU */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * It currently acknowledges and ignores restrict
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * or _RESTRICT_KYWD in code generation because
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang * of the uncertain behavior of "restrict".
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang } else { /* failure */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang const char *es;
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang printf("declspec : %d\n", declspec_Construct_calls);
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang decl_GetTraceInfo(dp, f_type, f_print, &funargs);
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang fprintf(stderr, "print function = %s\n", f_print);
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang fprintf(stderr, "function is function pointer\n");
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang de_const(declspec_ToString(buf, funargs->d_ds)));
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang fprintf(stderr, "print function = %s\n", a_print);
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang#endif /* TRACE */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fang#endif /* DEBUG */
22a84b8d79248a611e4ba663a268d3c4bed054acQuaker Fangstatic char *