]> git.sur5r.net Git - cc65/blob - src/cc65/declare.c
Separate the functions that parse unions and structs, because they became too
[cc65] / src / cc65 / declare.c
1 /*****************************************************************************/
2 /*                                                                           */
3 /*                                 declare.c                                 */
4 /*                                                                           */
5 /*                 Parse variable and function declarations                  */
6 /*                                                                           */
7 /*                                                                           */
8 /*                                                                           */
9 /* (C) 1998-2008 Ullrich von Bassewitz                                       */
10 /*               Roemerstrasse 52                                            */
11 /*               D-70794 Filderstadt                                         */
12 /* EMail:        uz@cc65.org                                                 */
13 /*                                                                           */
14 /*                                                                           */
15 /* This software is provided 'as-is', without any expressed or implied       */
16 /* warranty.  In no event will the authors be held liable for any damages    */
17 /* arising from the use of this software.                                    */
18 /*                                                                           */
19 /* Permission is granted to anyone to use this software for any purpose,     */
20 /* including commercial applications, and to alter it and redistribute it    */
21 /* freely, subject to the following restrictions:                            */
22 /*                                                                           */
23 /* 1. The origin of this software must not be misrepresented; you must not   */
24 /*    claim that you wrote the original software. If you use this software   */
25 /*    in a product, an acknowledgment in the product documentation would be  */
26 /*    appreciated but is not required.                                       */
27 /* 2. Altered source versions must be plainly marked as such, and must not   */
28 /*    be misrepresented as being the original software.                      */
29 /* 3. This notice may not be removed or altered from any source              */
30 /*    distribution.                                                          */
31 /*                                                                           */
32 /*****************************************************************************/
33
34
35
36 #include <stdio.h>
37 #include <string.h>
38 #include <errno.h>
39
40 /* common */
41 #include "addrsize.h"
42 #include "mmodel.h"
43 #include "xmalloc.h"
44
45 /* cc65 */
46 #include "anonname.h"
47 #include "codegen.h"
48 #include "datatype.h"
49 #include "declare.h"
50 #include "declattr.h"
51 #include "error.h"
52 #include "expr.h"
53 #include "funcdesc.h"
54 #include "function.h"
55 #include "global.h"
56 #include "litpool.h"
57 #include "pragma.h"
58 #include "scanner.h"
59 #include "standard.h"
60 #include "symtab.h"
61 #include "typeconv.h"
62
63
64
65 /*****************************************************************************/
66 /*                                 Forwards                                  */
67 /*****************************************************************************/
68
69
70
71 static void ParseTypeSpec (DeclSpec* D, long Default, TypeCode Qualifiers);
72 /* Parse a type specificier */
73
74 static unsigned ParseInitInternal (Type* T, int AllowFlexibleMembers);
75 /* Parse initialization of variables. Return the number of data bytes. */
76
77
78
79 /*****************************************************************************/
80 /*                            internal functions                             */
81 /*****************************************************************************/
82
83
84
85 static void DuplicateQualifier (const char* Name)
86 /* Print an error message */
87 {
88     Warning ("Duplicate qualifier: `%s'", Name);
89 }
90
91
92
93 static TypeCode OptionalQualifiers (TypeCode Allowed)
94 /* Read type qualifiers if we have any. Allowed specifies the allowed
95  * qualifiers.
96  */
97 {
98     /* We start without any qualifiers */
99     TypeCode Q = T_QUAL_NONE;
100
101     /* Check for more qualifiers */
102     while (1) {
103
104         switch (CurTok.Tok) {
105
106             case TOK_CONST:
107                 if (Allowed & T_QUAL_CONST) {
108                     if (Q & T_QUAL_CONST) {
109                         DuplicateQualifier ("const");
110                     }
111                     Q |= T_QUAL_CONST;
112                 } else {
113                     goto Done;
114                 }
115                 break;
116
117             case TOK_VOLATILE:
118                 if (Allowed & T_QUAL_VOLATILE) {
119                     if (Q & T_QUAL_VOLATILE) {
120                         DuplicateQualifier ("volatile");
121                     }
122                     Q |= T_QUAL_VOLATILE;
123                 } else {
124                     goto Done;
125                 }
126                 break;
127
128             case TOK_RESTRICT:
129                 if (Allowed & T_QUAL_RESTRICT) {
130                     if (Q & T_QUAL_RESTRICT) {
131                         DuplicateQualifier ("restrict");
132                     }
133                     Q |= T_QUAL_RESTRICT;
134                 } else {
135                     goto Done;
136                 }
137                 break;
138
139             case TOK_NEAR:
140                 if (Allowed & T_QUAL_NEAR) {
141                     if (Q & T_QUAL_NEAR) {
142                         DuplicateQualifier ("near");
143                     }
144                     Q |= T_QUAL_NEAR;
145                 } else {
146                     goto Done;
147                 }
148                 break;
149
150             case TOK_FAR:
151                 if (Allowed & T_QUAL_FAR) {
152                     if (Q & T_QUAL_FAR) {
153                         DuplicateQualifier ("far");
154                     }
155                     Q |= T_QUAL_FAR;
156                 } else {
157                     goto Done;
158                 }
159                 break;
160
161             case TOK_FASTCALL:
162                 if (Allowed & T_QUAL_FASTCALL) {
163                     if (Q & T_QUAL_FASTCALL) {
164                         DuplicateQualifier ("fastcall");
165                     }
166                     Q |= T_QUAL_FASTCALL;
167                 } else {
168                     goto Done;
169                 }
170                 break;
171
172             default:
173                 goto Done;
174
175         }
176
177         /* Skip the token */
178         NextToken ();
179     }
180
181 Done:
182     /* We cannot have more than one address size far qualifier */
183     switch (Q & T_QUAL_ADDRSIZE) {
184
185         case T_QUAL_NONE:
186         case T_QUAL_NEAR:
187         case T_QUAL_FAR:
188             break;
189
190         default:
191             Error ("Cannot specify more than one address size qualifier");
192             Q &= ~T_QUAL_ADDRSIZE;
193     }
194
195     /* Return the qualifiers read */
196     return Q;
197 }
198
199
200
201 static void OptionalInt (void)
202 /* Eat an optional "int" token */
203 {
204     if (CurTok.Tok == TOK_INT) {
205         /* Skip it */
206         NextToken ();
207     }
208 }
209
210
211
212 static void OptionalSigned (void)
213 /* Eat an optional "signed" token */
214 {
215     if (CurTok.Tok == TOK_SIGNED) {
216         /* Skip it */
217         NextToken ();
218     }
219 }
220
221
222
223 static void InitDeclSpec (DeclSpec* D)
224 /* Initialize the DeclSpec struct for use */
225 {
226     D->StorageClass     = 0;
227     D->Type[0].C        = T_END;
228     D->Flags            = 0;
229 }
230
231
232
233 static void InitDeclaration (Declaration* D)
234 /* Initialize the Declaration struct for use */
235 {
236     D->Ident[0]  = '\0';
237     D->Type[0].C = T_END;
238     D->Index     = 0;
239 }
240
241
242
243 static void NeedTypeSpace (Declaration* D, unsigned Count)
244 /* Check if there is enough space for Count type specifiers within D */
245 {
246     if (D->Index + Count >= MAXTYPELEN) {
247         /* We must call Fatal() here, since calling Error() will try to
248          * continue, and the declaration type is not correctly terminated
249          * in case we come here.
250          */
251         Fatal ("Too many type specifiers");
252     }
253 }
254
255
256
257 static void AddTypeToDeclaration (Declaration* D, TypeCode T)
258 /* Add a type specifier to the type of a declaration */
259 {
260     NeedTypeSpace (D, 1);
261     D->Type[D->Index++].C = T;
262 }
263
264
265
266 static void FixQualifiers (Type* DataType)
267 /* Apply several fixes to qualifiers */
268 {
269     Type*    T;
270     TypeCode Q;
271
272     /* Using typedefs, it is possible to generate declarations that have
273      * type qualifiers attached to an array, not the element type. Go and
274      * fix these here.
275      */
276     T = DataType;
277     Q = T_QUAL_NONE;
278     while (T->C != T_END) {
279         if (IsTypeArray (T)) {
280             /* Extract any type qualifiers */
281             Q |= T->C & T_MASK_QUAL;
282             T->C = UnqualifiedType (T->C);
283         } else {
284             /* Add extracted type qualifiers here */
285             T->C |= Q;
286             Q = T_QUAL_NONE;
287         }
288         ++T;
289     }
290     /* Q must be empty now */
291     CHECK (Q == T_QUAL_NONE);
292
293     /* Do some fixes on pointers and functions. */
294     T = DataType;
295     while (T->C != T_END) {
296         if (IsTypePtr (T)) {
297
298             /* Fastcall qualifier on the pointer? */
299             if (IsQualFastcall (T)) {
300                 /* Pointer to function which is not fastcall? */
301                 if (IsTypeFunc (T+1) && !IsQualFastcall (T+1)) {
302                     /* Move the fastcall qualifier from the pointer to
303                      * the function.
304                      */
305                     T[0].C &= ~T_QUAL_FASTCALL;
306                     T[1].C |= T_QUAL_FASTCALL;
307                 } else {
308                     Error ("Invalid `_fastcall__' qualifier for pointer");
309                 }
310             }
311
312             /* Apply the default far and near qualifiers if none are given */
313             Q = (T[0].C & T_QUAL_ADDRSIZE);
314             if (Q == T_QUAL_NONE) {
315                 /* No address size qualifiers specified */
316                 if (IsTypeFunc (T+1)) {
317                     /* Pointer to function. Use the qualifier from the function
318                      * or the default if the function don't has one.
319                      */
320                     Q = (T[1].C & T_QUAL_ADDRSIZE);
321                     if (Q == T_QUAL_NONE) {
322                         Q = CodeAddrSizeQualifier ();
323                     }
324                 } else {
325                     Q = DataAddrSizeQualifier ();
326                 }
327                 T[0].C |= Q;
328             } else {
329                 /* We have address size qualifiers. If followed by a function,
330                  * apply these also to the function.
331                  */
332                 if (IsTypeFunc (T+1)) {
333                     TypeCode FQ = (T[1].C & T_QUAL_ADDRSIZE);
334                     if (FQ == T_QUAL_NONE) {
335                         T[1].C |= Q;
336                     } else if (FQ != Q) {
337                         Error ("Address size qualifier mismatch");
338                         T[1].C = (T[1].C & ~T_QUAL_ADDRSIZE) | Q;
339                     }
340                 }
341             }
342
343         } else if (IsTypeFunc (T)) {
344
345             /* Apply the default far and near qualifiers if none are given */
346             if ((T[0].C & T_QUAL_ADDRSIZE) == 0) {
347                 T[0].C |= CodeAddrSizeQualifier ();
348             }
349
350         }
351         ++T;
352     }
353 }
354
355
356
357 static void ParseStorageClass (DeclSpec* D, unsigned DefStorage)
358 /* Parse a storage class */
359 {
360     /* Assume we're using an explicit storage class */
361     D->Flags &= ~DS_DEF_STORAGE;
362
363     /* Check the storage class given */
364     switch (CurTok.Tok) {
365
366         case TOK_EXTERN:
367             D->StorageClass = SC_EXTERN | SC_STATIC;
368             NextToken ();
369             break;
370
371         case TOK_STATIC:
372             D->StorageClass = SC_STATIC;
373             NextToken ();
374             break;
375
376         case TOK_REGISTER:
377             D->StorageClass = SC_REGISTER | SC_STATIC;
378             NextToken ();
379             break;
380
381         case TOK_AUTO:
382             D->StorageClass = SC_AUTO;
383             NextToken ();
384             break;
385
386         case TOK_TYPEDEF:
387             D->StorageClass = SC_TYPEDEF;
388             NextToken ();
389             break;
390
391         default:
392             /* No storage class given, use default */
393             D->Flags |= DS_DEF_STORAGE;
394             D->StorageClass = DefStorage;
395             break;
396     }
397 }
398
399
400
401 static void ParseEnumDecl (void)
402 /* Process an enum declaration . */
403 {
404     int EnumVal;
405     ident Ident;
406
407     /* Accept forward definitions */
408     if (CurTok.Tok != TOK_LCURLY) {
409         return;
410     }
411
412     /* Skip the opening curly brace */
413     NextToken ();
414
415     /* Read the enum tags */
416     EnumVal = 0;
417     while (CurTok.Tok != TOK_RCURLY) {
418
419         /* We expect an identifier */
420         if (CurTok.Tok != TOK_IDENT) {
421             Error ("Identifier expected");
422             continue;
423         }
424
425         /* Remember the identifier and skip it */
426         strcpy (Ident, CurTok.Ident);
427         NextToken ();
428
429         /* Check for an assigned value */
430         if (CurTok.Tok == TOK_ASSIGN) {
431             ExprDesc Expr;
432             NextToken ();
433             ConstAbsIntExpr (hie1, &Expr);
434             EnumVal = Expr.IVal;
435         }
436
437         /* Add an entry to the symbol table */
438         AddConstSym (Ident, type_int, SC_ENUM, EnumVal++);
439
440         /* Check for end of definition */
441         if (CurTok.Tok != TOK_COMMA)
442             break;
443         NextToken ();
444     }
445     ConsumeRCurly ();
446 }
447
448
449
450 static int ParseFieldWidth (Declaration* Decl)
451 /* Parse an optional field width. Returns -1 if no field width is speficied,
452  * otherwise the width of the field.
453  */
454 {
455     ExprDesc Expr;
456
457     if (CurTok.Tok != TOK_COLON) {
458         /* No bit-field declaration */
459         return -1;
460     }
461
462     /* Read the width */
463     NextToken ();
464     ConstAbsIntExpr (hie1, &Expr);
465     if (Expr.IVal < 0) {
466         Error ("Negative width in bit-field");
467         return -1;
468     }
469     if (Expr.IVal > INT_BITS) {
470         Error ("Width of bit-field exceeds its type");
471         return -1;
472     }
473     if (Expr.IVal == 0 && Decl->Ident[0] != '\0') {
474         Error ("Zero width for named bit-field");
475         return -1;
476     }
477     if (!IsTypeInt (Decl->Type)) {
478         /* Only integer types may be used for bit-fields */
479         Error ("Bit-field has invalid type");
480         return -1;
481     }
482
483     /* Return the field width */
484     return (int) Expr.IVal;
485 }
486
487
488
489 static SymEntry* StructOrUnionForwardDecl (const char* Name)
490 /* Handle a struct or union forward decl */
491 {
492     /* Try to find a struct with the given name. If there is none,
493      * insert a forward declaration into the current lexical level.
494      */
495     SymEntry* Entry = FindTagSym (Name);
496     if (Entry == 0) {
497         Entry = AddStructSym (Name, 0, 0);
498     } else if (SymIsLocal (Entry) && (Entry->Flags & SC_STRUCT) != SC_STRUCT) {
499         /* Already defined in the level, but no struct */
500         Error ("Symbol `%s' is already different kind", Name);
501     }
502     return Entry;
503 }
504
505
506
507 static SymEntry* ParseUnionDecl (const char* Name)
508 /* Parse a union declaration. */
509 {
510
511     unsigned  UnionSize;
512     unsigned  FieldSize;
513     int       FieldWidth;       /* Width in bits, -1 if not a bit-field */
514     SymTable* FieldTab;
515     SymEntry* Entry;
516
517
518     if (CurTok.Tok != TOK_LCURLY) {
519         /* Just a forward declaration. */
520         return StructOrUnionForwardDecl (Name);
521     }
522
523     /* Add a forward declaration for the struct in the current lexical level */
524     Entry = AddStructSym (Name, 0, 0);
525
526     /* Skip the curly brace */
527     NextToken ();
528
529     /* Enter a new lexical level for the struct */
530     EnterStructLevel ();
531
532     /* Parse union fields */
533     UnionSize      = 0;
534     while (CurTok.Tok != TOK_RCURLY) {
535
536         /* Get the type of the entry */
537         DeclSpec Spec;
538         InitDeclSpec (&Spec);
539         ParseTypeSpec (&Spec, -1, T_QUAL_NONE);
540
541         /* Read fields with this type */
542         while (1) {
543
544             Declaration Decl;
545
546             /* Get type and name of the struct field */
547             ParseDecl (&Spec, &Decl, DM_ACCEPT_IDENT);
548
549             /* Check for a bit-field declaration */
550             FieldWidth = ParseFieldWidth (&Decl);
551
552             /* Ignore zero sized bit fields in a union */
553             if (FieldWidth == 0) {
554                 goto NextMember;
555             }
556
557             /* Check for fields without a name */
558             if (Decl.Ident[0] == '\0') {
559                 if (FieldWidth < 0) {
560                     /* A non bit-field without a name is legal but useless */
561                     Warning ("Declaration does not declare anything");
562                     goto NextMember;
563                 } else {
564                     /* A bit-field without a name does nothing in a union */
565                     goto NextMember;
566                 }
567             }
568
569             /* Handle sizes */
570             FieldSize = CheckedSizeOf (Decl.Type);
571             if (FieldSize > UnionSize) {
572                 UnionSize = FieldSize;
573             }
574
575             /* Add a field entry to the table */
576             if (FieldWidth > 0) {
577                 AddBitField (Decl.Ident, 0, 0, FieldWidth);
578             } else {
579                 AddLocalSym (Decl.Ident, Decl.Type, SC_STRUCTFIELD, 0);
580             }
581
582 NextMember: if (CurTok.Tok != TOK_COMMA) {
583                 break;
584             }
585             NextToken ();
586         }
587         ConsumeSemi ();
588     }
589
590     /* Skip the closing brace */
591     NextToken ();
592
593     /* Remember the symbol table and leave the struct level */
594     FieldTab = GetSymTab ();
595     LeaveStructLevel ();
596
597     /* Make a real entry from the forward decl and return it */
598     return AddStructSym (Name, UnionSize, FieldTab);
599 }
600
601
602
603 static SymEntry* ParseStructDecl (const char* Name)
604 /* Parse a struct declaration. */
605 {
606
607     unsigned  StructSize;
608     int       FlexibleMember;
609     unsigned  Offs;
610     int       BitOffs;          /* Bit offset for bit-fields */
611     int       FieldWidth;       /* Width in bits, -1 if not a bit-field */
612     SymTable* FieldTab;
613     SymEntry* Entry;
614
615
616     if (CurTok.Tok != TOK_LCURLY) {
617         /* Just a forward declaration. */
618         return StructOrUnionForwardDecl (Name);
619     }
620
621     /* Add a forward declaration for the struct in the current lexical level */
622     Entry = AddStructSym (Name, 0, 0);
623
624     /* Skip the curly brace */
625     NextToken ();
626
627     /* Enter a new lexical level for the struct */
628     EnterStructLevel ();
629
630     /* Parse struct fields */
631     FlexibleMember = 0;
632     StructSize     = 0;
633     BitOffs        = 0;
634     while (CurTok.Tok != TOK_RCURLY) {
635
636         /* Get the type of the entry */
637         DeclSpec Spec;
638         InitDeclSpec (&Spec);
639         ParseTypeSpec (&Spec, -1, T_QUAL_NONE);
640
641         /* Read fields with this type */
642         while (1) {
643
644             Declaration Decl;
645
646             /* If we had a flexible array member before, no other fields can
647              * follow.
648              */
649             if (FlexibleMember) {
650                 Error ("Flexible array member must be last field");
651                 FlexibleMember = 0;     /* Avoid further errors */
652             }
653
654             /* Get type and name of the struct field */
655             ParseDecl (&Spec, &Decl, DM_ACCEPT_IDENT);
656
657             /* Check for a bit-field declaration */
658             FieldWidth = ParseFieldWidth (&Decl);
659
660             /* If this is not a bit field, or the bit field is too large for
661              * the remainder of the current member, or we have a bit field
662              * with width zero, align the struct to the next member
663              */
664             if (BitOffs > 0) {
665                 if (FieldWidth <= 0 || (BitOffs + FieldWidth) > INT_BITS) {
666                     StructSize += SIZEOF_INT;
667                     BitOffs = 0;
668                 }
669             }
670
671             /* Apart from the above, a bit field with width 0 is not processed
672              * further.
673              */
674             if (FieldWidth == 0) {
675                 goto NextMember;
676             }
677
678             /* Check for fields without names */
679             if (Decl.Ident[0] == '\0') {
680                 if (FieldWidth < 0) {
681                     /* A non bit-field without a name is legal but useless */
682                     Warning ("Declaration does not declare anything");
683                     goto NextMember;
684                 } else {
685                     /* A bit-field without a name will just increase the
686                      * offset
687                      */
688                     BitOffs += FieldWidth;
689                     goto NextMember;
690                 }
691             }
692
693             /* Byte offset of this member is the current struct size plus any
694              * full bytes from the bit offset in case of bit-fields.
695              */
696             Offs = StructSize + (BitOffs >> 3);
697
698             /* Check if this field is a flexible array member, and
699              * calculate the size of the field.
700              */
701             if (IsTypeArray (Decl.Type) && GetElementCount (Decl.Type) == UNSPECIFIED) {
702                 /* Array with unspecified size */
703                 if (StructSize == 0) {
704                     Error ("Flexible array member cannot be first struct field");
705                 }
706                 FlexibleMember = 1;
707                 /* Assume zero for size calculations */
708                 SetElementCount (Decl.Type, FLEXIBLE);
709             } else if (FieldWidth < 0) {
710                 StructSize += CheckedSizeOf (Decl.Type);
711             }
712
713             /* Add a field entry to the table */
714             if (FieldWidth > 0) {
715                 AddBitField (Decl.Ident, Offs, BitOffs & 0x07, FieldWidth);
716                 BitOffs += FieldWidth;
717             } else {
718                 AddLocalSym (Decl.Ident, Decl.Type, SC_STRUCTFIELD, Offs);
719             }
720
721 NextMember: if (CurTok.Tok != TOK_COMMA) {
722                 break;
723             }
724             NextToken ();
725         }
726         ConsumeSemi ();
727     }
728
729     /* If we have bits from bit-fields left, add them to the size. */
730     if (BitOffs > 0) {
731         StructSize += ((BitOffs + CHAR_BITS - 1) >> 3);
732     }
733
734     /* Skip the closing brace */
735     NextToken ();
736
737     /* Remember the symbol table and leave the struct level */
738     FieldTab = GetSymTab ();
739     LeaveStructLevel ();
740
741     /* Make a real entry from the forward decl and return it */
742     return AddStructSym (Name, StructSize, FieldTab);
743 }
744
745
746
747 static void ParseTypeSpec (DeclSpec* D, long Default, TypeCode Qualifiers)
748 /* Parse a type specificier */
749 {
750     ident       Ident;
751     SymEntry*   Entry;
752
753     /* Assume we have an explicit type */
754     D->Flags &= ~DS_DEF_TYPE;
755
756     /* Read type qualifiers if we have any */
757     Qualifiers |= OptionalQualifiers (T_QUAL_CONST | T_QUAL_VOLATILE);
758
759     /* Look at the data type */
760     switch (CurTok.Tok) {
761
762         case TOK_VOID:
763             NextToken ();
764             D->Type[0].C = T_VOID;
765             D->Type[1].C = T_END;
766             break;
767
768         case TOK_CHAR:
769             NextToken ();
770             D->Type[0].C = GetDefaultChar();
771             D->Type[1].C = T_END;
772             break;
773
774         case TOK_LONG:
775             NextToken ();
776             if (CurTok.Tok == TOK_UNSIGNED) {
777                 NextToken ();
778                 OptionalInt ();
779                 D->Type[0].C = T_ULONG;
780                 D->Type[1].C = T_END;
781             } else {
782                 OptionalSigned ();
783                 OptionalInt ();
784                 D->Type[0].C = T_LONG;
785                 D->Type[1].C = T_END;
786             }
787             break;
788
789         case TOK_SHORT:
790             NextToken ();
791             if (CurTok.Tok == TOK_UNSIGNED) {
792                 NextToken ();
793                 OptionalInt ();
794                 D->Type[0].C = T_USHORT;
795                 D->Type[1].C = T_END;
796             } else {
797                 OptionalSigned ();
798                 OptionalInt ();
799                 D->Type[0].C = T_SHORT;
800                 D->Type[1].C = T_END;
801             }
802             break;
803
804         case TOK_INT:
805             NextToken ();
806             D->Type[0].C = T_INT;
807             D->Type[1].C = T_END;
808             break;
809
810        case TOK_SIGNED:
811             NextToken ();
812             switch (CurTok.Tok) {
813
814                 case TOK_CHAR:
815                     NextToken ();
816                     D->Type[0].C = T_SCHAR;
817                     D->Type[1].C = T_END;
818                     break;
819
820                 case TOK_SHORT:
821                     NextToken ();
822                     OptionalInt ();
823                     D->Type[0].C = T_SHORT;
824                     D->Type[1].C = T_END;
825                     break;
826
827                 case TOK_LONG:
828                     NextToken ();
829                     OptionalInt ();
830                     D->Type[0].C = T_LONG;
831                     D->Type[1].C = T_END;
832                     break;
833
834                 case TOK_INT:
835                     NextToken ();
836                     /* FALL THROUGH */
837
838                 default:
839                     D->Type[0].C = T_INT;
840                     D->Type[1].C = T_END;
841                     break;
842             }
843             break;
844
845         case TOK_UNSIGNED:
846             NextToken ();
847             switch (CurTok.Tok) {
848
849                 case TOK_CHAR:
850                     NextToken ();
851                     D->Type[0].C = T_UCHAR;
852                     D->Type[1].C = T_END;
853                     break;
854
855                 case TOK_SHORT:
856                     NextToken ();
857                     OptionalInt ();
858                     D->Type[0].C = T_USHORT;
859                     D->Type[1].C = T_END;
860                     break;
861
862                 case TOK_LONG:
863                     NextToken ();
864                     OptionalInt ();
865                     D->Type[0].C = T_ULONG;
866                     D->Type[1].C = T_END;
867                     break;
868
869                 case TOK_INT:
870                     NextToken ();
871                     /* FALL THROUGH */
872
873                 default:
874                     D->Type[0].C = T_UINT;
875                     D->Type[1].C = T_END;
876                     break;
877             }
878             break;
879
880         case TOK_FLOAT:
881             NextToken ();
882             D->Type[0].C = T_FLOAT;
883             D->Type[1].C = T_END;
884             break;
885
886         case TOK_DOUBLE:
887             NextToken ();
888             D->Type[0].C = T_DOUBLE;
889             D->Type[1].C = T_END;
890             break;
891
892         case TOK_UNION:
893             NextToken ();
894             /* */
895             if (CurTok.Tok == TOK_IDENT) {
896                 strcpy (Ident, CurTok.Ident);
897                 NextToken ();
898             } else {
899                 AnonName (Ident, "union");
900             }
901             /* Remember we have an extra type decl */
902             D->Flags |= DS_EXTRA_TYPE;
903             /* Declare the union in the current scope */
904             Entry = ParseUnionDecl (Ident);
905             /* Encode the union entry into the type */
906             D->Type[0].C = T_UNION;
907             SetSymEntry (D->Type, Entry);
908             D->Type[1].C = T_END;
909             break;
910
911         case TOK_STRUCT:
912             NextToken ();
913             /* */
914             if (CurTok.Tok == TOK_IDENT) {
915                 strcpy (Ident, CurTok.Ident);
916                 NextToken ();
917             } else {
918                 AnonName (Ident, "struct");
919             }
920             /* Remember we have an extra type decl */
921             D->Flags |= DS_EXTRA_TYPE;
922             /* Declare the struct in the current scope */
923             Entry = ParseStructDecl (Ident);
924             /* Encode the struct entry into the type */
925             D->Type[0].C = T_STRUCT;
926             SetSymEntry (D->Type, Entry);
927             D->Type[1].C = T_END;
928             break;
929
930         case TOK_ENUM:
931             NextToken ();
932             if (CurTok.Tok != TOK_LCURLY) {
933                 /* Named enum */
934                 if (CurTok.Tok == TOK_IDENT) {
935                     /* Find an entry with this name */
936                     Entry = FindTagSym (CurTok.Ident);
937                     if (Entry) {
938                         if (SymIsLocal (Entry) && (Entry->Flags & SC_ENUM) == 0) {
939                             Error ("Symbol `%s' is already different kind", Entry->Name);
940                         }
941                     } else {
942                         /* Insert entry into table ### */
943                     }
944                     /* Skip the identifier */
945                     NextToken ();
946                 } else {
947                     Error ("Identifier expected");
948                 }
949             }
950             /* Remember we have an extra type decl */
951             D->Flags |= DS_EXTRA_TYPE;
952             /* Parse the enum decl */
953             ParseEnumDecl ();
954             D->Type[0].C = T_INT;
955             D->Type[1].C = T_END;
956             break;
957
958         case TOK_IDENT:
959             Entry = FindSym (CurTok.Ident);
960             if (Entry && SymIsTypeDef (Entry)) {
961                 /* It's a typedef */
962                 NextToken ();
963                 TypeCopy (D->Type, Entry->Type);
964                 break;
965             }
966             /* FALL THROUGH */
967
968         default:
969             if (Default < 0) {
970                 Error ("Type expected");
971                 D->Type[0].C = T_INT;
972                 D->Type[1].C = T_END;
973             } else {
974                 D->Flags |= DS_DEF_TYPE;
975                 D->Type[0].C = (TypeCode) Default;
976                 D->Type[1].C = T_END;
977             }
978             break;
979     }
980
981     /* There may also be qualifiers *after* the initial type */
982     D->Type[0].C |= (Qualifiers | OptionalQualifiers (T_QUAL_CONST | T_QUAL_VOLATILE));
983 }
984
985
986
987 static Type* ParamTypeCvt (Type* T)
988 /* If T is an array, convert it to a pointer else do nothing. Return the
989  * resulting type.
990  */
991 {
992     if (IsTypeArray (T)) {
993         T->C = T_PTR;
994     }
995     return T;
996 }
997
998
999
1000 static void ParseOldStyleParamList (FuncDesc* F)
1001 /* Parse an old style (K&R) parameter list */
1002 {
1003     /* Parse params */
1004     while (CurTok.Tok != TOK_RPAREN) {
1005
1006         /* List of identifiers expected */
1007         if (CurTok.Tok != TOK_IDENT) {
1008             Error ("Identifier expected");
1009         }
1010
1011         /* Create a symbol table entry with type int */
1012         AddLocalSym (CurTok.Ident, type_int, SC_AUTO | SC_PARAM | SC_DEF | SC_DEFTYPE, 0);
1013
1014         /* Count arguments */
1015         ++F->ParamCount;
1016
1017         /* Skip the identifier */
1018         NextToken ();
1019
1020         /* Check for more parameters */
1021         if (CurTok.Tok == TOK_COMMA) {
1022             NextToken ();
1023         } else {
1024             break;
1025         }
1026     }
1027
1028     /* Skip right paren. We must explicitly check for one here, since some of
1029      * the breaks above bail out without checking.
1030      */
1031     ConsumeRParen ();
1032
1033     /* An optional list of type specifications follows */
1034     while (CurTok.Tok != TOK_LCURLY) {
1035
1036         DeclSpec        Spec;
1037
1038         /* Read the declaration specifier */
1039         ParseDeclSpec (&Spec, SC_AUTO, T_INT);
1040
1041         /* We accept only auto and register as storage class specifiers, but
1042          * we ignore all this, since we use auto anyway.
1043          */
1044         if ((Spec.StorageClass & SC_AUTO) == 0 &&
1045             (Spec.StorageClass & SC_REGISTER) == 0) {
1046             Error ("Illegal storage class");
1047         }
1048
1049         /* Parse a comma separated variable list */
1050         while (1) {
1051
1052             Declaration         Decl;
1053
1054             /* Read the parameter */
1055             ParseDecl (&Spec, &Decl, DM_NEED_IDENT);
1056             if (Decl.Ident[0] != '\0') {
1057
1058                 /* We have a name given. Search for the symbol */
1059                 SymEntry* Sym = FindLocalSym (Decl.Ident);
1060                 if (Sym) {
1061                     /* Check if we already changed the type for this
1062                      * parameter
1063                      */
1064                     if (Sym->Flags & SC_DEFTYPE) {
1065                         /* Found it, change the default type to the one given */
1066                         ChangeSymType (Sym, ParamTypeCvt (Decl.Type));
1067                         /* Reset the "default type" flag */
1068                         Sym->Flags &= ~SC_DEFTYPE;
1069                     } else {
1070                         /* Type has already been changed */
1071                         Error ("Redefinition for parameter `%s'", Sym->Name);
1072                     }
1073                 } else {
1074                     Error ("Unknown identifier: `%s'", Decl.Ident);
1075                 }
1076             }
1077
1078             if (CurTok.Tok == TOK_COMMA) {
1079                 NextToken ();
1080             } else {
1081                 break;
1082             }
1083
1084         }
1085
1086         /* Variable list must be semicolon terminated */
1087         ConsumeSemi ();
1088     }
1089 }
1090
1091
1092
1093 static void ParseAnsiParamList (FuncDesc* F)
1094 /* Parse a new style (ANSI) parameter list */
1095 {
1096     /* Parse params */
1097     while (CurTok.Tok != TOK_RPAREN) {
1098
1099         DeclSpec        Spec;
1100         Declaration     Decl;
1101         DeclAttr        Attr;
1102
1103         /* Allow an ellipsis as last parameter */
1104         if (CurTok.Tok == TOK_ELLIPSIS) {
1105             NextToken ();
1106             F->Flags |= FD_VARIADIC;
1107             break;
1108         }
1109
1110         /* Read the declaration specifier */
1111         ParseDeclSpec (&Spec, SC_AUTO, T_INT);
1112
1113         /* We accept only auto and register as storage class specifiers */
1114         if ((Spec.StorageClass & SC_AUTO) == SC_AUTO) {
1115             Spec.StorageClass = SC_AUTO | SC_PARAM | SC_DEF;
1116         } else if ((Spec.StorageClass & SC_REGISTER) == SC_REGISTER) {
1117             Spec.StorageClass = SC_REGISTER | SC_STATIC | SC_PARAM | SC_DEF;
1118         } else {
1119             Error ("Illegal storage class");
1120             Spec.StorageClass = SC_AUTO | SC_PARAM | SC_DEF;
1121         }
1122
1123         /* Allow parameters without a name, but remember if we had some to
1124          * eventually print an error message later.
1125          */
1126         ParseDecl (&Spec, &Decl, DM_ACCEPT_IDENT);
1127         if (Decl.Ident[0] == '\0') {
1128
1129             /* Unnamed symbol. Generate a name that is not user accessible,
1130              * then handle the symbol normal.
1131              */
1132             AnonName (Decl.Ident, "param");
1133             F->Flags |= FD_UNNAMED_PARAMS;
1134
1135             /* Clear defined bit on nonames */
1136             Decl.StorageClass &= ~SC_DEF;
1137         }
1138
1139         /* Parse an attribute ### */
1140         ParseAttribute (&Decl, &Attr);
1141
1142         /* Create a symbol table entry */
1143         AddLocalSym (Decl.Ident, ParamTypeCvt (Decl.Type), Decl.StorageClass, 0);
1144
1145         /* Count arguments */
1146         ++F->ParamCount;
1147
1148         /* Check for more parameters */
1149         if (CurTok.Tok == TOK_COMMA) {
1150             NextToken ();
1151         } else {
1152             break;
1153         }
1154     }
1155
1156     /* Skip right paren. We must explicitly check for one here, since some of
1157      * the breaks above bail out without checking.
1158      */
1159     ConsumeRParen ();
1160
1161     /* Check if this is a function definition */
1162     if (CurTok.Tok == TOK_LCURLY) {
1163         /* Print an error if we have unnamed parameters and cc65 extensions
1164          * are disabled.
1165          */
1166         if (IS_Get (&Standard) != STD_CC65 &&
1167             (F->Flags & FD_UNNAMED_PARAMS) != 0) {
1168             Error ("Parameter name omitted");
1169         }
1170     }
1171 }
1172
1173
1174
1175 static FuncDesc* ParseFuncDecl (void)
1176 /* Parse the argument list of a function. */
1177 {
1178     unsigned Offs;
1179     SymEntry* Sym;
1180
1181     /* Create a new function descriptor */
1182     FuncDesc* F = NewFuncDesc ();
1183
1184     /* Enter a new lexical level */
1185     EnterFunctionLevel ();
1186
1187     /* Check for several special parameter lists */
1188     if (CurTok.Tok == TOK_RPAREN) {
1189         /* Parameter list is empty */
1190         F->Flags |= (FD_EMPTY | FD_VARIADIC);
1191     } else if (CurTok.Tok == TOK_VOID && NextTok.Tok == TOK_RPAREN) {
1192         /* Parameter list declared as void */
1193         NextToken ();
1194         F->Flags |= FD_VOID_PARAM;
1195     } else if (CurTok.Tok == TOK_IDENT &&
1196                (NextTok.Tok == TOK_COMMA || NextTok.Tok == TOK_RPAREN)) {
1197         /* If the identifier is a typedef, we have a new style parameter list,
1198          * if it's some other identifier, it's an old style parameter list.
1199          */
1200         Sym = FindSym (CurTok.Ident);
1201         if (Sym == 0 || !SymIsTypeDef (Sym)) {
1202             /* Old style (K&R) function. */
1203             F->Flags |= FD_OLDSTYLE;
1204         }
1205     }
1206
1207     /* Parse params */
1208     if ((F->Flags & FD_OLDSTYLE) == 0) {
1209         /* New style function */
1210         ParseAnsiParamList (F);
1211     } else {
1212         /* Old style function */
1213         ParseOldStyleParamList (F);
1214     }
1215
1216     /* Remember the last function parameter. We need it later for several
1217      * purposes, for example when passing stuff to fastcall functions. Since
1218      * more symbols are added to the table, it is easier if we remember it
1219      * now, since it is currently the last entry in the symbol table.
1220      */
1221     F->LastParam = GetSymTab()->SymTail;
1222
1223     /* Assign offsets. If the function has a variable parameter list,
1224      * there's one additional byte (the arg size).
1225      */
1226     Offs = (F->Flags & FD_VARIADIC)? 1 : 0;
1227     Sym = F->LastParam;
1228     while (Sym) {
1229         unsigned Size = CheckedSizeOf (Sym->Type);
1230         if (SymIsRegVar (Sym)) {
1231             Sym->V.R.SaveOffs = Offs;
1232         } else {
1233             Sym->V.Offs = Offs;
1234         }
1235         Offs += Size;
1236         F->ParamSize += Size;
1237         Sym = Sym->PrevSym;
1238     }
1239
1240     /* Leave the lexical level remembering the symbol tables */
1241     RememberFunctionLevel (F);
1242
1243     /* Return the function descriptor */
1244     return F;
1245 }
1246
1247
1248
1249 static void Declarator (const DeclSpec* Spec, Declaration* D, declmode_t Mode)
1250 /* Recursively process declarators. Build a type array in reverse order. */
1251 {
1252     /* Read optional function or pointer qualifiers. These modify the
1253      * identifier or token to the right. For convenience, we allow the fastcall
1254      * qualifier also for pointers here. If it is a pointer-to-function, the
1255      * qualifier will later be transfered to the function itself. If it's a
1256      * pointer to something else, it will be flagged as an error.
1257      */
1258     TypeCode Qualifiers = OptionalQualifiers (T_QUAL_ADDRSIZE | T_QUAL_FASTCALL);
1259
1260     /* Pointer to something */
1261     if (CurTok.Tok == TOK_STAR) {
1262
1263         /* Skip the star */
1264         NextToken ();
1265
1266         /* Allow const, restrict and volatile qualifiers */
1267         Qualifiers |= OptionalQualifiers (T_QUAL_CONST | T_QUAL_VOLATILE | T_QUAL_RESTRICT);
1268
1269         /* Parse the type, the pointer points to */
1270         Declarator (Spec, D, Mode);
1271
1272         /* Add the type */
1273         AddTypeToDeclaration (D, T_PTR | Qualifiers);
1274         return;
1275     }
1276
1277     if (CurTok.Tok == TOK_LPAREN) {
1278         NextToken ();
1279         Declarator (Spec, D, Mode);
1280         ConsumeRParen ();
1281     } else {
1282         /* Things depend on Mode now:
1283          *  - Mode == DM_NEED_IDENT means:
1284          *      we *must* have a type and a variable identifer.
1285          *  - Mode == DM_NO_IDENT means:
1286          *      we must have a type but no variable identifer
1287          *      (if there is one, it's not read).
1288          *  - Mode == DM_ACCEPT_IDENT means:
1289          *      we *may* have an identifier. If there is an identifier,
1290          *      it is read, but it is no error, if there is none.
1291          */
1292         if (Mode == DM_NO_IDENT) {
1293             D->Ident[0] = '\0';
1294         } else if (CurTok.Tok == TOK_IDENT) {
1295             strcpy (D->Ident, CurTok.Ident);
1296             NextToken ();
1297         } else {
1298             if (Mode == DM_NEED_IDENT) {
1299                 Error ("Identifier expected");
1300             }
1301             D->Ident[0] = '\0';
1302         }
1303     }
1304
1305     while (CurTok.Tok == TOK_LBRACK || CurTok.Tok == TOK_LPAREN) {
1306         if (CurTok.Tok == TOK_LPAREN) {
1307
1308             /* Function declaration */
1309             FuncDesc* F;
1310
1311             /* Skip the opening paren */
1312             NextToken ();
1313
1314             /* Parse the function declaration */
1315             F = ParseFuncDecl ();
1316
1317             /* We cannot specify fastcall for variadic functions */
1318             if ((F->Flags & FD_VARIADIC) && (Qualifiers & T_QUAL_FASTCALL)) {
1319                 Error ("Variadic functions cannot be `__fastcall'");
1320                 Qualifiers &= ~T_QUAL_FASTCALL;
1321             }
1322
1323             /* Add the function type. Be sure to bounds check the type buffer */
1324             NeedTypeSpace (D, 1);
1325             D->Type[D->Index].C = T_FUNC | Qualifiers;
1326             D->Type[D->Index].A.P = F;
1327             ++D->Index;
1328
1329             /* Qualifiers now used */
1330             Qualifiers = T_QUAL_NONE;
1331
1332         } else {
1333             /* Array declaration. */
1334             long Size = UNSPECIFIED;
1335
1336             /* We cannot have any qualifiers for an array */
1337             if (Qualifiers != T_QUAL_NONE) {
1338                 Error ("Invalid qualifiers for array");
1339                 Qualifiers = T_QUAL_NONE;
1340             }
1341
1342             /* Skip the left bracket */
1343             NextToken ();
1344
1345             /* Read the size if it is given */
1346             if (CurTok.Tok != TOK_RBRACK) {
1347                 ExprDesc Expr;
1348                 ConstAbsIntExpr (hie1, &Expr);
1349                 if (Expr.IVal <= 0) {
1350                     if (D->Ident[0] != '\0') {
1351                         Error ("Size of array `%s' is invalid", D->Ident);
1352                     } else {
1353                         Error ("Size of array is invalid");
1354                     }
1355                     Expr.IVal = 1;
1356                 }
1357                 Size = Expr.IVal;
1358             }
1359
1360             /* Skip the right bracket */
1361             ConsumeRBrack ();
1362
1363             /* Add the array type with the size to the type */
1364             NeedTypeSpace (D, 1);
1365             D->Type[D->Index].C = T_ARRAY;
1366             D->Type[D->Index].A.L = Size;
1367             ++D->Index;
1368         }
1369     }
1370
1371     /* If we have remaining qualifiers, flag them as invalid */
1372     if (Qualifiers & T_QUAL_NEAR) {
1373         Error ("Invalid `__near__' qualifier");
1374     }
1375     if (Qualifiers & T_QUAL_FAR) {
1376         Error ("Invalid `__far__' qualifier");
1377     }
1378     if (Qualifiers & T_QUAL_FASTCALL) {
1379         Error ("Invalid `__fastcall__' qualifier");
1380     }
1381 }
1382
1383
1384
1385 /*****************************************************************************/
1386 /*                                   code                                    */
1387 /*****************************************************************************/
1388
1389
1390
1391 Type* ParseType (Type* T)
1392 /* Parse a complete type specification */
1393 {
1394     DeclSpec Spec;
1395     Declaration Decl;
1396
1397     /* Get a type without a default */
1398     InitDeclSpec (&Spec);
1399     ParseTypeSpec (&Spec, -1, T_QUAL_NONE);
1400
1401     /* Parse additional declarators */
1402     ParseDecl (&Spec, &Decl, DM_NO_IDENT);
1403
1404     /* Copy the type to the target buffer */
1405     TypeCopy (T, Decl.Type);
1406
1407     /* Return a pointer to the target buffer */
1408     return T;
1409 }
1410
1411
1412
1413 void ParseDecl (const DeclSpec* Spec, Declaration* D, declmode_t Mode)
1414 /* Parse a variable, type or function declaration */
1415 {
1416     /* Initialize the Declaration struct */
1417     InitDeclaration (D);
1418
1419     /* Get additional declarators and the identifier */
1420     Declarator (Spec, D, Mode);
1421
1422     /* Add the base type. */
1423     NeedTypeSpace (D, TypeLen (Spec->Type) + 1);        /* Bounds check */
1424     TypeCopy (D->Type + D->Index, Spec->Type);
1425
1426     /* Use the storage class from the declspec */
1427     D->StorageClass = Spec->StorageClass;
1428
1429     /* Do several fixes on qualifiers */
1430     FixQualifiers (D->Type);
1431
1432     /* If we have a function, add a special storage class */
1433     if (IsTypeFunc (D->Type)) {
1434         D->StorageClass |= SC_FUNC;
1435     }
1436
1437     /* Check several things for function or function pointer types */
1438     if (IsTypeFunc (D->Type) || IsTypeFuncPtr (D->Type)) {
1439
1440         /* A function. Check the return type */
1441         Type* RetType = GetFuncReturn (D->Type);
1442
1443         /* Functions may not return functions or arrays */
1444         if (IsTypeFunc (RetType)) {
1445             Error ("Functions are not allowed to return functions");
1446         } else if (IsTypeArray (RetType)) {
1447             Error ("Functions are not allowed to return arrays");
1448         }
1449
1450         /* The return type must not be qualified */
1451         if (GetQualifier (RetType) != T_QUAL_NONE && RetType[1].C == T_END) {
1452
1453             if (GetType (RetType) == T_TYPE_VOID) {
1454                 /* A qualified void type is always an error */
1455                 Error ("function definition has qualified void return type");
1456             } else {
1457                 /* For others, qualifiers are ignored */
1458                 Warning ("type qualifiers ignored on function return type");
1459                 RetType[0].C = UnqualifiedType (RetType[0].C);
1460             }
1461         }
1462
1463         /* Warn about an implicit int return in the function */
1464         if ((Spec->Flags & DS_DEF_TYPE) != 0 &&
1465             RetType[0].C == T_INT && RetType[1].C == T_END) {
1466             /* Function has an implicit int return. Output a warning if we don't
1467              * have the C89 standard enabled explicitly.
1468              */
1469             if (IS_Get (&Standard) >= STD_C99) {
1470                 Warning ("Implicit `int' return type is an obsolete feature");
1471             }
1472             GetFuncDesc (D->Type)->Flags |= FD_OLDSTYLE_INTRET;
1473         }
1474
1475     }
1476
1477     /* For anthing that is not a function or typedef, check for an implicit
1478      * int declaration.
1479      */
1480     if ((D->StorageClass & SC_FUNC) != SC_FUNC &&
1481         (D->StorageClass & SC_TYPEDEF) != SC_TYPEDEF) {
1482         /* If the standard was not set explicitly to C89, print a warning
1483          * for variables with implicit int type.
1484          */
1485         if ((Spec->Flags & DS_DEF_TYPE) != 0 && IS_Get (&Standard) >= STD_C99) {
1486             Warning ("Implicit `int' is an obsolete feature");
1487         }
1488     }
1489
1490     /* Check the size of the generated type */
1491     if (!IsTypeFunc (D->Type) && !IsTypeVoid (D->Type)) {
1492         unsigned Size = SizeOf (D->Type);
1493         if (Size >= 0x10000) {
1494             if (D->Ident[0] != '\0') {
1495                 Error ("Size of `%s' is invalid (0x%06X)", D->Ident, Size);
1496             } else {
1497                 Error ("Invalid size in declaration (0x%06X)", Size);
1498             }
1499         }
1500     }
1501
1502 }
1503
1504
1505
1506 void ParseDeclSpec (DeclSpec* D, unsigned DefStorage, long DefType)
1507 /* Parse a declaration specification */
1508 {
1509     TypeCode Qualifiers;
1510
1511     /* Initialize the DeclSpec struct */
1512     InitDeclSpec (D);
1513
1514     /* There may be qualifiers *before* the storage class specifier */
1515     Qualifiers = OptionalQualifiers (T_QUAL_CONST | T_QUAL_VOLATILE);
1516
1517     /* Now get the storage class specifier for this declaration */
1518     ParseStorageClass (D, DefStorage);
1519
1520     /* Parse the type specifiers passing any initial type qualifiers */
1521     ParseTypeSpec (D, DefType, Qualifiers);
1522 }
1523
1524
1525
1526 void CheckEmptyDecl (const DeclSpec* D)
1527 /* Called after an empty type declaration (that is, a type declaration without
1528  * a variable). Checks if the declaration does really make sense and issues a
1529  * warning if not.
1530  */
1531 {
1532     if ((D->Flags & DS_EXTRA_TYPE) == 0) {
1533         Warning ("Useless declaration");
1534     }
1535 }
1536
1537
1538
1539 static void SkipInitializer (unsigned BracesExpected)
1540 /* Skip the remainder of an initializer in case of errors. Try to be somewhat
1541  * smart so we don't have too many following errors.
1542  */
1543 {
1544     while (CurTok.Tok != TOK_CEOF && CurTok.Tok != TOK_SEMI && BracesExpected > 0) {
1545         switch (CurTok.Tok) {
1546             case TOK_RCURLY:    --BracesExpected;   break;
1547             case TOK_LCURLY:    ++BracesExpected;   break;
1548             default:                                break;
1549         }
1550         NextToken ();
1551     }
1552 }
1553
1554
1555
1556 static unsigned OpeningCurlyBraces (unsigned BracesNeeded)
1557 /* Accept any number of opening curly braces around an initialization, skip
1558  * them and return the number. If the number of curly braces is less than
1559  * BracesNeeded, issue a warning.
1560  */
1561 {
1562     unsigned BraceCount = 0;
1563     while (CurTok.Tok == TOK_LCURLY) {
1564         ++BraceCount;
1565         NextToken ();
1566     }
1567     if (BraceCount < BracesNeeded) {
1568         Error ("`{' expected");
1569     }
1570     return BraceCount;
1571 }
1572
1573
1574
1575 static void ClosingCurlyBraces (unsigned BracesExpected)
1576 /* Accept and skip the given number of closing curly braces together with
1577  * an optional comma. Output an error messages, if the input does not contain
1578  * the expected number of braces.
1579  */
1580 {
1581     while (BracesExpected) {
1582         if (CurTok.Tok == TOK_RCURLY) {
1583             NextToken ();
1584         } else if (CurTok.Tok == TOK_COMMA && NextTok.Tok == TOK_RCURLY) {
1585             NextToken ();
1586             NextToken ();
1587         } else {
1588             Error ("`}' expected");
1589             return;
1590         }
1591         --BracesExpected;
1592     }
1593 }
1594
1595
1596
1597 static void DefineData (ExprDesc* Expr)
1598 /* Output a data definition for the given expression */
1599 {
1600     switch (ED_GetLoc (Expr)) {
1601
1602         case E_LOC_ABS:
1603             /* Absolute: numeric address or const */
1604             g_defdata (TypeOf (Expr->Type) | CF_CONST, Expr->IVal, 0);
1605             break;
1606
1607         case E_LOC_GLOBAL:
1608             /* Global variable */
1609             g_defdata (CF_EXTERNAL, Expr->Name, Expr->IVal);
1610             break;
1611
1612         case E_LOC_STATIC:
1613         case E_LOC_LITERAL:
1614             /* Static variable or literal in the literal pool */
1615             g_defdata (CF_STATIC, Expr->Name, Expr->IVal);
1616             break;
1617
1618         case E_LOC_REGISTER:
1619             /* Register variable. Taking the address is usually not
1620              * allowed.
1621              */
1622             if (IS_Get (&AllowRegVarAddr) == 0) {
1623                 Error ("Cannot take the address of a register variable");
1624             }
1625             g_defdata (CF_REGVAR, Expr->Name, Expr->IVal);
1626             break;
1627
1628         case E_LOC_STACK:
1629         case E_LOC_PRIMARY:
1630         case E_LOC_EXPR:
1631             Error ("Non constant initializer");
1632             break;
1633
1634         default:
1635             Internal ("Unknown constant type: 0x%04X", ED_GetLoc (Expr));
1636     }
1637 }
1638
1639
1640
1641 static unsigned ParseScalarInit (Type* T)
1642 /* Parse initializaton for scalar data types. Return the number of data bytes. */
1643 {
1644     ExprDesc ED;
1645
1646     /* Optional opening brace */
1647     unsigned BraceCount = OpeningCurlyBraces (0);
1648
1649     /* We warn if an initializer for a scalar contains braces, because this is
1650      * quite unusual and often a sign for some problem in the input.
1651      */
1652     if (BraceCount > 0) {
1653         Warning ("Braces around scalar initializer");
1654     }
1655
1656     /* Get the expression and convert it to the target type */
1657     ConstExpr (hie1, &ED);
1658     TypeConversion (&ED, T);
1659
1660     /* Output the data */
1661     DefineData (&ED);
1662
1663     /* Close eventually opening braces */
1664     ClosingCurlyBraces (BraceCount);
1665
1666     /* Done */
1667     return SizeOf (T);
1668 }
1669
1670
1671
1672 static unsigned ParsePointerInit (Type* T)
1673 /* Parse initializaton for pointer data types. Return the number of data bytes. */
1674 {
1675     /* Optional opening brace */
1676     unsigned BraceCount = OpeningCurlyBraces (0);
1677
1678     /* Expression */
1679     ExprDesc ED;
1680     ConstExpr (hie1, &ED);
1681     TypeConversion (&ED, T);
1682
1683     /* Output the data */
1684     DefineData (&ED);
1685
1686     /* Close eventually opening braces */
1687     ClosingCurlyBraces (BraceCount);
1688
1689     /* Done */
1690     return SIZEOF_PTR;
1691 }
1692
1693
1694
1695 static unsigned ParseArrayInit (Type* T, int AllowFlexibleMembers)
1696 /* Parse initializaton for arrays. Return the number of data bytes. */
1697 {
1698     int Count;
1699
1700     /* Get the array data */
1701     Type* ElementType    = GetElementType (T);
1702     unsigned ElementSize = CheckedSizeOf (ElementType);
1703     long ElementCount    = GetElementCount (T);
1704
1705     /* Special handling for a character array initialized by a literal */
1706     if (IsTypeChar (ElementType) &&
1707         (CurTok.Tok == TOK_SCONST ||
1708         (CurTok.Tok == TOK_LCURLY && NextTok.Tok == TOK_SCONST))) {
1709
1710         /* Char array initialized by string constant */
1711         int NeedParen;
1712         const char* Str;
1713
1714         /* If we initializer is enclosed in brackets, remember this fact and
1715          * skip the opening bracket.
1716          */
1717         NeedParen = (CurTok.Tok == TOK_LCURLY);
1718         if (NeedParen) {
1719             NextToken ();
1720         }
1721
1722         /* Get the initializer string and its size */
1723         Str = GetLiteral (CurTok.IVal);
1724         Count = GetLiteralPoolOffs () - CurTok.IVal;
1725
1726         /* Translate into target charset */
1727         TranslateLiteralPool (CurTok.IVal);
1728
1729         /* If the array is one too small for the string literal, omit the
1730          * trailing zero.
1731          */
1732         if (ElementCount != UNSPECIFIED &&
1733             ElementCount != FLEXIBLE    &&
1734             Count        == ElementCount + 1) {
1735             /* Omit the trailing zero */
1736             --Count;
1737         }
1738
1739         /* Output the data */
1740         g_defbytes (Str, Count);
1741
1742         /* Remove string from pool */
1743         ResetLiteralPoolOffs (CurTok.IVal);
1744         NextToken ();
1745
1746         /* If the initializer was enclosed in curly braces, we need a closing
1747          * one.
1748          */
1749         if (NeedParen) {
1750             ConsumeRCurly ();
1751         }
1752
1753     } else {
1754
1755         /* Curly brace */
1756         ConsumeLCurly ();
1757
1758         /* Initialize the array members */
1759         Count = 0;
1760         while (CurTok.Tok != TOK_RCURLY) {
1761             /* Flexible array members may not be initialized within
1762              * an array (because the size of each element may differ
1763              * otherwise).
1764              */
1765             ParseInitInternal (ElementType, 0);
1766             ++Count;
1767             if (CurTok.Tok != TOK_COMMA)
1768                 break;
1769             NextToken ();
1770         }
1771
1772         /* Closing curly braces */
1773         ConsumeRCurly ();
1774     }
1775
1776     if (ElementCount == UNSPECIFIED) {
1777         /* Number of elements determined by initializer */
1778         SetElementCount (T, Count);
1779         ElementCount = Count;
1780     } else if (ElementCount == FLEXIBLE && AllowFlexibleMembers) {
1781         /* In non ANSI mode, allow initialization of flexible array
1782          * members.
1783          */
1784         ElementCount = Count;
1785     } else if (Count < ElementCount) {
1786         g_zerobytes ((ElementCount - Count) * ElementSize);
1787     } else if (Count > ElementCount) {
1788         Error ("Too many initializers");
1789     }
1790     return ElementCount * ElementSize;
1791 }
1792
1793
1794
1795 static unsigned ParseStructInit (Type* T, int AllowFlexibleMembers)
1796 /* Parse initialization of a struct or union. Return the number of data bytes. */
1797 {
1798     SymEntry* Entry;
1799     SymTable* Tab;
1800     unsigned  StructSize;
1801     unsigned  Size;
1802
1803
1804     /* Consume the opening curly brace */
1805     ConsumeLCurly ();
1806
1807     /* Get a pointer to the struct entry from the type */
1808     Entry = GetSymEntry (T);
1809
1810     /* Get the size of the struct from the symbol table entry */
1811     StructSize = Entry->V.S.Size;
1812
1813     /* Check if this struct definition has a field table. If it doesn't, it
1814      * is an incomplete definition.
1815      */
1816     Tab = Entry->V.S.SymTab;
1817     if (Tab == 0) {
1818         Error ("Cannot initialize variables with incomplete type");
1819         /* Try error recovery */
1820         SkipInitializer (1);
1821         /* Nothing initialized */
1822         return 0;
1823     }
1824
1825     /* Get a pointer to the list of symbols */
1826     Entry = Tab->SymHead;
1827
1828     /* Initialize fields */
1829     Size = 0;
1830     while (CurTok.Tok != TOK_RCURLY) {
1831         if (Entry == 0) {
1832             Error ("Too many initializers");
1833             SkipInitializer (1);
1834             return Size;
1835         }
1836         /* Parse initialization of one field. Flexible array members may
1837          * only be initialized if they are the last field (or part of the
1838          * last struct field).
1839          */
1840         Size += ParseInitInternal (Entry->Type, AllowFlexibleMembers && Entry->NextSym == 0);
1841         Entry = Entry->NextSym;
1842         if (CurTok.Tok != TOK_COMMA)
1843             break;
1844         NextToken ();
1845     }
1846
1847     /* Consume the closing curly brace */
1848     ConsumeRCurly ();
1849
1850     /* If there are struct fields left, reserve additional storage */
1851     if (Size < StructSize) {
1852         g_zerobytes (StructSize - Size);
1853         Size = StructSize;
1854     }
1855
1856     /* Return the actual number of bytes initialized. This number may be
1857      * larger than StructSize if flexible array members are present and were
1858      * initialized (possible in non ANSI mode).
1859      */
1860     return Size;
1861 }
1862
1863
1864
1865 static unsigned ParseVoidInit (void)
1866 /* Parse an initialization of a void variable (special cc65 extension).
1867  * Return the number of bytes initialized.
1868  */
1869 {
1870     ExprDesc Expr;
1871     unsigned Size;
1872
1873     /* Opening brace */
1874     ConsumeLCurly ();
1875
1876     /* Allow an arbitrary list of values */
1877     Size = 0;
1878     do {
1879         ConstExpr (hie1, &Expr);
1880         switch (UnqualifiedType (Expr.Type[0].C)) {
1881
1882             case T_SCHAR:
1883             case T_UCHAR:
1884                 if (ED_IsConstAbsInt (&Expr)) {
1885                     /* Make it byte sized */
1886                     Expr.IVal &= 0xFF;
1887                 }
1888                 DefineData (&Expr);
1889                 Size += SIZEOF_CHAR;
1890                 break;
1891
1892             case T_SHORT:
1893             case T_USHORT:
1894             case T_INT:
1895             case T_UINT:
1896             case T_PTR:
1897             case T_ARRAY:
1898                 if (ED_IsConstAbsInt (&Expr)) {
1899                     /* Make it word sized */
1900                     Expr.IVal &= 0xFFFF;
1901                 }
1902                 DefineData (&Expr);
1903                 Size += SIZEOF_INT;
1904                 break;
1905
1906             case T_LONG:
1907             case T_ULONG:
1908                 if (ED_IsConstAbsInt (&Expr)) {
1909                     /* Make it dword sized */
1910                     Expr.IVal &= 0xFFFFFFFF;
1911                 }
1912                 DefineData (&Expr);
1913                 Size += SIZEOF_LONG;
1914                 break;
1915
1916             default:
1917                 Error ("Illegal type in initialization");
1918                 break;
1919
1920         }
1921
1922         if (CurTok.Tok != TOK_COMMA) {
1923             break;
1924         }
1925         NextToken ();
1926
1927     } while (CurTok.Tok != TOK_RCURLY);
1928
1929     /* Closing brace */
1930     ConsumeRCurly ();
1931
1932     /* Return the number of bytes initialized */
1933     return Size;
1934 }
1935
1936
1937
1938 static unsigned ParseInitInternal (Type* T, int AllowFlexibleMembers)
1939 /* Parse initialization of variables. Return the number of data bytes. */
1940 {
1941     switch (UnqualifiedType (T->C)) {
1942
1943         case T_SCHAR:
1944         case T_UCHAR:
1945         case T_SHORT:
1946         case T_USHORT:
1947         case T_INT:
1948         case T_UINT:
1949         case T_LONG:
1950         case T_ULONG:
1951         case T_FLOAT:
1952         case T_DOUBLE:
1953             return ParseScalarInit (T);
1954
1955         case T_PTR:
1956             return ParsePointerInit (T);
1957
1958         case T_ARRAY:
1959             return ParseArrayInit (T, AllowFlexibleMembers);
1960
1961         case T_STRUCT:
1962         case T_UNION:
1963             return ParseStructInit (T, AllowFlexibleMembers);
1964
1965         case T_VOID:
1966             if (IS_Get (&Standard) == STD_CC65) {
1967                 /* Special cc65 extension in non ANSI mode */
1968                 return ParseVoidInit ();
1969             }
1970             /* FALLTHROUGH */
1971
1972         default:
1973             Error ("Illegal type");
1974             return SIZEOF_CHAR;
1975
1976     }
1977 }
1978
1979
1980
1981 unsigned ParseInit (Type* T)
1982 /* Parse initialization of variables. Return the number of data bytes. */
1983 {
1984     /* Parse the initialization. Flexible array members can only be initialized
1985      * in cc65 mode.
1986      */
1987     unsigned Size = ParseInitInternal (T, IS_Get (&Standard) == STD_CC65);
1988
1989     /* The initialization may not generate code on global level, because code
1990      * outside function scope will never get executed.
1991      */
1992     if (HaveGlobalCode ()) {
1993         Error ("Non constant initializers");
1994         RemoveGlobalCode ();
1995     }
1996
1997     /* Return the size needed for the initialization */
1998     return Size;
1999 }
2000
2001
2002