/* */
/* */
/* */
-/* (C) 2000-2004 Ullrich von Bassewitz */
-/* Römerstrasse 52 */
-/* D-70794 Filderstadt */
-/* EMail: uz@cc65.org */
+/* (C) 2000-2009, Ullrich von Bassewitz */
+/* Roemerstrasse 52 */
+/* D-70794 Filderstadt */
+/* EMail: uz@cc65.org */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
+static unsigned AllocLabel (void (*UseSeg) ())
+/* Switch to a segment, define a local label and return it */
+{
+ unsigned Label;
+
+ /* Switch to the segment */
+ UseSeg ();
+
+ /* Define the variable label */
+ Label = GetLocalLabel ();
+ g_defdatalabel (Label);
+
+ /* Return the label */
+ return Label;
+}
+
+
+
+static unsigned AllocStorage (void (*UseSeg) (), unsigned Size)
+/* Reserve Size bytes of BSS storage prefixed by a local label. Return the
+ * label.
+ */
+{
+ /* Switch to the segment and define the label */
+ unsigned Label = AllocLabel (UseSeg);
+
+ /* Reserve space for the data */
+ g_res (Size);
+
+ /* Return the label */
+ return Label;
+}
+
+
+
static unsigned ParseRegisterDecl (Declaration* Decl, unsigned* SC, int Reg)
/* Parse the declaration of a register variable. The function returns the
* symbol data, which is the offset of the variable in the register bank.
/* Special handling for compound types */
if (IsCompound) {
- /* Switch to read only data */
- g_userodata ();
-
- /* Define a label for the initialization data */
- InitLabel = GetLocalLabel ();
- g_defdatalabel (InitLabel);
+ /* Switch to read only data and define a label for the
+ * initialization data.
+ */
+ InitLabel = AllocLabel (g_userodata);
/* Parse the initialization generating a memory image of the
* data in the RODATA segment. The function does return the size
{
unsigned Flags;
unsigned SymData;
- unsigned InitLabel;
/* Determine if this is a compound variable */
int IsCompound = IsClassStruct (Decl->Type) || IsTypeArray (Decl->Type);
/* Special handling for compound types */
if (IsCompound) {
- /* Switch to read only data */
- g_userodata ();
-
- /* Define a label for the initialization data */
- InitLabel = GetLocalLabel ();
- g_defdatalabel (InitLabel);
+ /* Switch to read only data and define a label for the
+ * initialization data.
+ */
+ unsigned InitLabel = AllocLabel (g_userodata);
/* Parse the initialization generating a memory image of the
* data in the RODATA segment. The function will return the
/* Static local variables. */
*SC = (*SC & ~SC_AUTO) | SC_STATIC;
- /* Put them into the BSS */
- g_usebss ();
-
- /* Define the variable label */
- SymData = GetLocalLabel ();
- g_defdatalabel (SymData);
-
- /* Reserve space for the data */
- g_res (Size);
-
/* Allow assignments */
if (CurTok.Tok == TOK_ASSIGN) {
if (IsCompound) {
- /* Switch to read only data */
- g_userodata ();
-
- /* Define a label for the initialization data */
- InitLabel = GetLocalLabel ();
- g_defdatalabel (InitLabel);
+ /* Switch to read only data and define a label for the
+ * initialization data.
+ */
+ unsigned InitLabel = AllocLabel (g_userodata);
/* Parse the initialization generating a memory image of the
* data in the RODATA segment.
*/
- ParseInit (Decl->Type);
+ Size = ParseInit (Decl->Type);
+
+ /* Allocate a label and space for the variable */
+ SymData = AllocStorage (g_usebss, Size);
/* Generate code to copy this data into the variable space */
g_initstatic (InitLabel, SymData, Size);
} else {
+ /* Allocate a label and space for the variable */
+ SymData = AllocStorage (g_usebss, Size);
+
/* Parse the expression */
hie1 (&Expr);
/* Mark the variable as referenced */
*SC |= SC_REF;
+
+ } else {
+
+ /* No assignment - allocate a label and space for the variable */
+ SymData = AllocStorage (g_usebss, Size);
+
}
}
*/
{
unsigned SymData;
-
- /* Get the size of the variable */
- unsigned Size = SizeOf (Decl->Type);
+ unsigned Size;
/* Static data */
if (CurTok.Tok == TOK_ASSIGN) {
- /* Initialization ahead, switch to data segment */
- if (IsQualConst (Decl->Type)) {
- g_userodata ();
+ /* Initialization ahead, switch to data segment and define a label.
+ * For arrays, we need to check the elements of the array for
+ * constness, not the array itself.
+ */
+ if (IsQualConst (Decl->Type) ||
+ (IsTypeArray (Decl->Type) && IsQualConst (GetElementType (Decl->Type)))) {
+ SymData = AllocLabel (g_userodata);
} else {
- g_usedata ();
+ SymData = AllocLabel (g_usedata);
}
- /* Define the variable label */
- SymData = GetLocalLabel ();
- g_defdatalabel (SymData);
-
/* Skip the '=' */
NextToken ();
/* Allow initialization of static vars */
- ParseInit (Decl->Type);
-
- /* If the previous size has been unknown, it must be known now */
- if (Size == 0) {
- Size = SizeOf (Decl->Type);
- }
+ Size = ParseInit (Decl->Type);
/* Mark the variable as referenced */
*SC |= SC_REF;
} else {
- /* Uninitialized data, use BSS segment */
- g_usebss ();
+ /* Get the size of the variable */
+ Size = SizeOf (Decl->Type);
- /* Define the variable label */
- SymData = GetLocalLabel ();
- g_defdatalabel (SymData);
-
- /* Reserve space for the data */
- g_res (Size);
+ /* Allocate a label and space for the variable in the BSS segment */
+ SymData = AllocStorage (g_usebss, Size);
}
ParseDecl (Spec, &Decl, DM_NEED_IDENT);
/* Set the correct storage class for functions */
- if (IsTypeFunc (Decl.Type)) {
+ if ((Decl.StorageClass & SC_FUNC) == SC_FUNC) {
/* Function prototypes are always external */
if ((Decl.StorageClass & SC_EXTERN) == 0) {
Warning ("Function must be extern");
}
- Decl.StorageClass |= SC_FUNC | SC_EXTERN;
-
+ Decl.StorageClass |= SC_EXTERN;
}
/* If we don't have a name, this was flagged as an error earlier.
} else {
Internal ("Invalid storage class in ParseOneDecl: %04X", Decl.StorageClass);
}
-
- /* If the standard was not set explicitly to C89, print a warning
- * for variables with implicit int type.
- */
- if ((Spec->Flags & DS_DEF_TYPE) != 0 && IS_Get (&Standard) >= STD_C99) {
- Warning ("Implicit `int' is an obsolete feature");
- }
}
/* If the symbol is not marked as external, it will be defined now */