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