4 * Ullrich von Bassewitz, 20.06.1998
31 /*****************************************************************************/
33 /*****************************************************************************/
37 static void ParseTypeSpec (DeclSpec* D, int Default);
38 /* Parse a type specificier */
42 /*****************************************************************************/
43 /* internal functions */
44 /*****************************************************************************/
48 static void optional_modifiers (void)
49 /* Eat optional "const" or "volatile" tokens */
51 while (curtok == CONST || curtok == VOLATILE) {
59 static void optionalint (void)
60 /* Eat an optional "int" token */
70 static void optionalsigned (void)
71 /* Eat an optional "signed" token */
73 if (curtok == SIGNED) {
81 static void InitDeclSpec (DeclSpec* D)
82 /* Initialize the DeclSpec struct for use */
91 static void InitDeclaration (Declaration* D)
92 /* Initialize the Declaration struct for use */
101 static void ParseStorageClass (DeclSpec* D, unsigned DefStorage)
102 /* Parse a storage class */
104 /* Assume we're using an explicit storage class */
105 D->Flags &= ~DS_DEF_STORAGE;
107 /* Check the storage class given */
111 D->StorageClass = SC_EXTERN | SC_STATIC;
116 D->StorageClass = SC_STATIC;
121 D->StorageClass = SC_REGISTER | SC_STATIC;
126 D->StorageClass = SC_AUTO;
131 D->StorageClass = SC_TYPEDEF;
136 /* No storage class given, use default */
137 D->Flags |= DS_DEF_STORAGE;
138 D->StorageClass = DefStorage;
145 static void ParseEnumDecl (void)
146 /* Process an enum declaration . */
151 /* Accept forward definitions */
152 if (curtok != LCURLY) {
156 /* Skip the opening curly brace */
159 /* Read the enum tags */
161 while (curtok != RCURLY) {
163 /* We expect an identifier */
164 if (curtok != IDENT) {
165 Error (ERR_IDENT_EXPECTED);
169 /* Remember the identifier and skip it */
170 strcpy (Ident, CurTok.Ident);
173 /* Check for an assigned value */
174 if (curtok == ASGN) {
178 EnumVal = lval.e_const;
181 /* Add an entry to the symbol table */
182 AddEnumSym (Ident, EnumVal++);
184 /* Check for end of definition */
194 static SymEntry* ParseStructDecl (const char* Name, type StructType)
195 /* Parse a struct/union declaration. */
204 if (curtok != LCURLY) {
205 /* Just a forward declaration. Try to find a struct with the given
206 * name. If there is none, insert a forward declaration into the
207 * current lexical level.
209 Entry = FindStructSym (Name);
210 if (Entry == 0 || Entry->Flags != SC_STRUCT) {
211 Entry = AddStructSym (Name, 0, 0);
216 /* Add a forward declaration for the struct in the current lexical level */
217 Entry = AddStructSym (Name, 0, 0);
219 /* Skip the curly brace */
222 /* Enter a new lexical level for the struct */
225 /* Parse struct fields */
227 while (curtok != RCURLY) {
229 /* Get the type of the entry */
231 InitDeclSpec (&Spec);
232 ParseTypeSpec (&Spec, -1);
234 /* Read fields with this type */
237 /* Get type and name of the struct field */
239 ParseDecl (&Spec, &Decl, 0);
241 /* Add a field entry to the table */
242 AddLocalSym (Decl.Ident, Decl.Type, SC_SFLD, (StructType == T_STRUCT)? Size : 0);
244 /* Calculate offset of next field/size of the union */
245 Offs = SizeOf (Decl.Type);
246 if (StructType == T_STRUCT) {
261 /* Skip the closing brace */
264 /* Remember the symbol table and leave the struct level */
265 FieldTab = GetSymTab ();
268 /* Make a real entry from the forward decl and return it */
269 return AddStructSym (Name, Size, FieldTab);
274 static void ParseTypeSpec (DeclSpec* D, int Default)
275 /* Parse a type specificier */
281 /* Assume have an explicit type */
282 D->Flags &= ~DS_DEF_TYPE;
284 /* Skip const or volatile modifiers if needed */
285 optional_modifiers ();
287 /* Look at the data type */
298 D->Type[0] = GetDefaultChar();
304 if (curtok == UNSIGNED) {
307 D->Type[0] = T_ULONG;
319 if (curtok == UNSIGNED) {
322 D->Type[0] = T_USHORT;
327 D->Type[0] = T_SHORT;
351 D->Type[0] = T_SHORT;
379 D->Type[0] = T_UCHAR;
386 D->Type[0] = T_USHORT;
393 D->Type[0] = T_ULONG;
410 StructType = (curtok == STRUCT)? T_STRUCT : T_UNION;
412 if (curtok == IDENT) {
413 strcpy (Ident, CurTok.Ident);
416 AnonName (Ident, (StructType == T_STRUCT)? "struct" : "union");
418 /* Declare the struct in the current scope */
419 Entry = ParseStructDecl (Ident, StructType);
420 /* Encode the struct entry into the type */
421 D->Type[0] = StructType;
422 EncodePtr (D->Type+1, Entry);
423 D->Type[DECODE_SIZE+1] = T_END;
428 if (curtok != LCURLY) {
430 Consume (IDENT, ERR_IDENT_EXPECTED);
438 Entry = FindSym (CurTok.Ident);
439 if (Entry && IsTypeDef (Entry)) {
442 TypeCpy (D->Type, Entry->Type);
449 Error (ERR_TYPE_EXPECTED);
453 D->Flags |= DS_DEF_TYPE;
454 D->Type[0] = (type) Default;
463 static FuncDesc* ParseFuncDecl (void)
464 /* Parse the argument list of a function. */
466 unsigned UnnamedCount = 0;
471 /* Create a new function descriptor */
472 FuncDesc* F = NewFuncDesc ();
474 /* Enter a new lexical level */
475 EnterFunctionLevel ();
477 /* Check for an empty or void parameter list */
478 if (curtok == RPAREN) {
479 /* Parameter list is empty */
480 F->Flags |= (FD_EMPTY | FD_ELLIPSIS);
481 } else if (curtok == VOID && nxttok == RPAREN) {
482 /* Parameter list declared as void */
484 F->Flags |= FD_VOID_PARAM;
488 while (curtok != RPAREN) {
493 /* Allow an ellipsis as last parameter */
494 if (curtok == ELLIPSIS) {
496 F->Flags |= FD_ELLIPSIS;
500 /* Read the declaration specifier */
501 ParseDeclSpec (&Spec, SC_AUTO, T_INT);
503 /* We accept only auto and register as storage class specifiers, but
504 * we ignore all this and use auto.
506 if ((Spec.StorageClass & SC_AUTO) == 0 &&
507 (Spec.StorageClass & SC_REGISTER) == 0) {
508 Error (ERR_ILLEGAL_STORAGE_CLASS);
510 Spec.StorageClass = SC_AUTO | SC_PARAM | SC_DEF;
512 /* Allow parameters without a name, but remember if we had some to
513 * eventually print an error message later.
515 ParseDecl (&Spec, &Decl, DM_ACCEPT_IDENT);
516 if (Decl.Ident[0] == '\0') {
518 /* Unnamed symbol. Generate a name that is not user accessible,
519 * then handle the symbol normal.
521 AnonName (Decl.Ident, "param");
524 /* Clear defined bit on nonames */
525 Spec.StorageClass &= ~SC_DEF;
528 /* If the parameter is an array, convert it to a pointer */
530 if (IsArray (Type)) {
535 /* Create a symbol table entry */
536 AddLocalSym (Decl.Ident, Type, Spec.StorageClass, 0);
538 /* Count arguments */
540 F->ParamSize += SizeOf (Type);
542 /* Check for more parameters */
543 if (curtok == COMMA) {
550 /* Skip right paren. We must explicitly check for one here, since some of
551 * the breaks above bail out without checking.
555 /* Assign offsets. If the function has a variable parameter list,
556 * there's one additional byte (the arg size).
558 Offs = (F->Flags & FD_ELLIPSIS)? 1 : 0;
559 Sym = GetSymTab()->SymTail;
562 Offs += SizeOf (Sym->Type);
566 /* Check if this is a function definition */
567 if (curtok == LCURLY) {
568 /* Print an error if in strict ANSI mode and we have unnamed
571 if (ANSI && UnnamedCount > 0) {
572 Error (ERR_MISSING_PARAM_NAME);
576 /* Leave the lexical level remembering the symbol tables */
577 RememberFunctionLevel (F);
579 /* Return the function descriptor */
585 static void Decl (Declaration* D, unsigned Mode)
586 /* Recursively process declarators. Build a type array in reverse order. */
588 if (curtok == STAR) {
590 /* Allow optional const or volatile modifiers */
591 optional_modifiers ();
595 } else if (curtok == LPAREN) {
599 } else if (curtok == FASTCALL) {
600 /* Remember the current type pointer */
602 /* Skip the fastcall token */
604 /* Parse the function */
606 /* Set the fastcall flag */
608 Error (ERR_ILLEGAL_MODIFIER);
610 FuncDesc* F = DecodePtr (T+1);
611 F->Flags |= FD_FASTCALL;
615 /* Things depend on Mode now:
616 * - Mode == DM_NEED_IDENT means:
617 * we *must* have a type and a variable identifer.
618 * - Mode == DM_NO_IDENT means:
619 * we must have a type but no variable identifer
620 * (if there is one, it's not read).
621 * - Mode == DM_ACCEPT_IDENT means:
622 * we *may* have an identifier. If there is an identifier,
623 * it is read, but it is no error, if there is none.
625 if (Mode == DM_NO_IDENT) {
627 } else if (curtok == IDENT) {
628 strcpy (D->Ident, CurTok.Ident);
631 if (Mode == DM_NEED_IDENT) {
632 Error (ERR_IDENT_EXPECTED);
639 while (curtok == LBRACK || curtok == LPAREN) {
640 if (curtok == LPAREN) {
641 /* Function declaration */
644 /* Parse the function declaration */
645 F = ParseFuncDecl ();
650 /* Array declaration */
651 unsigned long Size = 0;
653 /* Read the size if it is given */
654 if (curtok != RBRACK) {
669 /*****************************************************************************/
671 /*****************************************************************************/
675 type* ParseType (type* Type)
676 /* Parse a complete type specification */
681 /* Get a type without a default */
682 InitDeclSpec (&Spec);
683 ParseTypeSpec (&Spec, -1);
685 /* Parse additional declarators */
686 InitDeclaration (&Decl);
687 ParseDecl (&Spec, &Decl, DM_NO_IDENT);
689 /* Copy the type to the target buffer */
690 TypeCpy (Type, Decl.Type);
692 /* Return a pointer to the target buffer */
698 void ParseDecl (const DeclSpec* Spec, Declaration* D, unsigned Mode)
699 /* Parse a variable, type or function declaration */
701 /* Initialize the Declaration struct */
704 /* Get additional declarators and the identifier */
707 /* Add the base type. */
708 TypeCpy (D->T, Spec->Type);
710 /* Check the size of the generated type */
711 if (!IsFunc (D->Type) && SizeOf (D->Type) >= 0x10000) {
712 Error (ERR_ILLEGAL_SIZE);
718 void ParseDeclSpec (DeclSpec* D, unsigned DefStorage, int DefType)
719 /* Parse a declaration specification */
721 /* Initialize the DeclSpec struct */
724 /* First, get the storage class specifier for this declaration */
725 ParseStorageClass (D, DefStorage);
727 /* Parse the type specifiers */
728 ParseTypeSpec (D, DefType);
733 static void ParseVoidInit (void)
734 /* Parse an initialization of a void variable (special cc65 extension) */
738 /* Allow an arbitrary list of values */
742 switch (lval.e_tptr[0]) {
746 if ((lval.e_flags & E_MCTYPE) == E_TCONST) {
747 /* Make it byte sized */
748 lval.e_const &= 0xFF;
759 if ((lval.e_flags & E_MCTYPE) == E_TCONST) {
760 /* Make it word sized */
761 lval.e_const &= 0xFFFF;
772 Error (ERR_ILLEGAL_TYPE);
777 if (curtok != COMMA) {
782 } while (curtok != RCURLY);
789 static void ParseStructInit (type* Type)
790 /* Parse initialization of a struct or union */
795 /* Consume the opening curly brace */
798 /* Get a pointer to the struct entry from the type */
799 Entry = (SymEntry*) Decode (Type + 1);
801 /* Check if this struct definition has a field table. If it doesn't, it
802 * is an incomplete definition.
804 Tab = Entry->V.S.SymTab;
806 Error (ERR_INIT_INCOMPLETE_TYPE);
807 /* Returning here will cause lots of errors, but recovery is difficult */
811 /* Get a pointer to the list of symbols */
812 Entry = Tab->SymHead;
813 while (curtok != RCURLY) {
815 Error (ERR_TOO_MANY_INITIALIZERS);
818 ParseInit (Entry->Type);
819 Entry = Entry->NextSym;
825 /* Consume the closing curly brace */
828 /* If there are struct fields left, reserve additional storage */
830 g_zerobytes (SizeOf (Entry->Type));
831 Entry = Entry->NextSym;
839 void ParseInit (type *tptr)
840 /* Parse initialization of variables */
853 if ((lval.e_flags & E_MCTYPE) == E_TCONST) {
854 /* Make it byte sized */
855 lval.e_const &= 0xFF;
857 assignadjust (tptr, &lval);
867 if ((lval.e_flags & E_MCTYPE) == E_TCONST) {
868 /* Make it word sized */
869 lval.e_const &= 0xFFFF;
871 assignadjust (tptr, &lval);
878 if ((lval.e_flags & E_MCTYPE) == E_TCONST) {
879 /* Make it long sized */
880 lval.e_const &= 0xFFFFFFFF;
882 assignadjust (tptr, &lval);
887 sz = Decode (tptr + 1);
888 t = tptr + DECODE_SIZE + 1;
889 if ((t [0] == T_CHAR || t [0] == T_UCHAR) && curtok == SCONST) {
890 str = GetLiteral (curval);
891 count = strlen (str) + 1;
892 TranslateLiteralPool (curval); /* Translate into target charset */
893 g_defbytes (str, count);
894 ResetLiteralOffs (curval); /* Remove string from pool */
899 while (curtok != RCURLY) {
900 ParseInit (tptr + DECODE_SIZE + 1);
909 Encode (tptr + 1, count);
910 } else if (count < sz) {
911 g_zerobytes ((sz - count) * SizeOf (tptr + DECODE_SIZE + 1));
912 } else if (count > sz) {
913 Error (ERR_TOO_MANY_INITIALIZERS);
919 ParseStructInit (tptr);
924 /* Special cc65 extension in non ANSI mode */
931 Error (ERR_ILLEGAL_TYPE);