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