-static void ParseOneDecl (const DeclSpec* Spec)
-/* Parse one variable declaration */
+static unsigned ParseAutoDecl (Declaration* Decl, unsigned Size, unsigned* SC)
+/* Parse the declaration of an auto variable. The function returns the symbol
+ * data, which is the offset for variables on the stack, and the label for
+ * static variables.
+ */
{
- int Size; /* Size of an auto variable */
- int SC; /* Storage class for symbol */
- int SymData = 0; /* Symbol data (offset, label name, ...) */
- unsigned flags = 0; /* Code generator flags */
- Declaration Decl; /* Declaration data structure */
+ unsigned Flags;
+ unsigned SymData;
- /* Remember the storage class for the new symbol */
- SC = Spec->StorageClass;
+ /* Check if this is a variable on the stack or in static memory */
+ if (StaticLocals == 0) {
- /* Read the declaration */
- ParseDecl (Spec, &Decl, DM_NEED_IDENT);
+ /* Change SC in case it was register */
+ *SC = (*SC & ~SC_REGISTER) | SC_AUTO;
+ if (CurTok.Tok == TOK_ASSIGN) {
- /* Set the correct storage class for functions */
- if (IsTypeFunc (Decl.Type)) {
- /* Function prototypes are always external */
- if ((SC & SC_EXTERN) == 0) {
- Warning ("Function must be extern");
- }
- SC |= SC_FUNC | SC_EXTERN;
+ ExprDesc lval;
- }
+ /* Allocate previously reserved local space */
+ F_AllocLocalSpace (CurrentFunc);
- /* If we don't have a name, this was flagged as an error earlier.
- * To avoid problems later, use an anonymous name here.
- */
- if (Decl.Ident[0] == '\0') {
- AnonName (Decl.Ident, "param");
- }
+ /* Skip the '=' */
+ NextToken ();
- /* Handle anything that needs storage (no functions, no typdefs) */
- if ((SC & SC_FUNC) != SC_FUNC && (SC & SC_TYPEDEF) != SC_TYPEDEF) {
+ /* Setup the type flags for the assignment */
+ Flags = (Size == 1)? CF_FORCECHAR : CF_NONE;
- /* Get the size of the variable */
- Size = SizeOf (Decl.Type);
+ /* Get the expression into the primary */
+ if (evalexpr (Flags, hie1, &lval) == 0) {
+ /* Constant expression. Adjust the types */
+ assignadjust (Decl->Type, &lval);
+ Flags |= CF_CONST;
+ } else {
+ /* Expression is not constant and in the primary */
+ assignadjust (Decl->Type, &lval);
+ }
- /* */
- if (SC & (SC_AUTO | SC_REGISTER)) {
+ /* Push the value */
+ g_push (Flags | TypeOf (Decl->Type), lval.ConstVal);
- /* Auto variable */
- if (StaticLocals == 0) {
+ /* Mark the variable as referenced */
+ *SC |= SC_REF;
- /* Change SC in case it was register */
- SC = (SC & ~SC_REGISTER) | SC_AUTO;
- if (CurTok.Tok == TOK_ASSIGN) {
+ /* Variable is located at the current SP */
+ SymData = oursp;
- ExprDesc lval;
+ } else {
+ /* Non-initialized local variable. Just keep track of
+ * the space needed.
+ */
+ SymData = F_ReserveLocalSpace (CurrentFunc, Size);
+ }
- /* Allocate previously reserved local space */
- F_AllocLocalSpace (CurrentFunc);
+ } else {
- /* Skip the '=' */
- NextToken ();
+ /* Static local variables. */
+ *SC = (*SC & ~(SC_REGISTER | SC_AUTO)) | SC_STATIC;
- /* Setup the type flags for the assignment */
- flags = Size == 1? CF_FORCECHAR : CF_NONE;
+ /* Put them into the BSS */
+ g_usebss ();
- /* Get the expression into the primary */
- if (evalexpr (flags, hie1, &lval) == 0) {
- /* Constant expression. Adjust the types */
- assignadjust (Decl.Type, &lval);
- flags |= CF_CONST;
- } else {
- /* Expression is not constant and in the primary */
- assignadjust (Decl.Type, &lval);
- }
+ /* Define the variable label */
+ SymData = GetLocalLabel ();
+ g_defdatalabel (SymData);
- /* Push the value */
- g_push (flags | TypeOf (Decl.Type), lval.ConstVal);
+ /* Reserve space for the data */
+ g_res (Size);
- /* Mark the variable as referenced */
- SC |= SC_REF;
+ /* Allow assignments */
+ if (CurTok.Tok == TOK_ASSIGN) {
- /* Variable is located at the current SP */
- SymData = oursp;
+ ExprDesc lval;
- } else {
- /* Non-initialized local variable. Just keep track of
- * the space needed.
- */
- SymData = F_ReserveLocalSpace (CurrentFunc, Size);
- }
+ /* Skip the '=' */
+ NextToken ();
- } else {
+ /* Setup the type flags for the assignment */
+ Flags = (Size == 1)? CF_FORCECHAR : CF_NONE;
- /* Static local variables. */
- SC = (SC & ~(SC_REGISTER | SC_AUTO)) | SC_STATIC;
+ /* Get the expression into the primary */
+ if (evalexpr (Flags, hie1, &lval) == 0) {
+ /* Constant expression. Adjust the types */
+ assignadjust (Decl->Type, &lval);
+ Flags |= CF_CONST;
+ /* Load it into the primary */
+ exprhs (Flags, 0, &lval);
+ } else {
+ /* Expression is not constant and in the primary */
+ assignadjust (Decl->Type, &lval);
+ }
- /* Put them into the BSS */
- g_usebss ();
+ /* Store the value into the variable */
+ g_putstatic (Flags | TypeOf (Decl->Type), SymData, 0);
- /* Define the variable label */
- SymData = GetLocalLabel ();
- g_defdatalabel (SymData);
+ /* Mark the variable as referenced */
+ *SC |= SC_REF;
+ }
+ }
- /* Reserve space for the data */
- g_res (Size);
+ /* Return the symbol data */
+ return SymData;
+}
- /* Allow assignments */
- if (CurTok.Tok == TOK_ASSIGN) {
- ExprDesc lval;
- /* Skip the '=' */
- NextToken ();
+static unsigned ParseStaticDecl (Declaration* Decl, unsigned Size, unsigned* SC)
+/* Parse the declaration of a static variable. The function returns the symbol
+ * data, which is the asm label of the variable.
+ */
+{
+ unsigned SymData;
- /* Setup the type flags for the assignment */
- flags = Size == 1? CF_FORCECHAR : CF_NONE;
+ /* Static data */
+ if (CurTok.Tok == TOK_ASSIGN) {
- /* Get the expression into the primary */
- if (evalexpr (flags, hie1, &lval) == 0) {
- /* Constant expression. Adjust the types */
- assignadjust (Decl.Type, &lval);
- flags |= CF_CONST;
- /* Load it into the primary */
- exprhs (flags, 0, &lval);
- } else {
- /* Expression is not constant and in the primary */
- assignadjust (Decl.Type, &lval);
- }
+ /* Initialization ahead, switch to data segment */
+ if (IsQualConst (Decl->Type)) {
+ g_userodata ();
+ } else {
+ g_usedata ();
+ }
- /* Store the value into the variable */
- g_putstatic (flags | TypeOf (Decl.Type), SymData, 0);
+ /* Define the variable label */
+ SymData = GetLocalLabel ();
+ g_defdatalabel (SymData);
- /* Mark the variable as referenced */
- SC |= SC_REF;
- }
- }
+ /* Skip the '=' */
+ NextToken ();
- } else if ((SC & SC_STATIC) == SC_STATIC) {
+ /* Allow initialization of static vars */
+ ParseInit (Decl->Type);
- /* Static data */
- if (CurTok.Tok == TOK_ASSIGN) {
+ /* If the previous size has been unknown, it must be known now */
+ if (Size == 0) {
+ Size = SizeOf (Decl->Type);
+ }
- /* Initialization ahead, switch to data segment */
- if (IsQualConst (Decl.Type)) {
- g_userodata ();
- } else {
- g_usedata ();
- }
+ /* Mark the variable as referenced */
+ *SC |= SC_REF;
- /* Define the variable label */
- SymData = GetLocalLabel ();
- g_defdatalabel (SymData);
+ } else {
- /* Skip the '=' */
- NextToken ();
+ /* Uninitialized data, use BSS segment */
+ g_usebss ();
- /* Allow initialization of static vars */
- ParseInit (Decl.Type);
+ /* Define the variable label */
+ SymData = GetLocalLabel ();
+ g_defdatalabel (SymData);
- /* If the previous size has been unknown, it must be known now */
- if (Size == 0) {
- Size = SizeOf (Decl.Type);
- }
+ /* Reserve space for the data */
+ g_res (Size);
- /* Mark the variable as referenced */
- SC |= SC_REF;
+ }
- } else {
+ /* Return the symbol data */
+ return SymData;
+}
- /* Uninitialized data, use BSS segment */
- g_usebss ();
- /* Define the variable label */
- SymData = GetLocalLabel ();
- g_defdatalabel (SymData);
- /* Reserve space for the data */
- g_res (Size);
+static void ParseOneDecl (const DeclSpec* Spec)
+/* Parse one variable declaration */
+{
+ unsigned SC; /* Storage class for symbol */
+ unsigned Size; /* Size of the data object */
+ unsigned SymData = 0; /* Symbol data (offset, label name, ...) */
+ Declaration Decl; /* Declaration data structure */
+
+ /* Remember the storage class for the new symbol */
+ SC = Spec->StorageClass;
- }
- }
+ /* Read the declaration */
+ ParseDecl (Spec, &Decl, DM_NEED_IDENT);
+
+ /* Set the correct storage class for functions */
+ if (IsTypeFunc (Decl.Type)) {
+ /* Function prototypes are always external */
+ if ((SC & SC_EXTERN) == 0) {
+ Warning ("Function must be extern");
+ }
+ SC |= SC_FUNC | SC_EXTERN;
+
+ }
+
+ /* If we don't have a name, this was flagged as an error earlier.
+ * To avoid problems later, use an anonymous name here.
+ */
+ if (Decl.Ident[0] == '\0') {
+ AnonName (Decl.Ident, "param");
+ }
+
+ /* Handle anything that needs storage (no functions, no typdefs) */
+ if ((SC & SC_FUNC) != SC_FUNC && (SC & SC_TYPEDEF) != SC_TYPEDEF) {
+
+ /* Get the size of the variable */
+ Size = SizeOf (Decl.Type);
+
+ /* */
+ if (SC & (SC_AUTO | SC_REGISTER)) {
+
+ /* Auto variable */
+ SymData = ParseAutoDecl (&Decl, Size, &SC);
+
+ } else if ((SC & SC_STATIC) == SC_STATIC) {
+
+ /* Static variable */
+ SymData = ParseStaticDecl (&Decl, Size, &SC);
+
+ }
/* Cannot allocate a variable of zero size */
if (Size == 0) {