]> git.sur5r.net Git - cc65/blobdiff - src/cc65/declare.c
Small but significant shift optimization
[cc65] / src / cc65 / declare.c
index feac79212ea5a21a2a910cac971de40c1529711d..e2770e1ca0e9f39429cc46082a5403d1f3618923 100644 (file)
@@ -6,7 +6,7 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 1998-2001 Ullrich von Bassewitz                                       */
+/* (C) 1998-2002 Ullrich von Bassewitz                                       */
 /*               Wacholderweg 14                                             */
 /*               D-70597 Stuttgart                                           */
 /* EMail:        uz@musoftware.de                                            */
@@ -230,7 +230,7 @@ static void ParseEnumDecl (void)
        if (CurTok.Tok == TOK_ASSIGN) {
            ExprDesc lval;
            NextToken ();
-           constexpr (&lval);
+           ConstExpr (&lval);
            EnumVal = lval.ConstVal;
        }
 
@@ -301,7 +301,7 @@ static SymEntry* ParseStructDecl (const char* Name, type StructType)
            AddLocalSym (Decl.Ident, Decl.Type, SC_SFLD, (StructType == T_STRUCT)? Size : 0);
 
            /* Calculate offset of next field/size of the union */
-           Offs = SizeOf (Decl.Type);
+           Offs = CheckedSizeOf (Decl.Type);
            if (StructType == T_STRUCT) {
                Size += Offs;
            } else {
@@ -417,7 +417,7 @@ static void ParseTypeSpec (DeclSpec* D, int Default)
                    optionalint ();
                    D->Type[0] = T_LONG;
                    D->Type[1] = T_END;
-                   break;
+                   break;
 
                case TOK_INT:
                    NextToken ();
@@ -454,13 +454,13 @@ static void ParseTypeSpec (DeclSpec* D, int Default)
                    D->Type[1] = T_END;
                    break;
 
-               case TOK_INT:
+               case TOK_INT:
                    NextToken ();
                    /* FALL THROUGH */
 
                default:
                    D->Type[0] = T_UINT;
-                   D->Type[1] = T_END;
+                   D->Type[1] = T_END;
                    break;
            }
            break;
@@ -497,7 +497,7 @@ static void ParseTypeSpec (DeclSpec* D, int Default)
                        if (SymIsLocal (Entry) && (Entry->Flags & SC_ENUM) == 0) {
                            Error ("Symbol `%s' is already different kind", Entry->Name);
                        }
-                   } else {
+                   } else {
                        /* Insert entry into table ### */
                    }
                    /* Skip the identifier */
@@ -626,7 +626,7 @@ static void ParseOldStyleParamList (FuncDesc* F)
            }
 
            if (CurTok.Tok == TOK_COMMA) {
-               NextToken ();
+               NextToken ();
            } else {
                break;
            }
@@ -720,7 +720,7 @@ static void ParseAnsiParamList (FuncDesc* F)
 
 
 
-static FuncDesc* ParseFuncDecl (void)
+static FuncDesc* ParseFuncDecl (const DeclSpec* Spec)
 /* Parse the argument list of a function. */
 {
     unsigned Offs;
@@ -749,6 +749,14 @@ static FuncDesc* ParseFuncDecl (void)
        if (Sym == 0 || !IsTypeDef (Sym)) {
            /* Old style (K&R) function. Assume variable param list. */
            F->Flags |= (FD_OLDSTYLE | FD_VARIADIC);
+
+           /* Check for an implicit int return in the K&R function */
+           if ((Spec->Flags & DS_DEF_TYPE) != 0 &&
+               Spec->Type[0] == T_INT   &&
+               Spec->Type[1] == T_END) {
+               /* Function has an implicit int return */
+               F->Flags |= FD_OLDSTYLE_INTRET;
+           }
        }
     }
 
@@ -767,7 +775,7 @@ static FuncDesc* ParseFuncDecl (void)
     Offs = (F->Flags & FD_VARIADIC)? 1 : 0;
     Sym = GetSymTab()->SymTail;
     while (Sym) {
-       unsigned Size = SizeOf (Sym->Type);
+       unsigned Size = CheckedSizeOf (Sym->Type);
        Sym->V.Offs = Offs;
                Offs += Size;
        F->ParamSize += Size;
@@ -783,21 +791,21 @@ static FuncDesc* ParseFuncDecl (void)
 
 
 
-static void Decl (Declaration* D, unsigned Mode)
+static void Decl (const DeclSpec* Spec, Declaration* D, unsigned Mode)
 /* Recursively process declarators. Build a type array in reverse order. */
 {
 
     if (CurTok.Tok == TOK_STAR) {
-       type T = T_PTR;
+       type T = T_PTR;
                NextToken ();
-       /* Allow optional const or volatile qualifiers */
-       T |= OptionalQualifiers (T_QUAL_NONE);
-               Decl (D, Mode);
+       /* Allow optional const or volatile qualifiers */
+       T |= OptionalQualifiers (T_QUAL_NONE);
+               Decl (Spec, D, Mode);
                *D->T++ = T;
                return;
     } else if (CurTok.Tok == TOK_LPAREN) {
                NextToken ();
-               Decl (D, Mode);
+               Decl (Spec, D, Mode);
                ConsumeRParen ();
     } else if (CurTok.Tok == TOK_FASTCALL) {
        /* Remember the current type pointer */
@@ -805,14 +813,14 @@ static void Decl (Declaration* D, unsigned Mode)
        /* Skip the fastcall token */
        NextToken ();
        /* Parse the function */
-       Decl (D, Mode);
+       Decl (Spec, D, Mode);
        /* Set the fastcall flag */
-       if (!IsTypeFunc (T)) {
+       if (!IsTypeFunc (T) && !IsTypeFuncPtr (T)) {
            Error ("__fastcall__ modifier applied to non function");
        } else if (IsVariadicFunc (T)) {
            Error ("Cannot apply __fastcall__ to functions with variable parameter list");
        } else {
-           FuncDesc* F = (FuncDesc*) DecodePtr (T+1);
+           FuncDesc* F = GetFuncDesc (T);
                    F->Flags |= FD_FASTCALL;
        }
        return;
@@ -821,11 +829,11 @@ static void Decl (Declaration* D, unsigned Mode)
                 *  - Mode == DM_NEED_IDENT means:
         *      we *must* have a type and a variable identifer.
         *  - Mode == DM_NO_IDENT means:
-        *      we must have a type but no variable identifer
+        *      we must have a type but no variable identifer
         *      (if there is one, it's not read).
         *  - Mode == DM_ACCEPT_IDENT means:
-        *      we *may* have an identifier. If there is an identifier,
-        *      it is read, but it is no error, if there is none.
+        *      we *may* have an identifier. If there is an identifier,
+        *      it is read, but it is no error, if there is none.
         */
        if (Mode == DM_NO_IDENT) {
            D->Ident[0] = '\0';
@@ -837,7 +845,6 @@ static void Decl (Declaration* D, unsigned Mode)
                Error ("Identifier expected");
            }
            D->Ident[0] = '\0';
-           return;
        }
     }
 
@@ -847,7 +854,7 @@ static void Decl (Declaration* D, unsigned Mode)
            FuncDesc* F;
                    NextToken ();
            /* Parse the function declaration */
-                   F = ParseFuncDecl ();
+                   F = ParseFuncDecl (Spec);
            *D->T++ = T_FUNC;
            EncodePtr (D->T, F);
            D->T += DECODE_SIZE;
@@ -858,7 +865,7 @@ static void Decl (Declaration* D, unsigned Mode)
            /* Read the size if it is given */
                    if (CurTok.Tok != TOK_RBRACK) {
                ExprDesc lval;
-                       constexpr (&lval);
+                       ConstExpr (&lval);
                        Size = lval.ConstVal;
                    }
                    ConsumeRBrack ();
@@ -907,18 +914,18 @@ void ParseDecl (const DeclSpec* Spec, Declaration* D, unsigned Mode)
     InitDeclaration (D);
 
     /* Get additional declarators and the identifier */
-    Decl (D, Mode);
+    Decl (Spec, D, Mode);
 
     /* Add the base type. */
     TypeCpy (D->T, Spec->Type);
 
     /* Check the size of the generated type */
     if (!IsTypeFunc (D->Type) && !IsTypeVoid (D->Type) && SizeOf (D->Type) >= 0x10000) {
-       if (D->Ident[0] != '\0') {
-           Error ("Size of `%s' is invalid", D->Ident);
-       } else {
-           Error ("Invalid size");
-       }
+       if (D->Ident[0] != '\0') {
+           Error ("Size of `%s' is invalid", D->Ident);
+       } else {
+           Error ("Invalid size");
+       }
     }
 }
 
@@ -960,7 +967,7 @@ static void ParseVoidInit (void)
     /* Allow an arbitrary list of values */
     ConsumeLCurly ();
     do {
-       constexpr (&lval);
+       ConstExpr (&lval);
        switch (lval.Type[0]) {
 
            case T_SCHAR:
@@ -1049,7 +1056,7 @@ static void ParseStructInit (type* Type)
 
     /* If there are struct fields left, reserve additional storage */
     while (Entry) {
-       g_zerobytes (SizeOf (Entry->Type));
+       g_zerobytes (CheckedSizeOf (Entry->Type));
        Entry = Entry->NextSym;
     }
 }
@@ -1069,7 +1076,7 @@ void ParseInit (type* T)
 
        case T_SCHAR:
        case T_UCHAR:
-           constexpr (&lval);
+           ConstExpr (&lval);
            if ((lval.Flags & E_MCTYPE) == E_TCONST) {
                /* Make it byte sized */
                lval.ConstVal &= 0xFF;
@@ -1083,7 +1090,7 @@ void ParseInit (type* T)
        case T_INT:
        case T_UINT:
        case T_PTR:
-           constexpr (&lval);
+           ConstExpr (&lval);
            if ((lval.Flags & E_MCTYPE) == E_TCONST) {
                /* Make it word sized */
                lval.ConstVal &= 0xFFFF;
@@ -1094,7 +1101,7 @@ void ParseInit (type* T)
 
        case T_LONG:
        case T_ULONG:
-           constexpr (&lval);
+           ConstExpr (&lval);
            if ((lval.Flags & E_MCTYPE) == E_TCONST) {
                /* Make it long sized */
                lval.ConstVal &= 0xFFFFFFFF;
@@ -1128,7 +1135,7 @@ void ParseInit (type* T)
            if (Size == 0) {
                Encode (T + 1, Count);
            } else if (Count < Size) {
-               g_zerobytes ((Size - Count) * SizeOf (T + DECODE_SIZE + 1));
+               g_zerobytes ((Size - Count) * CheckedSizeOf (T + DECODE_SIZE + 1));
            } else if (Count > Size) {
                Error ("Too many initializers");
            }