4 * Ullrich von Bassewitz, 20.06.1998
34 /*****************************************************************************/
36 /*****************************************************************************/
40 static void ParseTypeSpec (DeclSpec* D, int Default);
41 /* Parse a type specificier */
45 /*****************************************************************************/
46 /* internal functions */
47 /*****************************************************************************/
51 static type OptionalQualifiers (type Q)
52 /* Read type qualifiers if we have any */
54 while (curtok == TOK_CONST || curtok == TOK_VOLATILE) {
59 if (Q & T_QUAL_CONST) {
60 Error ("Duplicate qualifier: `const'");
66 if (Q & T_QUAL_VOLATILE) {
67 Error ("Duplicate qualifier: `volatile'");
82 /* Return the qualifiers read */
88 static void optionalint (void)
89 /* Eat an optional "int" token */
91 if (curtok == TOK_INT) {
99 static void optionalsigned (void)
100 /* Eat an optional "signed" token */
102 if (curtok == TOK_SIGNED) {
110 static void InitDeclSpec (DeclSpec* D)
111 /* Initialize the DeclSpec struct for use */
120 static void InitDeclaration (Declaration* D)
121 /* Initialize the Declaration struct for use */
130 static void ParseStorageClass (DeclSpec* D, unsigned DefStorage)
131 /* Parse a storage class */
133 /* Assume we're using an explicit storage class */
134 D->Flags &= ~DS_DEF_STORAGE;
136 /* Check the storage class given */
140 D->StorageClass = SC_EXTERN | SC_STATIC;
145 D->StorageClass = SC_STATIC;
150 D->StorageClass = SC_REGISTER | SC_STATIC;
155 D->StorageClass = SC_AUTO;
160 D->StorageClass = SC_TYPEDEF;
165 /* No storage class given, use default */
166 D->Flags |= DS_DEF_STORAGE;
167 D->StorageClass = DefStorage;
174 static void ParseEnumDecl (void)
175 /* Process an enum declaration . */
180 /* Accept forward definitions */
181 if (curtok != TOK_LCURLY) {
185 /* Skip the opening curly brace */
188 /* Read the enum tags */
190 while (curtok != TOK_RCURLY) {
192 /* We expect an identifier */
193 if (curtok != TOK_IDENT) {
194 Error ("Identifier expected");
198 /* Remember the identifier and skip it */
199 strcpy (Ident, CurTok.Ident);
202 /* Check for an assigned value */
203 if (curtok == TOK_ASSIGN) {
207 EnumVal = lval.e_const;
210 /* Add an entry to the symbol table */
211 AddEnumSym (Ident, EnumVal++);
213 /* Check for end of definition */
214 if (curtok != TOK_COMMA)
223 static SymEntry* ParseStructDecl (const char* Name, type StructType)
224 /* Parse a struct/union declaration. */
233 if (curtok != TOK_LCURLY) {
234 /* Just a forward declaration. Try to find a struct with the given
235 * name. If there is none, insert a forward declaration into the
236 * current lexical level.
238 Entry = FindTagSym (Name);
240 Entry = AddStructSym (Name, 0, 0);
241 } else if (SymIsLocal (Entry) && (Entry->Flags & SC_STRUCT) == 0) {
242 /* Already defined in the level but no struct */
243 Error ("Symbol `%s' is already different kind", Name);
248 /* Add a forward declaration for the struct in the current lexical level */
249 Entry = AddStructSym (Name, 0, 0);
251 /* Skip the curly brace */
254 /* Enter a new lexical level for the struct */
257 /* Parse struct fields */
259 while (curtok != TOK_RCURLY) {
261 /* Get the type of the entry */
263 InitDeclSpec (&Spec);
264 ParseTypeSpec (&Spec, -1);
266 /* Read fields with this type */
269 /* Get type and name of the struct field */
271 ParseDecl (&Spec, &Decl, 0);
273 /* Add a field entry to the table */
274 AddLocalSym (Decl.Ident, Decl.Type, SC_SFLD, (StructType == T_STRUCT)? Size : 0);
276 /* Calculate offset of next field/size of the union */
277 Offs = SizeOf (Decl.Type);
278 if (StructType == T_STRUCT) {
286 if (curtok != TOK_COMMA)
293 /* Skip the closing brace */
296 /* Remember the symbol table and leave the struct level */
297 FieldTab = GetSymTab ();
300 /* Make a real entry from the forward decl and return it */
301 return AddStructSym (Name, Size, FieldTab);
306 static void ParseTypeSpec (DeclSpec* D, int Default)
307 /* Parse a type specificier */
312 type Qualifiers; /* Type qualifiers */
314 /* Assume we have an explicit type */
315 D->Flags &= ~DS_DEF_TYPE;
317 /* Read type qualifiers if we have any */
318 Qualifiers = OptionalQualifiers (T_QUAL_NONE);
320 /* Look at the data type */
331 D->Type[0] = GetDefaultChar();
337 if (curtok == TOK_UNSIGNED) {
340 D->Type[0] = T_ULONG;
352 if (curtok == TOK_UNSIGNED) {
355 D->Type[0] = T_USHORT;
360 D->Type[0] = T_SHORT;
377 D->Type[0] = T_SCHAR;
384 D->Type[0] = T_SHORT;
412 D->Type[0] = T_UCHAR;
419 D->Type[0] = T_USHORT;
426 D->Type[0] = T_ULONG;
443 StructType = (curtok == TOK_STRUCT)? T_STRUCT : T_UNION;
446 if (curtok == TOK_IDENT) {
447 strcpy (Ident, CurTok.Ident);
450 AnonName (Ident, (StructType == T_STRUCT)? "struct" : "union");
452 /* Remember we have an extra type decl */
453 D->Flags |= DS_EXTRA_TYPE;
454 /* Declare the struct in the current scope */
455 Entry = ParseStructDecl (Ident, StructType);
456 /* Encode the struct entry into the type */
457 D->Type[0] = StructType;
458 EncodePtr (D->Type+1, Entry);
459 D->Type[DECODE_SIZE+1] = T_END;
464 if (curtok != TOK_LCURLY) {
466 if (curtok == TOK_IDENT) {
467 /* Find an entry with this name */
468 Entry = FindTagSym (CurTok.Ident);
470 if (SymIsLocal (Entry) && (Entry->Flags & SC_ENUM) == 0) {
471 Error ("Symbol `%s' is already different kind", Entry->Name);
474 /* Insert entry into table ### */
476 /* Skip the identifier */
479 Error ("Identifier expected");
482 /* Remember we have an extra type decl */
483 D->Flags |= DS_EXTRA_TYPE;
484 /* Parse the enum decl */
491 Entry = FindSym (CurTok.Ident);
492 if (Entry && IsTypeDef (Entry)) {
495 TypeCpy (D->Type, Entry->Type);
502 Error ("Type expected");
506 D->Flags |= DS_DEF_TYPE;
507 D->Type[0] = (type) Default;
513 /* There may also be qualifiers *after* the initial type */
514 D->Type[0] |= OptionalQualifiers (Qualifiers);
519 static type* ParamTypeCvt (type* T)
520 /* If T is an array, convert it to a pointer else do nothing. Return the
524 if (IsTypeArray (T)) {
533 static void ParseOldStyleParamList (FuncDesc* F)
534 /* Parse an old style (K&R) parameter list */
537 while (curtok != TOK_RPAREN) {
539 /* List of identifiers expected */
540 if (curtok != TOK_IDENT) {
541 Error ("Identifier expected");
544 /* Create a symbol table entry with type int */
545 AddLocalSym (CurTok.Ident, type_int, SC_AUTO | SC_PARAM | SC_DEF, 0);
547 /* Count arguments */
550 /* Skip the identifier */
553 /* Check for more parameters */
554 if (curtok == TOK_COMMA) {
561 /* Skip right paren. We must explicitly check for one here, since some of
562 * the breaks above bail out without checking.
566 /* An optional list of type specifications follows */
567 while (curtok != TOK_LCURLY) {
571 /* Read the declaration specifier */
572 ParseDeclSpec (&Spec, SC_AUTO, T_INT);
574 /* We accept only auto and register as storage class specifiers, but
575 * we ignore all this, since we use auto anyway.
577 if ((Spec.StorageClass & SC_AUTO) == 0 &&
578 (Spec.StorageClass & SC_REGISTER) == 0) {
579 Error ("Illegal storage class");
582 /* Parse a comma separated variable list */
587 /* Read the parameter */
588 ParseDecl (&Spec, &Decl, DM_NEED_IDENT);
589 if (Decl.Ident[0] != '\0') {
591 /* We have a name given. Search for the symbol */
592 SymEntry* Sym = FindLocalSym (Decl.Ident);
594 /* Found it, change the default type to the one given */
595 ChangeSymType (Sym, ParamTypeCvt (Decl.Type));
597 Error ("Unknown identifier: `%s'", Decl.Ident);
601 if (curtok == TOK_COMMA) {
609 /* Variable list must be semicolon terminated */
616 static void ParseAnsiParamList (FuncDesc* F)
617 /* Parse a new style (ANSI) parameter list */
620 while (curtok != TOK_RPAREN) {
626 /* Allow an ellipsis as last parameter */
627 if (curtok == TOK_ELLIPSIS) {
629 F->Flags |= FD_ELLIPSIS;
633 /* Read the declaration specifier */
634 ParseDeclSpec (&Spec, SC_AUTO, T_INT);
636 /* We accept only auto and register as storage class specifiers, but
637 * we ignore all this and use auto.
639 if ((Spec.StorageClass & SC_AUTO) == 0 &&
640 (Spec.StorageClass & SC_REGISTER) == 0) {
641 Error ("Illegal storage class");
643 Spec.StorageClass = SC_AUTO | SC_PARAM | SC_DEF;
645 /* Allow parameters without a name, but remember if we had some to
646 * eventually print an error message later.
648 ParseDecl (&Spec, &Decl, DM_ACCEPT_IDENT);
649 if (Decl.Ident[0] == '\0') {
651 /* Unnamed symbol. Generate a name that is not user accessible,
652 * then handle the symbol normal.
654 AnonName (Decl.Ident, "param");
655 F->Flags |= FD_UNNAMED_PARAMS;
657 /* Clear defined bit on nonames */
658 Spec.StorageClass &= ~SC_DEF;
661 /* Parse an attribute ### */
662 ParseAttribute (&Decl, &Attr);
664 /* Create a symbol table entry */
665 AddLocalSym (Decl.Ident, ParamTypeCvt (Decl.Type), Spec.StorageClass, 0);
667 /* Count arguments */
670 /* Check for more parameters */
671 if (curtok == TOK_COMMA) {
678 /* Skip right paren. We must explicitly check for one here, since some of
679 * the breaks above bail out without checking.
683 /* Check if this is a function definition */
684 if (curtok == TOK_LCURLY) {
685 /* Print an error if in strict ANSI mode and we have unnamed
688 if (ANSI && (F->Flags & FD_UNNAMED_PARAMS) != 0) {
689 Error ("Parameter name omitted");
696 static FuncDesc* ParseFuncDecl (void)
697 /* Parse the argument list of a function. */
702 /* Create a new function descriptor */
703 FuncDesc* F = NewFuncDesc ();
705 /* Enter a new lexical level */
706 EnterFunctionLevel ();
708 /* Check for several special parameter lists */
709 if (curtok == TOK_RPAREN) {
710 /* Parameter list is empty */
711 F->Flags |= (FD_EMPTY | FD_ELLIPSIS);
712 } else if (curtok == TOK_VOID && nxttok == TOK_RPAREN) {
713 /* Parameter list declared as void */
715 F->Flags |= FD_VOID_PARAM;
716 } else if (curtok == TOK_IDENT && (nxttok == TOK_COMMA || nxttok == TOK_RPAREN)) {
717 /* Old style (K&R) function. Assume variable param list. */
718 F->Flags |= (FD_OLDSTYLE | FD_ELLIPSIS);
722 if ((F->Flags & FD_OLDSTYLE) == 0) {
723 /* New style function */
724 ParseAnsiParamList (F);
726 /* Old style function */
727 ParseOldStyleParamList (F);
730 /* Assign offsets. If the function has a variable parameter list,
731 * there's one additional byte (the arg size).
733 Offs = (F->Flags & FD_ELLIPSIS)? 1 : 0;
734 Sym = GetSymTab()->SymTail;
736 unsigned Size = SizeOf (Sym->Type);
739 F->ParamSize += Size;
743 /* Leave the lexical level remembering the symbol tables */
744 RememberFunctionLevel (F);
746 /* Return the function descriptor */
752 static void Decl (Declaration* D, unsigned Mode)
753 /* Recursively process declarators. Build a type array in reverse order. */
756 if (curtok == TOK_STAR) {
759 /* Allow optional const or volatile qualifiers */
760 T |= OptionalQualifiers (T_QUAL_NONE);
764 } else if (curtok == TOK_LPAREN) {
768 } else if (curtok == TOK_FASTCALL) {
769 /* Remember the current type pointer */
771 /* Skip the fastcall token */
773 /* Parse the function */
775 /* Set the fastcall flag */
776 if (!IsTypeFunc (T)) {
777 Error ("__fastcall__ modifier applied to non function");
779 FuncDesc* F = DecodePtr (T+1);
780 F->Flags |= FD_FASTCALL;
784 /* Things depend on Mode now:
785 * - Mode == DM_NEED_IDENT means:
786 * we *must* have a type and a variable identifer.
787 * - Mode == DM_NO_IDENT means:
788 * we must have a type but no variable identifer
789 * (if there is one, it's not read).
790 * - Mode == DM_ACCEPT_IDENT means:
791 * we *may* have an identifier. If there is an identifier,
792 * it is read, but it is no error, if there is none.
794 if (Mode == DM_NO_IDENT) {
796 } else if (curtok == TOK_IDENT) {
797 strcpy (D->Ident, CurTok.Ident);
800 if (Mode == DM_NEED_IDENT) {
801 Error ("Identifier expected");
808 while (curtok == TOK_LBRACK || curtok == TOK_LPAREN) {
809 if (curtok == TOK_LPAREN) {
810 /* Function declaration */
813 /* Parse the function declaration */
814 F = ParseFuncDecl ();
819 /* Array declaration */
820 unsigned long Size = 0;
822 /* Read the size if it is given */
823 if (curtok != TOK_RBRACK) {
838 /*****************************************************************************/
840 /*****************************************************************************/
844 type* ParseType (type* Type)
845 /* Parse a complete type specification */
850 /* Get a type without a default */
851 InitDeclSpec (&Spec);
852 ParseTypeSpec (&Spec, -1);
854 /* Parse additional declarators */
855 InitDeclaration (&Decl);
856 ParseDecl (&Spec, &Decl, DM_NO_IDENT);
858 /* Copy the type to the target buffer */
859 TypeCpy (Type, Decl.Type);
861 /* Return a pointer to the target buffer */
867 void ParseDecl (const DeclSpec* Spec, Declaration* D, unsigned Mode)
868 /* Parse a variable, type or function declaration */
870 /* Initialize the Declaration struct */
873 /* Get additional declarators and the identifier */
876 /* Add the base type. */
877 TypeCpy (D->T, Spec->Type);
879 /* Check the size of the generated type */
880 if (!IsTypeFunc (D->Type) && !IsTypeVoid (D->Type) && SizeOf (D->Type) >= 0x10000) {
881 if (D->Ident[0] != '\0') {
882 Error ("Size of `%s' is invalid", D->Ident);
884 Error ("Invalid size");
891 void ParseDeclSpec (DeclSpec* D, unsigned DefStorage, int DefType)
892 /* Parse a declaration specification */
894 /* Initialize the DeclSpec struct */
897 /* First, get the storage class specifier for this declaration */
898 ParseStorageClass (D, DefStorage);
900 /* Parse the type specifiers */
901 ParseTypeSpec (D, DefType);
906 void CheckEmptyDecl (const DeclSpec* D)
907 /* Called after an empty type declaration (that is, a type declaration without
908 * a variable). Checks if the declaration does really make sense and issues a
912 if ((D->Flags & DS_EXTRA_TYPE) == 0) {
913 Warning ("Useless declaration");
919 static void ParseVoidInit (void)
920 /* Parse an initialization of a void variable (special cc65 extension) */
924 /* Allow an arbitrary list of values */
928 switch (lval.e_tptr[0]) {
932 if ((lval.e_flags & E_MCTYPE) == E_TCONST) {
933 /* Make it byte sized */
934 lval.e_const &= 0xFF;
945 if ((lval.e_flags & E_MCTYPE) == E_TCONST) {
946 /* Make it word sized */
947 lval.e_const &= 0xFFFF;
958 Error ("Illegal type in initialization");
963 if (curtok != TOK_COMMA) {
968 } while (curtok != TOK_RCURLY);
975 static void ParseStructInit (type* Type)
976 /* Parse initialization of a struct or union */
981 /* Consume the opening curly brace */
984 /* Get a pointer to the struct entry from the type */
985 Entry = (SymEntry*) Decode (Type + 1);
987 /* Check if this struct definition has a field table. If it doesn't, it
988 * is an incomplete definition.
990 Tab = Entry->V.S.SymTab;
992 Error ("Cannot initialize variables with incomplete type");
993 /* Returning here will cause lots of errors, but recovery is difficult */
997 /* Get a pointer to the list of symbols */
998 Entry = Tab->SymHead;
999 while (curtok != TOK_RCURLY) {
1001 Error ("Too many initializers");
1004 ParseInit (Entry->Type);
1005 Entry = Entry->NextSym;
1006 if (curtok != TOK_COMMA)
1011 /* Consume the closing curly brace */
1014 /* If there are struct fields left, reserve additional storage */
1016 g_zerobytes (SizeOf (Entry->Type));
1017 Entry = Entry->NextSym;
1023 void ParseInit (type* T)
1024 /* Parse initialization of variables. */
1032 switch (UnqualifiedType (*T)) {
1037 if ((lval.e_flags & E_MCTYPE) == E_TCONST) {
1038 /* Make it byte sized */
1039 lval.e_const &= 0xFF;
1041 assignadjust (T, &lval);
1051 if ((lval.e_flags & E_MCTYPE) == E_TCONST) {
1052 /* Make it word sized */
1053 lval.e_const &= 0xFFFF;
1055 assignadjust (T, &lval);
1062 if ((lval.e_flags & E_MCTYPE) == E_TCONST) {
1063 /* Make it long sized */
1064 lval.e_const &= 0xFFFFFFFF;
1066 assignadjust (T, &lval);
1071 sz = Decode (T + 1);
1072 t = T + DECODE_SIZE + 1;
1073 if (IsTypeChar(t) && curtok == TOK_SCONST) {
1074 str = GetLiteral (curval);
1075 count = strlen (str) + 1;
1076 TranslateLiteralPool (curval); /* Translate into target charset */
1077 g_defbytes (str, count);
1078 ResetLiteralOffs (curval); /* Remove string from pool */
1083 while (curtok != TOK_RCURLY) {
1084 ParseInit (T + DECODE_SIZE + 1);
1086 if (curtok != TOK_COMMA)
1093 Encode (T + 1, count);
1094 } else if (count < sz) {
1095 g_zerobytes ((sz - count) * SizeOf (T + DECODE_SIZE + 1));
1096 } else if (count > sz) {
1097 Error ("Too many initializers");
1103 ParseStructInit (T);
1108 /* Special cc65 extension in non ANSI mode */
1115 Error ("Illegal type");