]> git.sur5r.net Git - cc65/blobdiff - src/cc65/declare.c
Cosmetic changes
[cc65] / src / cc65 / declare.c
index 004a9c27af4a5e6b22eadc398b63c58f66a315b4..c3ebf482bea5a995a97995d95643ccf162d31a70 100644 (file)
@@ -1,15 +1,41 @@
-/*
- * declare.c
- *
- * Ullrich von Bassewitz, 20.06.1998
- */
+/*****************************************************************************/
+/*                                                                           */
+/*                                declare.c                                 */
+/*                                                                           */
+/*                Parse variable and function declarations                  */
+/*                                                                           */
+/*                                                                           */
+/*                                                                           */
+/* (C) 1998-2001 Ullrich von Bassewitz                                       */
+/*               Wacholderweg 14                                             */
+/*               D-70597 Stuttgart                                           */
+/* EMail:        uz@musoftware.de                                            */
+/*                                                                           */
+/*                                                                           */
+/* This software is provided 'as-is', without any expressed or implied       */
+/* warranty.  In no event will the authors be held liable for any damages    */
+/* arising from the use of this software.                                    */
+/*                                                                           */
+/* Permission is granted to anyone to use this software for any purpose,     */
+/* including commercial applications, and to alter it and redistribute it    */
+/* freely, subject to the following restrictions:                            */
+/*                                                                           */
+/* 1. The origin of this software must not be misrepresented; you must not   */
+/*    claim that you wrote the original software. If you use this software   */
+/*    in a product, an acknowledgment in the product documentation would be  */
+/*    appreciated but is not required.                                       */
+/* 2. Altered source versions must be plainly marked as such, and must not   */
+/*    be misrepresented as being the original software.                      */
+/* 3. This notice may not be removed or altered from any source              */
+/*    distribution.                                                          */
+/*                                                                           */
+/*****************************************************************************/
 
 
 
 #include <stdio.h>
 #include <string.h>
 #include <errno.h>
-#include <ctype.h>
 
 /* common */
 #include "xmalloc.h"
@@ -52,20 +78,20 @@ static void ParseTypeSpec (DeclSpec* D, int Default);
 static type OptionalQualifiers (type Q)
 /* Read type qualifiers if we have any */
 {
-    while (curtok == TOK_CONST || curtok == TOK_VOLATILE) {
+    while (CurTok.Tok == TOK_CONST || CurTok.Tok == TOK_VOLATILE) {
 
-       switch (curtok) {
+       switch (CurTok.Tok) {
 
            case TOK_CONST:
                if (Q & T_QUAL_CONST) {
-                   Error (ERR_DUPLICATE_QUALIFIER, "const");
+                   Error ("Duplicate qualifier: `const'");
                }
                Q |= T_QUAL_CONST;
                break;
 
            case TOK_VOLATILE:
                if (Q & T_QUAL_VOLATILE) {
-                   Error (ERR_DUPLICATE_QUALIFIER, "volatile");
+                   Error ("Duplicate qualifier: `volatile'");
                }
                Q |= T_QUAL_VOLATILE;
                break;
@@ -89,7 +115,7 @@ static type OptionalQualifiers (type Q)
 static void optionalint (void)
 /* Eat an optional "int" token */
 {
-    if (curtok == TOK_INT) {
+    if (CurTok.Tok == TOK_INT) {
        /* Skip it */
        NextToken ();
     }
@@ -100,7 +126,7 @@ static void optionalint (void)
 static void optionalsigned (void)
 /* Eat an optional "signed" token */
 {
-    if (curtok == TOK_SIGNED) {
+    if (CurTok.Tok == TOK_SIGNED) {
        /* Skip it */
        NextToken ();
     }
@@ -135,7 +161,7 @@ static void ParseStorageClass (DeclSpec* D, unsigned DefStorage)
     D->Flags &= ~DS_DEF_STORAGE;
 
     /* Check the storage class given */
-    switch (curtok) {
+    switch (CurTok.Tok) {
 
        case TOK_EXTERN:
            D->StorageClass = SC_EXTERN | SC_STATIC;
@@ -179,7 +205,7 @@ static void ParseEnumDecl (void)
     ident Ident;
 
     /* Accept forward definitions */
-    if (curtok != TOK_LCURLY) {
+    if (CurTok.Tok != TOK_LCURLY) {
        return;
     }
 
@@ -188,11 +214,11 @@ static void ParseEnumDecl (void)
 
     /* Read the enum tags */
     EnumVal = 0;
-    while (curtok != TOK_RCURLY) {
+    while (CurTok.Tok != TOK_RCURLY) {
 
        /* We expect an identifier */
-       if (curtok != TOK_IDENT) {
-           Error (ERR_IDENT_EXPECTED);
+       if (CurTok.Tok != TOK_IDENT) {
+           Error ("Identifier expected");
            continue;
        }
 
@@ -201,7 +227,7 @@ static void ParseEnumDecl (void)
        NextToken ();
 
        /* Check for an assigned value */
-       if (curtok == TOK_ASSIGN) {
+       if (CurTok.Tok == TOK_ASSIGN) {
            struct expent lval;
            NextToken ();
            constexpr (&lval);
@@ -209,10 +235,10 @@ static void ParseEnumDecl (void)
        }
 
        /* Add an entry to the symbol table */
-       AddEnumSym (Ident, EnumVal++);
+       AddConstSym (Ident, type_int, SC_ENUM, EnumVal++);
 
        /* Check for end of definition */
-       if (curtok != TOK_COMMA)
+       if (CurTok.Tok != TOK_COMMA)
            break;
        NextToken ();
     }
@@ -231,7 +257,7 @@ static SymEntry* ParseStructDecl (const char* Name, type StructType)
     SymEntry* Entry;
 
 
-    if (curtok != TOK_LCURLY) {
+    if (CurTok.Tok != TOK_LCURLY) {
        /* Just a forward declaration. Try to find a struct with the given
         * name. If there is none, insert a forward declaration into the
         * current lexical level.
@@ -241,7 +267,7 @@ static SymEntry* ParseStructDecl (const char* Name, type StructType)
            Entry = AddStructSym (Name, 0, 0);
        } else if (SymIsLocal (Entry) && (Entry->Flags & SC_STRUCT) == 0) {
            /* Already defined in the level but no struct */
-           Error (ERR_SYMBOL_KIND);
+           Error ("Symbol `%s' is already different kind", Name);
        }
        return Entry;
     }
@@ -257,7 +283,7 @@ static SymEntry* ParseStructDecl (const char* Name, type StructType)
 
     /* Parse struct fields */
     Size = 0;
-    while (curtok != TOK_RCURLY) {
+    while (CurTok.Tok != TOK_RCURLY) {
 
        /* Get the type of the entry */
        DeclSpec Spec;
@@ -284,7 +310,7 @@ static SymEntry* ParseStructDecl (const char* Name, type StructType)
                }
            }
 
-           if (curtok != TOK_COMMA)
+           if (CurTok.Tok != TOK_COMMA)
                break;
            NextToken ();
        }
@@ -319,7 +345,7 @@ static void ParseTypeSpec (DeclSpec* D, int Default)
     Qualifiers = OptionalQualifiers (T_QUAL_NONE);
 
     /* Look at the data type */
-    switch (curtok) {
+    switch (CurTok.Tok) {
 
        case TOK_VOID:
            NextToken ();
@@ -335,7 +361,7 @@ static void ParseTypeSpec (DeclSpec* D, int Default)
 
        case TOK_LONG:
            NextToken ();
-           if (curtok == TOK_UNSIGNED) {
+           if (CurTok.Tok == TOK_UNSIGNED) {
                NextToken ();
                optionalint ();
                D->Type[0] = T_ULONG;
@@ -350,7 +376,7 @@ static void ParseTypeSpec (DeclSpec* D, int Default)
 
        case TOK_SHORT:
            NextToken ();
-           if (curtok == TOK_UNSIGNED) {
+           if (CurTok.Tok == TOK_UNSIGNED) {
                NextToken ();
                optionalint ();
                D->Type[0] = T_USHORT;
@@ -371,7 +397,7 @@ static void ParseTypeSpec (DeclSpec* D, int Default)
 
        case TOK_SIGNED:
            NextToken ();
-           switch (curtok) {
+           switch (CurTok.Tok) {
 
                        case TOK_CHAR:
                    NextToken ();
@@ -406,7 +432,7 @@ static void ParseTypeSpec (DeclSpec* D, int Default)
 
        case TOK_UNSIGNED:
            NextToken ();
-           switch (curtok) {
+           switch (CurTok.Tok) {
 
                        case TOK_CHAR:
                    NextToken ();
@@ -441,10 +467,10 @@ static void ParseTypeSpec (DeclSpec* D, int Default)
 
        case TOK_STRUCT:
        case TOK_UNION:
-           StructType = (curtok == TOK_STRUCT)? T_STRUCT : T_UNION;
+           StructType = (CurTok.Tok == TOK_STRUCT)? T_STRUCT : T_UNION;
            NextToken ();
            /* */
-           if (curtok == TOK_IDENT) {
+           if (CurTok.Tok == TOK_IDENT) {
                strcpy (Ident, CurTok.Ident);
                NextToken ();
            } else {
@@ -462,14 +488,14 @@ static void ParseTypeSpec (DeclSpec* D, int Default)
 
        case TOK_ENUM:
            NextToken ();
-           if (curtok != TOK_LCURLY) {
+           if (CurTok.Tok != TOK_LCURLY) {
                /* Named enum */
-               if (curtok == TOK_IDENT) {
+               if (CurTok.Tok == TOK_IDENT) {
                    /* Find an entry with this name */
                    Entry = FindTagSym (CurTok.Ident);
                    if (Entry) {
                        if (SymIsLocal (Entry) && (Entry->Flags & SC_ENUM) == 0) {
-                           Error (ERR_SYMBOL_KIND);
+                           Error ("Symbol `%s' is already different kind", Entry->Name);
                        }
                    } else {
                        /* Insert entry into table ### */
@@ -477,7 +503,7 @@ static void ParseTypeSpec (DeclSpec* D, int Default)
                    /* Skip the identifier */
                    NextToken ();
                } else {
-                   Error (ERR_IDENT_EXPECTED);
+                   Error ("Identifier expected");
                }
            }
            /* Remember we have an extra type decl */
@@ -500,7 +526,7 @@ static void ParseTypeSpec (DeclSpec* D, int Default)
 
        default:
            if (Default < 0) {
-               Error (ERR_TYPE_EXPECTED);
+               Error ("Type expected");
                D->Type[0] = T_INT;
                D->Type[1] = T_END;
            } else {
@@ -535,11 +561,11 @@ static void ParseOldStyleParamList (FuncDesc* F)
 /* Parse an old style (K&R) parameter list */
 {
     /* Parse params */
-    while (curtok != TOK_RPAREN) {
+    while (CurTok.Tok != TOK_RPAREN) {
 
        /* List of identifiers expected */
-       if (curtok != TOK_IDENT) {
-           Error (ERR_IDENT_EXPECTED);
+       if (CurTok.Tok != TOK_IDENT) {
+           Error ("Identifier expected");
        }
 
        /* Create a symbol table entry with type int */
@@ -552,7 +578,7 @@ static void ParseOldStyleParamList (FuncDesc* F)
        NextToken ();
 
        /* Check for more parameters */
-       if (curtok == TOK_COMMA) {
+       if (CurTok.Tok == TOK_COMMA) {
            NextToken ();
        } else {
            break;
@@ -565,9 +591,9 @@ static void ParseOldStyleParamList (FuncDesc* F)
     ConsumeRParen ();
 
     /* An optional list of type specifications follows */
-    while (curtok != TOK_LCURLY) {
+    while (CurTok.Tok != TOK_LCURLY) {
 
-       DeclSpec        Spec;
+       DeclSpec        Spec;
 
        /* Read the declaration specifier */
        ParseDeclSpec (&Spec, SC_AUTO, T_INT);
@@ -577,7 +603,7 @@ static void ParseOldStyleParamList (FuncDesc* F)
         */
        if ((Spec.StorageClass & SC_AUTO) == 0 &&
            (Spec.StorageClass & SC_REGISTER) == 0) {
-           Error (ERR_ILLEGAL_STORAGE_CLASS);
+           Error ("Illegal storage class");
        }
 
        /* Parse a comma separated variable list */
@@ -595,11 +621,11 @@ static void ParseOldStyleParamList (FuncDesc* F)
                    /* Found it, change the default type to the one given */
                    ChangeSymType (Sym, ParamTypeCvt (Decl.Type));
                } else {
-                   Error (ERR_UNKNOWN_IDENT, Decl.Ident);
+                   Error ("Unknown identifier: `%s'", Decl.Ident);
                }
            }
 
-           if (curtok == TOK_COMMA) {
+           if (CurTok.Tok == TOK_COMMA) {
                NextToken ();
            } else {
                break;
@@ -618,16 +644,16 @@ static void ParseAnsiParamList (FuncDesc* F)
 /* Parse a new style (ANSI) parameter list */
 {
     /* Parse params */
-    while (curtok != TOK_RPAREN) {
+    while (CurTok.Tok != TOK_RPAREN) {
 
        DeclSpec        Spec;
        Declaration     Decl;
        DeclAttr        Attr;
 
        /* Allow an ellipsis as last parameter */
-       if (curtok == TOK_ELLIPSIS) {
+       if (CurTok.Tok == TOK_ELLIPSIS) {
            NextToken ();
-           F->Flags |= FD_ELLIPSIS;
+           F->Flags |= FD_VARIADIC;
            break;
        }
 
@@ -639,7 +665,7 @@ static void ParseAnsiParamList (FuncDesc* F)
         */
        if ((Spec.StorageClass & SC_AUTO) == 0 &&
            (Spec.StorageClass & SC_REGISTER) == 0) {
-           Error (ERR_ILLEGAL_STORAGE_CLASS);
+           Error ("Illegal storage class");
        }
        Spec.StorageClass = SC_AUTO | SC_PARAM | SC_DEF;
 
@@ -669,7 +695,7 @@ static void ParseAnsiParamList (FuncDesc* F)
                ++F->ParamCount;
 
        /* Check for more parameters */
-       if (curtok == TOK_COMMA) {
+       if (CurTok.Tok == TOK_COMMA) {
            NextToken ();
        } else {
            break;
@@ -682,12 +708,12 @@ static void ParseAnsiParamList (FuncDesc* F)
     ConsumeRParen ();
 
     /* Check if this is a function definition */
-    if (curtok == TOK_LCURLY) {
+    if (CurTok.Tok == TOK_LCURLY) {
        /* Print an error if in strict ANSI mode and we have unnamed
         * parameters.
         */
                if (ANSI && (F->Flags & FD_UNNAMED_PARAMS) != 0) {
-           Error (ERR_MISSING_PARAM_NAME);
+           Error ("Parameter name omitted");
        }
     }
 }
@@ -707,16 +733,23 @@ static FuncDesc* ParseFuncDecl (void)
     EnterFunctionLevel ();
 
     /* Check for several special parameter lists */
-    if (curtok == TOK_RPAREN) {
+    if (CurTok.Tok == TOK_RPAREN) {
        /* Parameter list is empty */
-       F->Flags |= (FD_EMPTY | FD_ELLIPSIS);
-    } else if (curtok == TOK_VOID && nxttok == TOK_RPAREN) {
+       F->Flags |= (FD_EMPTY | FD_VARIADIC);
+    } else if (CurTok.Tok == TOK_VOID && NextTok.Tok == TOK_RPAREN) {
        /* Parameter list declared as void */
        NextToken ();
        F->Flags |= FD_VOID_PARAM;
-    } else if (curtok == TOK_IDENT && (nxttok == TOK_COMMA || nxttok == TOK_RPAREN)) {
-       /* Old style (K&R) function. Assume variable param list. */
-               F->Flags |= (FD_OLDSTYLE | FD_ELLIPSIS);
+    } else if (CurTok.Tok == TOK_IDENT &&
+              (NextTok.Tok == TOK_COMMA || NextTok.Tok == TOK_RPAREN)) {
+       /* If the identifier is a typedef, we have a new style parameter list,
+        * if it's some other identifier, it's an old style parameter list.
+        */
+       Sym = FindSym (CurTok.Ident);
+       if (Sym == 0 || !IsTypeDef (Sym)) {
+           /* Old style (K&R) function. Assume variable param list. */
+           F->Flags |= (FD_OLDSTYLE | FD_VARIADIC);
+       }
     }
 
     /* Parse params */
@@ -731,7 +764,7 @@ static FuncDesc* ParseFuncDecl (void)
     /* Assign offsets. If the function has a variable parameter list,
      * there's one additional byte (the arg size).
      */
-    Offs = (F->Flags & FD_ELLIPSIS)? 1 : 0;
+    Offs = (F->Flags & FD_VARIADIC)? 1 : 0;
     Sym = GetSymTab()->SymTail;
     while (Sym) {
        unsigned Size = SizeOf (Sym->Type);
@@ -754,7 +787,7 @@ static void Decl (Declaration* D, unsigned Mode)
 /* Recursively process declarators. Build a type array in reverse order. */
 {
 
-    if (curtok == TOK_STAR) {
+    if (CurTok.Tok == TOK_STAR) {
        type T = T_PTR;
                NextToken ();
        /* Allow optional const or volatile qualifiers */
@@ -762,11 +795,11 @@ static void Decl (Declaration* D, unsigned Mode)
                Decl (D, Mode);
                *D->T++ = T;
                return;
-    } else if (curtok == TOK_LPAREN) {
+    } else if (CurTok.Tok == TOK_LPAREN) {
                NextToken ();
                Decl (D, Mode);
                ConsumeRParen ();
-    } else if (curtok == TOK_FASTCALL) {
+    } else if (CurTok.Tok == TOK_FASTCALL) {
        /* Remember the current type pointer */
        type* T = D->T;
        /* Skip the fastcall token */
@@ -775,9 +808,11 @@ static void Decl (Declaration* D, unsigned Mode)
        Decl (D, Mode);
        /* Set the fastcall flag */
        if (!IsTypeFunc (T)) {
-           Error (ERR_ILLEGAL_MODIFIER);
+           Error ("__fastcall__ modifier applied to non function");
+       } else if (IsVariadicFunc (T)) {
+           Error ("Cannot apply __fastcall__ to functions with variable parameter list");
        } else {
-           FuncDesc* F = DecodePtr (T+1);
+           FuncDesc* F = (FuncDesc*) DecodePtr (T+1);
                    F->Flags |= FD_FASTCALL;
        }
        return;
@@ -794,20 +829,20 @@ static void Decl (Declaration* D, unsigned Mode)
         */
        if (Mode == DM_NO_IDENT) {
            D->Ident[0] = '\0';
-       } else if (curtok == TOK_IDENT) {
+       } else if (CurTok.Tok == TOK_IDENT) {
                    strcpy (D->Ident, CurTok.Ident);
            NextToken ();
        } else {
            if (Mode == DM_NEED_IDENT) {
-               Error (ERR_IDENT_EXPECTED);
+               Error ("Identifier expected");
            }
            D->Ident[0] = '\0';
            return;
        }
     }
 
-    while (curtok == TOK_LBRACK || curtok == TOK_LPAREN) {
-               if (curtok == TOK_LPAREN) {
+    while (CurTok.Tok == TOK_LBRACK || CurTok.Tok == TOK_LPAREN) {
+               if (CurTok.Tok == TOK_LPAREN) {
                    /* Function declaration */
            FuncDesc* F;
                    NextToken ();
@@ -821,7 +856,7 @@ static void Decl (Declaration* D, unsigned Mode)
                    unsigned long Size = 0;
                    NextToken ();
            /* Read the size if it is given */
-                   if (curtok != TOK_RBRACK) {
+                   if (CurTok.Tok != TOK_RBRACK) {
                struct expent lval;
                        constexpr (&lval);
                        Size = lval.e_const;
@@ -879,7 +914,11 @@ void ParseDecl (const DeclSpec* Spec, Declaration* D, unsigned Mode)
 
     /* Check the size of the generated type */
     if (!IsTypeFunc (D->Type) && !IsTypeVoid (D->Type) && SizeOf (D->Type) >= 0x10000) {
-       Error (ERR_ILLEGAL_SIZE);
+       if (D->Ident[0] != '\0') {
+           Error ("Size of `%s' is invalid", D->Ident);
+       } else {
+           Error ("Invalid size");
+       }
     }
 }
 
@@ -952,17 +991,17 @@ static void ParseVoidInit (void)
                break;
 
            default:
-               Error (ERR_ILLEGAL_TYPE);
+               Error ("Illegal type in initialization");
                break;
 
        }
 
-       if (curtok != TOK_COMMA) {
+       if (CurTok.Tok != TOK_COMMA) {
            break;
        }
        NextToken ();
 
-    } while (curtok != TOK_RCURLY);
+    } while (CurTok.Tok != TOK_RCURLY);
 
     ConsumeRCurly ();
 }
@@ -986,21 +1025,21 @@ static void ParseStructInit (type* Type)
      */
     Tab = Entry->V.S.SymTab;
     if (Tab == 0) {
-       Error (ERR_INIT_INCOMPLETE_TYPE);
+       Error ("Cannot initialize variables with incomplete type");
        /* Returning here will cause lots of errors, but recovery is difficult */
        return;
     }
 
     /* Get a pointer to the list of symbols */
     Entry = Tab->SymHead;
-    while (curtok != TOK_RCURLY) {
+    while (CurTok.Tok != TOK_RCURLY) {
        if (Entry == 0) {
-           Error (ERR_TOO_MANY_INITIALIZERS);
+           Error ("Too many initializers");
            return;
        }
        ParseInit (Entry->Type);
        Entry = Entry->NextSym;
-       if (curtok != TOK_COMMA)
+       if (CurTok.Tok != TOK_COMMA)
            break;
        NextToken ();
     }
@@ -1020,11 +1059,11 @@ static void ParseStructInit (type* Type)
 void ParseInit (type* T)
 /* Parse initialization of variables. */
 {
-    int count;
     struct expent lval;
     type* t;
     const char* str;
-    int sz;
+    int Count;
+    int Size;
 
     switch (UnqualifiedType (*T)) {
 
@@ -1065,33 +1104,33 @@ void ParseInit (type* T)
            break;
 
        case T_ARRAY:
-           sz = Decode (T + 1);
+           Size = Decode (T + 1);
            t = T + DECODE_SIZE + 1;
-                   if (IsTypeChar(t) && curtok == TOK_SCONST) {
-               str = GetLiteral (curval);
-               count = strlen (str) + 1;
-               TranslateLiteralPool (curval);  /* Translate into target charset */
-               g_defbytes (str, count);
-               ResetLiteralOffs (curval);      /* Remove string from pool */
+                   if (IsTypeChar(t) && CurTok.Tok == TOK_SCONST) {
+               str = GetLiteral (CurTok.IVal);
+               Count = strlen (str) + 1;
+               TranslateLiteralPool (CurTok.IVal);     /* Translate into target charset */
+               g_defbytes (str, Count);
+               ResetLiteralPoolOffs (CurTok.IVal);     /* Remove string from pool */
                NextToken ();
            } else {
                ConsumeLCurly ();
-               count = 0;
-               while (curtok != TOK_RCURLY) {
+               Count = 0;
+               while (CurTok.Tok != TOK_RCURLY) {
                    ParseInit (T + DECODE_SIZE + 1);
-                   ++count;
-                   if (curtok != TOK_COMMA)
+                   ++Count;
+                   if (CurTok.Tok != TOK_COMMA)
                        break;
                    NextToken ();
                }
                ConsumeRCurly ();
            }
-           if (sz == 0) {
-               Encode (T + 1, count);
-           } else if (count < sz) {
-               g_zerobytes ((sz - count) * SizeOf (T + DECODE_SIZE + 1));
-           } else if (count > sz) {
-               Error (ERR_TOO_MANY_INITIALIZERS);
+           if (Size == 0) {
+               Encode (T + 1, Count);
+           } else if (Count < Size) {
+               g_zerobytes ((Size - Count) * SizeOf (T + DECODE_SIZE + 1));
+           } else if (Count > Size) {
+               Error ("Too many initializers");
            }
            break;
 
@@ -1109,7 +1148,7 @@ void ParseInit (type* T)
            /* FALLTHROUGH */
 
        default:
-           Error (ERR_ILLEGAL_TYPE);
+           Error ("Illegal type");
            break;
 
     }