]> git.sur5r.net Git - cc65/blob - src/cc65/declare.c
Any field without a name is legal but useless in a union.
[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                 /* Any field without a name is legal but useless in a union */
560                 Warning ("Declaration does not declare anything");
561                 goto NextMember;
562             }
563
564             /* Handle sizes */
565             FieldSize = CheckedSizeOf (Decl.Type);
566             if (FieldSize > UnionSize) {
567                 UnionSize = FieldSize;
568             }
569
570             /* Add a field entry to the table */
571             if (FieldWidth > 0) {
572                 AddBitField (Decl.Ident, 0, 0, FieldWidth);
573             } else {
574                 AddLocalSym (Decl.Ident, Decl.Type, SC_STRUCTFIELD, 0);
575             }
576
577 NextMember: if (CurTok.Tok != TOK_COMMA) {
578                 break;
579             }
580             NextToken ();
581         }
582         ConsumeSemi ();
583     }
584
585     /* Skip the closing brace */
586     NextToken ();
587
588     /* Remember the symbol table and leave the struct level */
589     FieldTab = GetSymTab ();
590     LeaveStructLevel ();
591
592     /* Make a real entry from the forward decl and return it */
593     return AddStructSym (Name, UnionSize, FieldTab);
594 }
595
596
597
598 static SymEntry* ParseStructDecl (const char* Name)
599 /* Parse a struct declaration. */
600 {
601
602     unsigned  StructSize;
603     int       FlexibleMember;
604     unsigned  Offs;
605     int       BitOffs;          /* Bit offset for bit-fields */
606     int       FieldWidth;       /* Width in bits, -1 if not a bit-field */
607     SymTable* FieldTab;
608     SymEntry* Entry;
609
610
611     if (CurTok.Tok != TOK_LCURLY) {
612         /* Just a forward declaration. */
613         return StructOrUnionForwardDecl (Name);
614     }
615
616     /* Add a forward declaration for the struct in the current lexical level */
617     Entry = AddStructSym (Name, 0, 0);
618
619     /* Skip the curly brace */
620     NextToken ();
621
622     /* Enter a new lexical level for the struct */
623     EnterStructLevel ();
624
625     /* Parse struct fields */
626     FlexibleMember = 0;
627     StructSize     = 0;
628     BitOffs        = 0;
629     while (CurTok.Tok != TOK_RCURLY) {
630
631         /* Get the type of the entry */
632         DeclSpec Spec;
633         InitDeclSpec (&Spec);
634         ParseTypeSpec (&Spec, -1, T_QUAL_NONE);
635
636         /* Read fields with this type */
637         while (1) {
638
639             Declaration Decl;
640
641             /* If we had a flexible array member before, no other fields can
642              * follow.
643              */
644             if (FlexibleMember) {
645                 Error ("Flexible array member must be last field");
646                 FlexibleMember = 0;     /* Avoid further errors */
647             }
648
649             /* Get type and name of the struct field */
650             ParseDecl (&Spec, &Decl, DM_ACCEPT_IDENT);
651
652             /* Check for a bit-field declaration */
653             FieldWidth = ParseFieldWidth (&Decl);
654
655             /* If this is not a bit field, or the bit field is too large for
656              * the remainder of the current member, or we have a bit field
657              * with width zero, align the struct to the next member
658              */
659             if (BitOffs > 0) {
660                 if (FieldWidth <= 0 || (BitOffs + FieldWidth) > INT_BITS) {
661                     StructSize += SIZEOF_INT;
662                     BitOffs = 0;
663                 }
664             }
665
666             /* Apart from the above, a bit field with width 0 is not processed
667              * further.
668              */
669             if (FieldWidth == 0) {
670                 goto NextMember;
671             }
672
673             /* Check for fields without names */
674             if (Decl.Ident[0] == '\0') {
675                 if (FieldWidth < 0) {
676                     /* A non bit-field without a name is legal but useless */
677                     Warning ("Declaration does not declare anything");
678                     goto NextMember;
679                 } else {
680                     /* A bit-field without a name will just increase the
681                      * offset
682                      */
683                     BitOffs += FieldWidth;
684                     goto NextMember;
685                 }
686             }
687
688             /* Byte offset of this member is the current struct size plus any
689              * full bytes from the bit offset in case of bit-fields.
690              */
691             Offs = StructSize + (BitOffs >> 3);
692
693             /* Check if this field is a flexible array member, and
694              * calculate the size of the field.
695              */
696             if (IsTypeArray (Decl.Type) && GetElementCount (Decl.Type) == UNSPECIFIED) {
697                 /* Array with unspecified size */
698                 if (StructSize == 0) {
699                     Error ("Flexible array member cannot be first struct field");
700                 }
701                 FlexibleMember = 1;
702                 /* Assume zero for size calculations */
703                 SetElementCount (Decl.Type, FLEXIBLE);
704             } else if (FieldWidth < 0) {
705                 StructSize += CheckedSizeOf (Decl.Type);
706             }
707
708             /* Add a field entry to the table */
709             if (FieldWidth > 0) {
710                 AddBitField (Decl.Ident, Offs, BitOffs & 0x07, FieldWidth);
711                 BitOffs += FieldWidth;
712             } else {
713                 AddLocalSym (Decl.Ident, Decl.Type, SC_STRUCTFIELD, Offs);
714             }
715
716 NextMember: if (CurTok.Tok != TOK_COMMA) {
717                 break;
718             }
719             NextToken ();
720         }
721         ConsumeSemi ();
722     }
723
724     /* If we have bits from bit-fields left, add them to the size. */
725     if (BitOffs > 0) {
726         StructSize += ((BitOffs + CHAR_BITS - 1) >> 3);
727     }
728
729     /* Skip the closing brace */
730     NextToken ();
731
732     /* Remember the symbol table and leave the struct level */
733     FieldTab = GetSymTab ();
734     LeaveStructLevel ();
735
736     /* Make a real entry from the forward decl and return it */
737     return AddStructSym (Name, StructSize, FieldTab);
738 }
739
740
741
742 static void ParseTypeSpec (DeclSpec* D, long Default, TypeCode Qualifiers)
743 /* Parse a type specificier */
744 {
745     ident       Ident;
746     SymEntry*   Entry;
747
748     /* Assume we have an explicit type */
749     D->Flags &= ~DS_DEF_TYPE;
750
751     /* Read type qualifiers if we have any */
752     Qualifiers |= OptionalQualifiers (T_QUAL_CONST | T_QUAL_VOLATILE);
753
754     /* Look at the data type */
755     switch (CurTok.Tok) {
756
757         case TOK_VOID:
758             NextToken ();
759             D->Type[0].C = T_VOID;
760             D->Type[1].C = T_END;
761             break;
762
763         case TOK_CHAR:
764             NextToken ();
765             D->Type[0].C = GetDefaultChar();
766             D->Type[1].C = T_END;
767             break;
768
769         case TOK_LONG:
770             NextToken ();
771             if (CurTok.Tok == TOK_UNSIGNED) {
772                 NextToken ();
773                 OptionalInt ();
774                 D->Type[0].C = T_ULONG;
775                 D->Type[1].C = T_END;
776             } else {
777                 OptionalSigned ();
778                 OptionalInt ();
779                 D->Type[0].C = T_LONG;
780                 D->Type[1].C = T_END;
781             }
782             break;
783
784         case TOK_SHORT:
785             NextToken ();
786             if (CurTok.Tok == TOK_UNSIGNED) {
787                 NextToken ();
788                 OptionalInt ();
789                 D->Type[0].C = T_USHORT;
790                 D->Type[1].C = T_END;
791             } else {
792                 OptionalSigned ();
793                 OptionalInt ();
794                 D->Type[0].C = T_SHORT;
795                 D->Type[1].C = T_END;
796             }
797             break;
798
799         case TOK_INT:
800             NextToken ();
801             D->Type[0].C = T_INT;
802             D->Type[1].C = T_END;
803             break;
804
805        case TOK_SIGNED:
806             NextToken ();
807             switch (CurTok.Tok) {
808
809                 case TOK_CHAR:
810                     NextToken ();
811                     D->Type[0].C = T_SCHAR;
812                     D->Type[1].C = T_END;
813                     break;
814
815                 case TOK_SHORT:
816                     NextToken ();
817                     OptionalInt ();
818                     D->Type[0].C = T_SHORT;
819                     D->Type[1].C = T_END;
820                     break;
821
822                 case TOK_LONG:
823                     NextToken ();
824                     OptionalInt ();
825                     D->Type[0].C = T_LONG;
826                     D->Type[1].C = T_END;
827                     break;
828
829                 case TOK_INT:
830                     NextToken ();
831                     /* FALL THROUGH */
832
833                 default:
834                     D->Type[0].C = T_INT;
835                     D->Type[1].C = T_END;
836                     break;
837             }
838             break;
839
840         case TOK_UNSIGNED:
841             NextToken ();
842             switch (CurTok.Tok) {
843
844                 case TOK_CHAR:
845                     NextToken ();
846                     D->Type[0].C = T_UCHAR;
847                     D->Type[1].C = T_END;
848                     break;
849
850                 case TOK_SHORT:
851                     NextToken ();
852                     OptionalInt ();
853                     D->Type[0].C = T_USHORT;
854                     D->Type[1].C = T_END;
855                     break;
856
857                 case TOK_LONG:
858                     NextToken ();
859                     OptionalInt ();
860                     D->Type[0].C = T_ULONG;
861                     D->Type[1].C = T_END;
862                     break;
863
864                 case TOK_INT:
865                     NextToken ();
866                     /* FALL THROUGH */
867
868                 default:
869                     D->Type[0].C = T_UINT;
870                     D->Type[1].C = T_END;
871                     break;
872             }
873             break;
874
875         case TOK_FLOAT:
876             NextToken ();
877             D->Type[0].C = T_FLOAT;
878             D->Type[1].C = T_END;
879             break;
880
881         case TOK_DOUBLE:
882             NextToken ();
883             D->Type[0].C = T_DOUBLE;
884             D->Type[1].C = T_END;
885             break;
886
887         case TOK_UNION:
888             NextToken ();
889             /* */
890             if (CurTok.Tok == TOK_IDENT) {
891                 strcpy (Ident, CurTok.Ident);
892                 NextToken ();
893             } else {
894                 AnonName (Ident, "union");
895             }
896             /* Remember we have an extra type decl */
897             D->Flags |= DS_EXTRA_TYPE;
898             /* Declare the union in the current scope */
899             Entry = ParseUnionDecl (Ident);
900             /* Encode the union entry into the type */
901             D->Type[0].C = T_UNION;
902             SetSymEntry (D->Type, Entry);
903             D->Type[1].C = T_END;
904             break;
905
906         case TOK_STRUCT:
907             NextToken ();
908             /* */
909             if (CurTok.Tok == TOK_IDENT) {
910                 strcpy (Ident, CurTok.Ident);
911                 NextToken ();
912             } else {
913                 AnonName (Ident, "struct");
914             }
915             /* Remember we have an extra type decl */
916             D->Flags |= DS_EXTRA_TYPE;
917             /* Declare the struct in the current scope */
918             Entry = ParseStructDecl (Ident);
919             /* Encode the struct entry into the type */
920             D->Type[0].C = T_STRUCT;
921             SetSymEntry (D->Type, Entry);
922             D->Type[1].C = T_END;
923             break;
924
925         case TOK_ENUM:
926             NextToken ();
927             if (CurTok.Tok != TOK_LCURLY) {
928                 /* Named enum */
929                 if (CurTok.Tok == TOK_IDENT) {
930                     /* Find an entry with this name */
931                     Entry = FindTagSym (CurTok.Ident);
932                     if (Entry) {
933                         if (SymIsLocal (Entry) && (Entry->Flags & SC_ENUM) == 0) {
934                             Error ("Symbol `%s' is already different kind", Entry->Name);
935                         }
936                     } else {
937                         /* Insert entry into table ### */
938                     }
939                     /* Skip the identifier */
940                     NextToken ();
941                 } else {
942                     Error ("Identifier expected");
943                 }
944             }
945             /* Remember we have an extra type decl */
946             D->Flags |= DS_EXTRA_TYPE;
947             /* Parse the enum decl */
948             ParseEnumDecl ();
949             D->Type[0].C = T_INT;
950             D->Type[1].C = T_END;
951             break;
952
953         case TOK_IDENT:
954             Entry = FindSym (CurTok.Ident);
955             if (Entry && SymIsTypeDef (Entry)) {
956                 /* It's a typedef */
957                 NextToken ();
958                 TypeCopy (D->Type, Entry->Type);
959                 break;
960             }
961             /* FALL THROUGH */
962
963         default:
964             if (Default < 0) {
965                 Error ("Type expected");
966                 D->Type[0].C = T_INT;
967                 D->Type[1].C = T_END;
968             } else {
969                 D->Flags |= DS_DEF_TYPE;
970                 D->Type[0].C = (TypeCode) Default;
971                 D->Type[1].C = T_END;
972             }
973             break;
974     }
975
976     /* There may also be qualifiers *after* the initial type */
977     D->Type[0].C |= (Qualifiers | OptionalQualifiers (T_QUAL_CONST | T_QUAL_VOLATILE));
978 }
979
980
981
982 static Type* ParamTypeCvt (Type* T)
983 /* If T is an array, convert it to a pointer else do nothing. Return the
984  * resulting type.
985  */
986 {
987     if (IsTypeArray (T)) {
988         T->C = T_PTR;
989     }
990     return T;
991 }
992
993
994
995 static void ParseOldStyleParamList (FuncDesc* F)
996 /* Parse an old style (K&R) parameter list */
997 {
998     /* Parse params */
999     while (CurTok.Tok != TOK_RPAREN) {
1000
1001         /* List of identifiers expected */
1002         if (CurTok.Tok != TOK_IDENT) {
1003             Error ("Identifier expected");
1004         }
1005
1006         /* Create a symbol table entry with type int */
1007         AddLocalSym (CurTok.Ident, type_int, SC_AUTO | SC_PARAM | SC_DEF | SC_DEFTYPE, 0);
1008
1009         /* Count arguments */
1010         ++F->ParamCount;
1011
1012         /* Skip the identifier */
1013         NextToken ();
1014
1015         /* Check for more parameters */
1016         if (CurTok.Tok == TOK_COMMA) {
1017             NextToken ();
1018         } else {
1019             break;
1020         }
1021     }
1022
1023     /* Skip right paren. We must explicitly check for one here, since some of
1024      * the breaks above bail out without checking.
1025      */
1026     ConsumeRParen ();
1027
1028     /* An optional list of type specifications follows */
1029     while (CurTok.Tok != TOK_LCURLY) {
1030
1031         DeclSpec        Spec;
1032
1033         /* Read the declaration specifier */
1034         ParseDeclSpec (&Spec, SC_AUTO, T_INT);
1035
1036         /* We accept only auto and register as storage class specifiers, but
1037          * we ignore all this, since we use auto anyway.
1038          */
1039         if ((Spec.StorageClass & SC_AUTO) == 0 &&
1040             (Spec.StorageClass & SC_REGISTER) == 0) {
1041             Error ("Illegal storage class");
1042         }
1043
1044         /* Parse a comma separated variable list */
1045         while (1) {
1046
1047             Declaration         Decl;
1048
1049             /* Read the parameter */
1050             ParseDecl (&Spec, &Decl, DM_NEED_IDENT);
1051             if (Decl.Ident[0] != '\0') {
1052
1053                 /* We have a name given. Search for the symbol */
1054                 SymEntry* Sym = FindLocalSym (Decl.Ident);
1055                 if (Sym) {
1056                     /* Check if we already changed the type for this
1057                      * parameter
1058                      */
1059                     if (Sym->Flags & SC_DEFTYPE) {
1060                         /* Found it, change the default type to the one given */
1061                         ChangeSymType (Sym, ParamTypeCvt (Decl.Type));
1062                         /* Reset the "default type" flag */
1063                         Sym->Flags &= ~SC_DEFTYPE;
1064                     } else {
1065                         /* Type has already been changed */
1066                         Error ("Redefinition for parameter `%s'", Sym->Name);
1067                     }
1068                 } else {
1069                     Error ("Unknown identifier: `%s'", Decl.Ident);
1070                 }
1071             }
1072
1073             if (CurTok.Tok == TOK_COMMA) {
1074                 NextToken ();
1075             } else {
1076                 break;
1077             }
1078
1079         }
1080
1081         /* Variable list must be semicolon terminated */
1082         ConsumeSemi ();
1083     }
1084 }
1085
1086
1087
1088 static void ParseAnsiParamList (FuncDesc* F)
1089 /* Parse a new style (ANSI) parameter list */
1090 {
1091     /* Parse params */
1092     while (CurTok.Tok != TOK_RPAREN) {
1093
1094         DeclSpec        Spec;
1095         Declaration     Decl;
1096         DeclAttr        Attr;
1097
1098         /* Allow an ellipsis as last parameter */
1099         if (CurTok.Tok == TOK_ELLIPSIS) {
1100             NextToken ();
1101             F->Flags |= FD_VARIADIC;
1102             break;
1103         }
1104
1105         /* Read the declaration specifier */
1106         ParseDeclSpec (&Spec, SC_AUTO, T_INT);
1107
1108         /* We accept only auto and register as storage class specifiers */
1109         if ((Spec.StorageClass & SC_AUTO) == SC_AUTO) {
1110             Spec.StorageClass = SC_AUTO | SC_PARAM | SC_DEF;
1111         } else if ((Spec.StorageClass & SC_REGISTER) == SC_REGISTER) {
1112             Spec.StorageClass = SC_REGISTER | SC_STATIC | SC_PARAM | SC_DEF;
1113         } else {
1114             Error ("Illegal storage class");
1115             Spec.StorageClass = SC_AUTO | SC_PARAM | SC_DEF;
1116         }
1117
1118         /* Allow parameters without a name, but remember if we had some to
1119          * eventually print an error message later.
1120          */
1121         ParseDecl (&Spec, &Decl, DM_ACCEPT_IDENT);
1122         if (Decl.Ident[0] == '\0') {
1123
1124             /* Unnamed symbol. Generate a name that is not user accessible,
1125              * then handle the symbol normal.
1126              */
1127             AnonName (Decl.Ident, "param");
1128             F->Flags |= FD_UNNAMED_PARAMS;
1129
1130             /* Clear defined bit on nonames */
1131             Decl.StorageClass &= ~SC_DEF;
1132         }
1133
1134         /* Parse an attribute ### */
1135         ParseAttribute (&Decl, &Attr);
1136
1137         /* Create a symbol table entry */
1138         AddLocalSym (Decl.Ident, ParamTypeCvt (Decl.Type), Decl.StorageClass, 0);
1139
1140         /* Count arguments */
1141         ++F->ParamCount;
1142
1143         /* Check for more parameters */
1144         if (CurTok.Tok == TOK_COMMA) {
1145             NextToken ();
1146         } else {
1147             break;
1148         }
1149     }
1150
1151     /* Skip right paren. We must explicitly check for one here, since some of
1152      * the breaks above bail out without checking.
1153      */
1154     ConsumeRParen ();
1155
1156     /* Check if this is a function definition */
1157     if (CurTok.Tok == TOK_LCURLY) {
1158         /* Print an error if we have unnamed parameters and cc65 extensions
1159          * are disabled.
1160          */
1161         if (IS_Get (&Standard) != STD_CC65 &&
1162             (F->Flags & FD_UNNAMED_PARAMS) != 0) {
1163             Error ("Parameter name omitted");
1164         }
1165     }
1166 }
1167
1168
1169
1170 static FuncDesc* ParseFuncDecl (void)
1171 /* Parse the argument list of a function. */
1172 {
1173     unsigned Offs;
1174     SymEntry* Sym;
1175
1176     /* Create a new function descriptor */
1177     FuncDesc* F = NewFuncDesc ();
1178
1179     /* Enter a new lexical level */
1180     EnterFunctionLevel ();
1181
1182     /* Check for several special parameter lists */
1183     if (CurTok.Tok == TOK_RPAREN) {
1184         /* Parameter list is empty */
1185         F->Flags |= (FD_EMPTY | FD_VARIADIC);
1186     } else if (CurTok.Tok == TOK_VOID && NextTok.Tok == TOK_RPAREN) {
1187         /* Parameter list declared as void */
1188         NextToken ();
1189         F->Flags |= FD_VOID_PARAM;
1190     } else if (CurTok.Tok == TOK_IDENT &&
1191                (NextTok.Tok == TOK_COMMA || NextTok.Tok == TOK_RPAREN)) {
1192         /* If the identifier is a typedef, we have a new style parameter list,
1193          * if it's some other identifier, it's an old style parameter list.
1194          */
1195         Sym = FindSym (CurTok.Ident);
1196         if (Sym == 0 || !SymIsTypeDef (Sym)) {
1197             /* Old style (K&R) function. */
1198             F->Flags |= FD_OLDSTYLE;
1199         }
1200     }
1201
1202     /* Parse params */
1203     if ((F->Flags & FD_OLDSTYLE) == 0) {
1204         /* New style function */
1205         ParseAnsiParamList (F);
1206     } else {
1207         /* Old style function */
1208         ParseOldStyleParamList (F);
1209     }
1210
1211     /* Remember the last function parameter. We need it later for several
1212      * purposes, for example when passing stuff to fastcall functions. Since
1213      * more symbols are added to the table, it is easier if we remember it
1214      * now, since it is currently the last entry in the symbol table.
1215      */
1216     F->LastParam = GetSymTab()->SymTail;
1217
1218     /* Assign offsets. If the function has a variable parameter list,
1219      * there's one additional byte (the arg size).
1220      */
1221     Offs = (F->Flags & FD_VARIADIC)? 1 : 0;
1222     Sym = F->LastParam;
1223     while (Sym) {
1224         unsigned Size = CheckedSizeOf (Sym->Type);
1225         if (SymIsRegVar (Sym)) {
1226             Sym->V.R.SaveOffs = Offs;
1227         } else {
1228             Sym->V.Offs = Offs;
1229         }
1230         Offs += Size;
1231         F->ParamSize += Size;
1232         Sym = Sym->PrevSym;
1233     }
1234
1235     /* Leave the lexical level remembering the symbol tables */
1236     RememberFunctionLevel (F);
1237
1238     /* Return the function descriptor */
1239     return F;
1240 }
1241
1242
1243
1244 static void Declarator (const DeclSpec* Spec, Declaration* D, declmode_t Mode)
1245 /* Recursively process declarators. Build a type array in reverse order. */
1246 {
1247     /* Read optional function or pointer qualifiers. These modify the
1248      * identifier or token to the right. For convenience, we allow the fastcall
1249      * qualifier also for pointers here. If it is a pointer-to-function, the
1250      * qualifier will later be transfered to the function itself. If it's a
1251      * pointer to something else, it will be flagged as an error.
1252      */
1253     TypeCode Qualifiers = OptionalQualifiers (T_QUAL_ADDRSIZE | T_QUAL_FASTCALL);
1254
1255     /* Pointer to something */
1256     if (CurTok.Tok == TOK_STAR) {
1257
1258         /* Skip the star */
1259         NextToken ();
1260
1261         /* Allow const, restrict and volatile qualifiers */
1262         Qualifiers |= OptionalQualifiers (T_QUAL_CONST | T_QUAL_VOLATILE | T_QUAL_RESTRICT);
1263
1264         /* Parse the type, the pointer points to */
1265         Declarator (Spec, D, Mode);
1266
1267         /* Add the type */
1268         AddTypeToDeclaration (D, T_PTR | Qualifiers);
1269         return;
1270     }
1271
1272     if (CurTok.Tok == TOK_LPAREN) {
1273         NextToken ();
1274         Declarator (Spec, D, Mode);
1275         ConsumeRParen ();
1276     } else {
1277         /* Things depend on Mode now:
1278          *  - Mode == DM_NEED_IDENT means:
1279          *      we *must* have a type and a variable identifer.
1280          *  - Mode == DM_NO_IDENT means:
1281          *      we must have a type but no variable identifer
1282          *      (if there is one, it's not read).
1283          *  - Mode == DM_ACCEPT_IDENT means:
1284          *      we *may* have an identifier. If there is an identifier,
1285          *      it is read, but it is no error, if there is none.
1286          */
1287         if (Mode == DM_NO_IDENT) {
1288             D->Ident[0] = '\0';
1289         } else if (CurTok.Tok == TOK_IDENT) {
1290             strcpy (D->Ident, CurTok.Ident);
1291             NextToken ();
1292         } else {
1293             if (Mode == DM_NEED_IDENT) {
1294                 Error ("Identifier expected");
1295             }
1296             D->Ident[0] = '\0';
1297         }
1298     }
1299
1300     while (CurTok.Tok == TOK_LBRACK || CurTok.Tok == TOK_LPAREN) {
1301         if (CurTok.Tok == TOK_LPAREN) {
1302
1303             /* Function declaration */
1304             FuncDesc* F;
1305
1306             /* Skip the opening paren */
1307             NextToken ();
1308
1309             /* Parse the function declaration */
1310             F = ParseFuncDecl ();
1311
1312             /* We cannot specify fastcall for variadic functions */
1313             if ((F->Flags & FD_VARIADIC) && (Qualifiers & T_QUAL_FASTCALL)) {
1314                 Error ("Variadic functions cannot be `__fastcall'");
1315                 Qualifiers &= ~T_QUAL_FASTCALL;
1316             }
1317
1318             /* Add the function type. Be sure to bounds check the type buffer */
1319             NeedTypeSpace (D, 1);
1320             D->Type[D->Index].C = T_FUNC | Qualifiers;
1321             D->Type[D->Index].A.P = F;
1322             ++D->Index;
1323
1324             /* Qualifiers now used */
1325             Qualifiers = T_QUAL_NONE;
1326
1327         } else {
1328             /* Array declaration. */
1329             long Size = UNSPECIFIED;
1330
1331             /* We cannot have any qualifiers for an array */
1332             if (Qualifiers != T_QUAL_NONE) {
1333                 Error ("Invalid qualifiers for array");
1334                 Qualifiers = T_QUAL_NONE;
1335             }
1336
1337             /* Skip the left bracket */
1338             NextToken ();
1339
1340             /* Read the size if it is given */
1341             if (CurTok.Tok != TOK_RBRACK) {
1342                 ExprDesc Expr;
1343                 ConstAbsIntExpr (hie1, &Expr);
1344                 if (Expr.IVal <= 0) {
1345                     if (D->Ident[0] != '\0') {
1346                         Error ("Size of array `%s' is invalid", D->Ident);
1347                     } else {
1348                         Error ("Size of array is invalid");
1349                     }
1350                     Expr.IVal = 1;
1351                 }
1352                 Size = Expr.IVal;
1353             }
1354
1355             /* Skip the right bracket */
1356             ConsumeRBrack ();
1357
1358             /* Add the array type with the size to the type */
1359             NeedTypeSpace (D, 1);
1360             D->Type[D->Index].C = T_ARRAY;
1361             D->Type[D->Index].A.L = Size;
1362             ++D->Index;
1363         }
1364     }
1365
1366     /* If we have remaining qualifiers, flag them as invalid */
1367     if (Qualifiers & T_QUAL_NEAR) {
1368         Error ("Invalid `__near__' qualifier");
1369     }
1370     if (Qualifiers & T_QUAL_FAR) {
1371         Error ("Invalid `__far__' qualifier");
1372     }
1373     if (Qualifiers & T_QUAL_FASTCALL) {
1374         Error ("Invalid `__fastcall__' qualifier");
1375     }
1376 }
1377
1378
1379
1380 /*****************************************************************************/
1381 /*                                   code                                    */
1382 /*****************************************************************************/
1383
1384
1385
1386 Type* ParseType (Type* T)
1387 /* Parse a complete type specification */
1388 {
1389     DeclSpec Spec;
1390     Declaration Decl;
1391
1392     /* Get a type without a default */
1393     InitDeclSpec (&Spec);
1394     ParseTypeSpec (&Spec, -1, T_QUAL_NONE);
1395
1396     /* Parse additional declarators */
1397     ParseDecl (&Spec, &Decl, DM_NO_IDENT);
1398
1399     /* Copy the type to the target buffer */
1400     TypeCopy (T, Decl.Type);
1401
1402     /* Return a pointer to the target buffer */
1403     return T;
1404 }
1405
1406
1407
1408 void ParseDecl (const DeclSpec* Spec, Declaration* D, declmode_t Mode)
1409 /* Parse a variable, type or function declaration */
1410 {
1411     /* Initialize the Declaration struct */
1412     InitDeclaration (D);
1413
1414     /* Get additional declarators and the identifier */
1415     Declarator (Spec, D, Mode);
1416
1417     /* Add the base type. */
1418     NeedTypeSpace (D, TypeLen (Spec->Type) + 1);        /* Bounds check */
1419     TypeCopy (D->Type + D->Index, Spec->Type);
1420
1421     /* Use the storage class from the declspec */
1422     D->StorageClass = Spec->StorageClass;
1423
1424     /* Do several fixes on qualifiers */
1425     FixQualifiers (D->Type);
1426
1427     /* If we have a function, add a special storage class */
1428     if (IsTypeFunc (D->Type)) {
1429         D->StorageClass |= SC_FUNC;
1430     }
1431
1432     /* Check several things for function or function pointer types */
1433     if (IsTypeFunc (D->Type) || IsTypeFuncPtr (D->Type)) {
1434
1435         /* A function. Check the return type */
1436         Type* RetType = GetFuncReturn (D->Type);
1437
1438         /* Functions may not return functions or arrays */
1439         if (IsTypeFunc (RetType)) {
1440             Error ("Functions are not allowed to return functions");
1441         } else if (IsTypeArray (RetType)) {
1442             Error ("Functions are not allowed to return arrays");
1443         }
1444
1445         /* The return type must not be qualified */
1446         if (GetQualifier (RetType) != T_QUAL_NONE && RetType[1].C == T_END) {
1447
1448             if (GetType (RetType) == T_TYPE_VOID) {
1449                 /* A qualified void type is always an error */
1450                 Error ("function definition has qualified void return type");
1451             } else {
1452                 /* For others, qualifiers are ignored */
1453                 Warning ("type qualifiers ignored on function return type");
1454                 RetType[0].C = UnqualifiedType (RetType[0].C);
1455             }
1456         }
1457
1458         /* Warn about an implicit int return in the function */
1459         if ((Spec->Flags & DS_DEF_TYPE) != 0 &&
1460             RetType[0].C == T_INT && RetType[1].C == T_END) {
1461             /* Function has an implicit int return. Output a warning if we don't
1462              * have the C89 standard enabled explicitly.
1463              */
1464             if (IS_Get (&Standard) >= STD_C99) {
1465                 Warning ("Implicit `int' return type is an obsolete feature");
1466             }
1467             GetFuncDesc (D->Type)->Flags |= FD_OLDSTYLE_INTRET;
1468         }
1469
1470     }
1471
1472     /* For anthing that is not a function or typedef, check for an implicit
1473      * int declaration.
1474      */
1475     if ((D->StorageClass & SC_FUNC) != SC_FUNC &&
1476         (D->StorageClass & SC_TYPEDEF) != SC_TYPEDEF) {
1477         /* If the standard was not set explicitly to C89, print a warning
1478          * for variables with implicit int type.
1479          */
1480         if ((Spec->Flags & DS_DEF_TYPE) != 0 && IS_Get (&Standard) >= STD_C99) {
1481             Warning ("Implicit `int' is an obsolete feature");
1482         }
1483     }
1484
1485     /* Check the size of the generated type */
1486     if (!IsTypeFunc (D->Type) && !IsTypeVoid (D->Type)) {
1487         unsigned Size = SizeOf (D->Type);
1488         if (Size >= 0x10000) {
1489             if (D->Ident[0] != '\0') {
1490                 Error ("Size of `%s' is invalid (0x%06X)", D->Ident, Size);
1491             } else {
1492                 Error ("Invalid size in declaration (0x%06X)", Size);
1493             }
1494         }
1495     }
1496
1497 }
1498
1499
1500
1501 void ParseDeclSpec (DeclSpec* D, unsigned DefStorage, long DefType)
1502 /* Parse a declaration specification */
1503 {
1504     TypeCode Qualifiers;
1505
1506     /* Initialize the DeclSpec struct */
1507     InitDeclSpec (D);
1508
1509     /* There may be qualifiers *before* the storage class specifier */
1510     Qualifiers = OptionalQualifiers (T_QUAL_CONST | T_QUAL_VOLATILE);
1511
1512     /* Now get the storage class specifier for this declaration */
1513     ParseStorageClass (D, DefStorage);
1514
1515     /* Parse the type specifiers passing any initial type qualifiers */
1516     ParseTypeSpec (D, DefType, Qualifiers);
1517 }
1518
1519
1520
1521 void CheckEmptyDecl (const DeclSpec* D)
1522 /* Called after an empty type declaration (that is, a type declaration without
1523  * a variable). Checks if the declaration does really make sense and issues a
1524  * warning if not.
1525  */
1526 {
1527     if ((D->Flags & DS_EXTRA_TYPE) == 0) {
1528         Warning ("Useless declaration");
1529     }
1530 }
1531
1532
1533
1534 static void SkipInitializer (unsigned BracesExpected)
1535 /* Skip the remainder of an initializer in case of errors. Try to be somewhat
1536  * smart so we don't have too many following errors.
1537  */
1538 {
1539     while (CurTok.Tok != TOK_CEOF && CurTok.Tok != TOK_SEMI && BracesExpected > 0) {
1540         switch (CurTok.Tok) {
1541             case TOK_RCURLY:    --BracesExpected;   break;
1542             case TOK_LCURLY:    ++BracesExpected;   break;
1543             default:                                break;
1544         }
1545         NextToken ();
1546     }
1547 }
1548
1549
1550
1551 static unsigned OpeningCurlyBraces (unsigned BracesNeeded)
1552 /* Accept any number of opening curly braces around an initialization, skip
1553  * them and return the number. If the number of curly braces is less than
1554  * BracesNeeded, issue a warning.
1555  */
1556 {
1557     unsigned BraceCount = 0;
1558     while (CurTok.Tok == TOK_LCURLY) {
1559         ++BraceCount;
1560         NextToken ();
1561     }
1562     if (BraceCount < BracesNeeded) {
1563         Error ("`{' expected");
1564     }
1565     return BraceCount;
1566 }
1567
1568
1569
1570 static void ClosingCurlyBraces (unsigned BracesExpected)
1571 /* Accept and skip the given number of closing curly braces together with
1572  * an optional comma. Output an error messages, if the input does not contain
1573  * the expected number of braces.
1574  */
1575 {
1576     while (BracesExpected) {
1577         if (CurTok.Tok == TOK_RCURLY) {
1578             NextToken ();
1579         } else if (CurTok.Tok == TOK_COMMA && NextTok.Tok == TOK_RCURLY) {
1580             NextToken ();
1581             NextToken ();
1582         } else {
1583             Error ("`}' expected");
1584             return;
1585         }
1586         --BracesExpected;
1587     }
1588 }
1589
1590
1591
1592 static void DefineData (ExprDesc* Expr)
1593 /* Output a data definition for the given expression */
1594 {
1595     switch (ED_GetLoc (Expr)) {
1596
1597         case E_LOC_ABS:
1598             /* Absolute: numeric address or const */
1599             g_defdata (TypeOf (Expr->Type) | CF_CONST, Expr->IVal, 0);
1600             break;
1601
1602         case E_LOC_GLOBAL:
1603             /* Global variable */
1604             g_defdata (CF_EXTERNAL, Expr->Name, Expr->IVal);
1605             break;
1606
1607         case E_LOC_STATIC:
1608         case E_LOC_LITERAL:
1609             /* Static variable or literal in the literal pool */
1610             g_defdata (CF_STATIC, Expr->Name, Expr->IVal);
1611             break;
1612
1613         case E_LOC_REGISTER:
1614             /* Register variable. Taking the address is usually not
1615              * allowed.
1616              */
1617             if (IS_Get (&AllowRegVarAddr) == 0) {
1618                 Error ("Cannot take the address of a register variable");
1619             }
1620             g_defdata (CF_REGVAR, Expr->Name, Expr->IVal);
1621             break;
1622
1623         case E_LOC_STACK:
1624         case E_LOC_PRIMARY:
1625         case E_LOC_EXPR:
1626             Error ("Non constant initializer");
1627             break;
1628
1629         default:
1630             Internal ("Unknown constant type: 0x%04X", ED_GetLoc (Expr));
1631     }
1632 }
1633
1634
1635
1636 static unsigned ParseScalarInit (Type* T)
1637 /* Parse initializaton for scalar data types. Return the number of data bytes. */
1638 {
1639     ExprDesc ED;
1640
1641     /* Optional opening brace */
1642     unsigned BraceCount = OpeningCurlyBraces (0);
1643
1644     /* We warn if an initializer for a scalar contains braces, because this is
1645      * quite unusual and often a sign for some problem in the input.
1646      */
1647     if (BraceCount > 0) {
1648         Warning ("Braces around scalar initializer");
1649     }
1650
1651     /* Get the expression and convert it to the target type */
1652     ConstExpr (hie1, &ED);
1653     TypeConversion (&ED, T);
1654
1655     /* Output the data */
1656     DefineData (&ED);
1657
1658     /* Close eventually opening braces */
1659     ClosingCurlyBraces (BraceCount);
1660
1661     /* Done */
1662     return SizeOf (T);
1663 }
1664
1665
1666
1667 static unsigned ParsePointerInit (Type* T)
1668 /* Parse initializaton for pointer data types. Return the number of data bytes. */
1669 {
1670     /* Optional opening brace */
1671     unsigned BraceCount = OpeningCurlyBraces (0);
1672
1673     /* Expression */
1674     ExprDesc ED;
1675     ConstExpr (hie1, &ED);
1676     TypeConversion (&ED, T);
1677
1678     /* Output the data */
1679     DefineData (&ED);
1680
1681     /* Close eventually opening braces */
1682     ClosingCurlyBraces (BraceCount);
1683
1684     /* Done */
1685     return SIZEOF_PTR;
1686 }
1687
1688
1689
1690 static unsigned ParseArrayInit (Type* T, int AllowFlexibleMembers)
1691 /* Parse initializaton for arrays. Return the number of data bytes. */
1692 {
1693     int Count;
1694
1695     /* Get the array data */
1696     Type* ElementType    = GetElementType (T);
1697     unsigned ElementSize = CheckedSizeOf (ElementType);
1698     long ElementCount    = GetElementCount (T);
1699
1700     /* Special handling for a character array initialized by a literal */
1701     if (IsTypeChar (ElementType) &&
1702         (CurTok.Tok == TOK_SCONST ||
1703         (CurTok.Tok == TOK_LCURLY && NextTok.Tok == TOK_SCONST))) {
1704
1705         /* Char array initialized by string constant */
1706         int NeedParen;
1707         const char* Str;
1708
1709         /* If we initializer is enclosed in brackets, remember this fact and
1710          * skip the opening bracket.
1711          */
1712         NeedParen = (CurTok.Tok == TOK_LCURLY);
1713         if (NeedParen) {
1714             NextToken ();
1715         }
1716
1717         /* Get the initializer string and its size */
1718         Str = GetLiteral (CurTok.IVal);
1719         Count = GetLiteralPoolOffs () - CurTok.IVal;
1720
1721         /* Translate into target charset */
1722         TranslateLiteralPool (CurTok.IVal);
1723
1724         /* If the array is one too small for the string literal, omit the
1725          * trailing zero.
1726          */
1727         if (ElementCount != UNSPECIFIED &&
1728             ElementCount != FLEXIBLE    &&
1729             Count        == ElementCount + 1) {
1730             /* Omit the trailing zero */
1731             --Count;
1732         }
1733
1734         /* Output the data */
1735         g_defbytes (Str, Count);
1736
1737         /* Remove string from pool */
1738         ResetLiteralPoolOffs (CurTok.IVal);
1739         NextToken ();
1740
1741         /* If the initializer was enclosed in curly braces, we need a closing
1742          * one.
1743          */
1744         if (NeedParen) {
1745             ConsumeRCurly ();
1746         }
1747
1748     } else {
1749
1750         /* Curly brace */
1751         ConsumeLCurly ();
1752
1753         /* Initialize the array members */
1754         Count = 0;
1755         while (CurTok.Tok != TOK_RCURLY) {
1756             /* Flexible array members may not be initialized within
1757              * an array (because the size of each element may differ
1758              * otherwise).
1759              */
1760             ParseInitInternal (ElementType, 0);
1761             ++Count;
1762             if (CurTok.Tok != TOK_COMMA)
1763                 break;
1764             NextToken ();
1765         }
1766
1767         /* Closing curly braces */
1768         ConsumeRCurly ();
1769     }
1770
1771     if (ElementCount == UNSPECIFIED) {
1772         /* Number of elements determined by initializer */
1773         SetElementCount (T, Count);
1774         ElementCount = Count;
1775     } else if (ElementCount == FLEXIBLE && AllowFlexibleMembers) {
1776         /* In non ANSI mode, allow initialization of flexible array
1777          * members.
1778          */
1779         ElementCount = Count;
1780     } else if (Count < ElementCount) {
1781         g_zerobytes ((ElementCount - Count) * ElementSize);
1782     } else if (Count > ElementCount) {
1783         Error ("Too many initializers");
1784     }
1785     return ElementCount * ElementSize;
1786 }
1787
1788
1789
1790 static unsigned ParseStructInit (Type* T, int AllowFlexibleMembers)
1791 /* Parse initialization of a struct or union. Return the number of data bytes. */
1792 {
1793     SymEntry* Entry;
1794     SymTable* Tab;
1795     unsigned  StructSize;
1796     unsigned  Size;
1797
1798
1799     /* Consume the opening curly brace */
1800     ConsumeLCurly ();
1801
1802     /* Get a pointer to the struct entry from the type */
1803     Entry = GetSymEntry (T);
1804
1805     /* Get the size of the struct from the symbol table entry */
1806     StructSize = Entry->V.S.Size;
1807
1808     /* Check if this struct definition has a field table. If it doesn't, it
1809      * is an incomplete definition.
1810      */
1811     Tab = Entry->V.S.SymTab;
1812     if (Tab == 0) {
1813         Error ("Cannot initialize variables with incomplete type");
1814         /* Try error recovery */
1815         SkipInitializer (1);
1816         /* Nothing initialized */
1817         return 0;
1818     }
1819
1820     /* Get a pointer to the list of symbols */
1821     Entry = Tab->SymHead;
1822
1823     /* Initialize fields */
1824     Size = 0;
1825     while (CurTok.Tok != TOK_RCURLY) {
1826         if (Entry == 0) {
1827             Error ("Too many initializers");
1828             SkipInitializer (1);
1829             return Size;
1830         }
1831         /* Parse initialization of one field. Flexible array members may
1832          * only be initialized if they are the last field (or part of the
1833          * last struct field).
1834          */
1835         Size += ParseInitInternal (Entry->Type, AllowFlexibleMembers && Entry->NextSym == 0);
1836         Entry = Entry->NextSym;
1837         if (CurTok.Tok != TOK_COMMA)
1838             break;
1839         NextToken ();
1840     }
1841
1842     /* Consume the closing curly brace */
1843     ConsumeRCurly ();
1844
1845     /* If there are struct fields left, reserve additional storage */
1846     if (Size < StructSize) {
1847         g_zerobytes (StructSize - Size);
1848         Size = StructSize;
1849     }
1850
1851     /* Return the actual number of bytes initialized. This number may be
1852      * larger than StructSize if flexible array members are present and were
1853      * initialized (possible in non ANSI mode).
1854      */
1855     return Size;
1856 }
1857
1858
1859
1860 static unsigned ParseVoidInit (void)
1861 /* Parse an initialization of a void variable (special cc65 extension).
1862  * Return the number of bytes initialized.
1863  */
1864 {
1865     ExprDesc Expr;
1866     unsigned Size;
1867
1868     /* Opening brace */
1869     ConsumeLCurly ();
1870
1871     /* Allow an arbitrary list of values */
1872     Size = 0;
1873     do {
1874         ConstExpr (hie1, &Expr);
1875         switch (UnqualifiedType (Expr.Type[0].C)) {
1876
1877             case T_SCHAR:
1878             case T_UCHAR:
1879                 if (ED_IsConstAbsInt (&Expr)) {
1880                     /* Make it byte sized */
1881                     Expr.IVal &= 0xFF;
1882                 }
1883                 DefineData (&Expr);
1884                 Size += SIZEOF_CHAR;
1885                 break;
1886
1887             case T_SHORT:
1888             case T_USHORT:
1889             case T_INT:
1890             case T_UINT:
1891             case T_PTR:
1892             case T_ARRAY:
1893                 if (ED_IsConstAbsInt (&Expr)) {
1894                     /* Make it word sized */
1895                     Expr.IVal &= 0xFFFF;
1896                 }
1897                 DefineData (&Expr);
1898                 Size += SIZEOF_INT;
1899                 break;
1900
1901             case T_LONG:
1902             case T_ULONG:
1903                 if (ED_IsConstAbsInt (&Expr)) {
1904                     /* Make it dword sized */
1905                     Expr.IVal &= 0xFFFFFFFF;
1906                 }
1907                 DefineData (&Expr);
1908                 Size += SIZEOF_LONG;
1909                 break;
1910
1911             default:
1912                 Error ("Illegal type in initialization");
1913                 break;
1914
1915         }
1916
1917         if (CurTok.Tok != TOK_COMMA) {
1918             break;
1919         }
1920         NextToken ();
1921
1922     } while (CurTok.Tok != TOK_RCURLY);
1923
1924     /* Closing brace */
1925     ConsumeRCurly ();
1926
1927     /* Return the number of bytes initialized */
1928     return Size;
1929 }
1930
1931
1932
1933 static unsigned ParseInitInternal (Type* T, int AllowFlexibleMembers)
1934 /* Parse initialization of variables. Return the number of data bytes. */
1935 {
1936     switch (UnqualifiedType (T->C)) {
1937
1938         case T_SCHAR:
1939         case T_UCHAR:
1940         case T_SHORT:
1941         case T_USHORT:
1942         case T_INT:
1943         case T_UINT:
1944         case T_LONG:
1945         case T_ULONG:
1946         case T_FLOAT:
1947         case T_DOUBLE:
1948             return ParseScalarInit (T);
1949
1950         case T_PTR:
1951             return ParsePointerInit (T);
1952
1953         case T_ARRAY:
1954             return ParseArrayInit (T, AllowFlexibleMembers);
1955
1956         case T_STRUCT:
1957         case T_UNION:
1958             return ParseStructInit (T, AllowFlexibleMembers);
1959
1960         case T_VOID:
1961             if (IS_Get (&Standard) == STD_CC65) {
1962                 /* Special cc65 extension in non ANSI mode */
1963                 return ParseVoidInit ();
1964             }
1965             /* FALLTHROUGH */
1966
1967         default:
1968             Error ("Illegal type");
1969             return SIZEOF_CHAR;
1970
1971     }
1972 }
1973
1974
1975
1976 unsigned ParseInit (Type* T)
1977 /* Parse initialization of variables. Return the number of data bytes. */
1978 {
1979     /* Parse the initialization. Flexible array members can only be initialized
1980      * in cc65 mode.
1981      */
1982     unsigned Size = ParseInitInternal (T, IS_Get (&Standard) == STD_CC65);
1983
1984     /* The initialization may not generate code on global level, because code
1985      * outside function scope will never get executed.
1986      */
1987     if (HaveGlobalCode ()) {
1988         Error ("Non constant initializers");
1989         RemoveGlobalCode ();
1990     }
1991
1992     /* Return the size needed for the initialization */
1993     return Size;
1994 }
1995
1996
1997