]> git.sur5r.net Git - cc65/commitdiff
Some changes in the way, types and type strings are handled.
authorcuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Tue, 1 Aug 2000 18:45:08 +0000 (18:45 +0000)
committercuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Tue, 1 Aug 2000 18:45:08 +0000 (18:45 +0000)
Check for and honour const in several places: Assignment to const is flagged
with an error. Const data is placed in the rodata segment.

git-svn-id: svn://svn.cc65.org/cc65/trunk@252 b7a2c559-68d2-44c3-8de9-860c34a00d81

src/cc65/compile.c
src/cc65/datatype.c
src/cc65/datatype.h
src/cc65/declare.c
src/cc65/declare.h
src/cc65/error.c
src/cc65/error.h
src/cc65/expr.c
src/cc65/locals.c
src/cc65/stmt.c
src/cc65/symtab.c

index 6eadc4a2125a43d836ef51e6d638e27baa673aec..cb3dd92c51fa318e843975eb4ec18a8b0beda6ba 100644 (file)
@@ -37,7 +37,7 @@
 
 /* common */
 #include "version.h"
-         
+
 /* cc65 */
 #include "asmlabel.h"
 #include "codegen.h"
@@ -136,7 +136,7 @@ static void Parse (void)
 
            /* Get the symbol flags */
            SymFlags = Spec.StorageClass;
-           if (IsFunc (Decl.Type)) {
+           if (IsTypeFunc (Decl.Type)) {
                SymFlags |= SC_FUNC;
            } else {
                if (NeedStorage) {
@@ -161,19 +161,23 @@ static void Parse (void)
                     * void types in non ANSI mode.
                     */
                            if (Size == 0) {
-                       if (!IsTypeVoid (Decl.Type)) {
-                           if (!IsArray (Decl.Type)) {
-                               /* Size is unknown and not an array */
-                               Error (ERR_UNKNOWN_SIZE);
-                           }
-                       } else if (ANSI) {
-                           /* We cannot declare variables of type void */
-                           Error (ERR_ILLEGAL_TYPE);
-                       }
+                       if (!IsTypeVoid (Decl.Type)) {
+                           if (!IsTypeArray (Decl.Type)) {
+                               /* Size is unknown and not an array */
+                               Error (ERR_UNKNOWN_SIZE);
+                           }
+                       } else if (ANSI) {
+                           /* We cannot declare variables of type void */
+                           Error (ERR_ILLEGAL_TYPE);
+                       }
                    }
 
-                   /* Switch to the data segment */
-                   g_usedata ();
+                   /* Switch to the data or rodata segment */
+                   if (IsConst (Decl.Type)) {
+                       g_userodata ();
+                   } else {
+                       g_usedata ();
+                   }
 
                    /* Define a label */
                    g_defgloblabel (Entry->Name);
@@ -215,7 +219,7 @@ static void Parse (void)
        }
 
        /* Function declaration? */
-       if (IsFunc (Decl.Type)) {
+       if (IsTypeFunc (Decl.Type)) {
 
            /* Function */
            if (!comma) {
index c7070725735768c8e2b76e76a369d9011b9ef276..a450d0972e25adc1b09c65f0809d7672b7b0ef19 100644 (file)
@@ -222,45 +222,49 @@ static type PrintTypeComp (FILE* F, type T, type Mask, const char* Name)
 void PrintType (FILE* F, const type* Type)
 /* Output translation of type array. */
 {
-    /* If the first field has const and/or volatile qualifiers, print and
-     * remove them.
-     */
-    type T = *Type++;
-    T = PrintTypeComp (F, T, T_QUAL_CONST, "const");
-    T = PrintTypeComp (F, T, T_QUAL_VOLATILE, "volatile");
+    type T;
+
 
     /* Walk over the complete string */
-    do {
+    while ((T = *Type++) != T_END) {
 
-       /* Check for the sizes */
-               T = PrintTypeComp (F, T, T_SIZE_SHORT, "short");
-       T = PrintTypeComp (F, T, T_SIZE_LONG, "long");
-       T = PrintTypeComp (F, T, T_SIZE_LONGLONG, "long long");
+       /* Print any qualifiers */
+       T = PrintTypeComp (F, T, T_QUAL_CONST, "const");
+       T = PrintTypeComp (F, T, T_QUAL_VOLATILE, "volatile");
 
-       /* Signedness */
-       T = PrintTypeComp (F, T, T_SIGN_SIGNED, "signed");
-       T = PrintTypeComp (F, T, T_SIGN_UNSIGNED, "unsigned");
+       /* Signedness */
+       T = PrintTypeComp (F, T, T_SIGN_SIGNED, "signed");
+       T = PrintTypeComp (F, T, T_SIGN_UNSIGNED, "unsigned");
 
-       /* Now check the real type */
+       /* Now check the real type */
        switch (T & T_MASK_TYPE) {
-           case T_TYPE_CHAR:
-               fprintf (F, "char\n");
-               break;
-           case T_TYPE_INT:
-               fprintf (F, "int\n");
-               break;
-           case T_TYPE_FLOAT:
-               fprintf (F, "float\n");
-               break;
-           case T_TYPE_DOUBLE:
-               fprintf (F, "double\n");
-               break;
+           case T_TYPE_CHAR:
+               fprintf (F, "char\n");
+               break;
+           case T_TYPE_SHORT:
+               fprintf (F, "short\n");
+               break;
+           case T_TYPE_INT:
+               fprintf (F, "int\n");
+               break;
+           case T_TYPE_LONG:
+               fprintf (F, "long\n");
+               break;
+           case T_TYPE_LONGLONG:
+               fprintf (F, "long long\n");
+               break;
+           case T_TYPE_FLOAT:
+               fprintf (F, "float\n");
+               break;
+           case T_TYPE_DOUBLE:
+               fprintf (F, "double\n");
+               break;
            case T_TYPE_VOID:
                fprintf (F, "void\n");
-               break;
-           case T_TYPE_STRUCT:
-               fprintf (F, "struct %s\n", ((SymEntry*) DecodePtr (Type))->Name);
-               Type += DECODE_SIZE;
+               break;
+           case T_TYPE_STRUCT:
+               fprintf (F, "struct %s\n", ((SymEntry*) DecodePtr (Type))->Name);
+                       Type += DECODE_SIZE;
                break;
            case T_TYPE_UNION:
                fprintf (F, "union %s\n", ((SymEntry*) DecodePtr (Type))->Name);
@@ -281,10 +285,7 @@ void PrintType (FILE* F, const type* Type)
                fprintf (F, "unknown type: %04X\n", T);
        }
 
-       /* Get the next type element */
-       T = *Type++;
-
-    } while (T != T_END);
+    }
 }
 
 
@@ -345,7 +346,7 @@ void* DecodePtr (const type* Type)
 int HasEncode (const type* Type)
 /* Return true if the given type has encoded data */
 {
-    return IsStruct (Type) || IsArray (Type) || IsFunc (Type);
+    return IsClassStruct (Type) || IsTypeArray (Type) || IsTypeFunc (Type);
 }
 
 
@@ -358,15 +359,23 @@ void CopyEncode (const type* Source, type* Target)
 
 
 
+type UnqualifiedType (type T)
+/* Return the unqalified type */
+{
+    return (T & ~T_MASK_QUAL);
+}
+
+
+
 unsigned SizeOf (const type* T)
 /* Compute size of object represented by type array. */
 {
     SymEntry* Entry;
 
-    switch (*T) {
+    switch (UnqualifiedType (T[0])) {
 
-       case T_VOID:
-           Error (ERR_ILLEGAL_SIZE);
+       case T_VOID:
+           Error (ERR_ILLEGAL_SIZE);
            return 0;
 
        case T_SCHAR:
@@ -419,7 +428,7 @@ unsigned PSizeOf (const type* T)
     CHECK ((*T & T_CLASS_PTR) != 0);
 
     /* Skip the pointer or array token itself */
-    if (*T == T_ARRAY) {
+    if (IsTypeArray (T)) {
                return SizeOf (T + DECODE_SIZE + 1);
     } else {
        return SizeOf (T + 1);
@@ -428,12 +437,12 @@ unsigned PSizeOf (const type* T)
 
 
 
-unsigned TypeOf (const type* Type)
+unsigned TypeOf (const type* T)
 /* Get the code generator base type of the object */
 {
     FuncDesc* F;
 
-    switch (*Type) {
+    switch (UnqualifiedType (T[0])) {
 
        case T_SCHAR:
            return CF_CHAR;
@@ -459,7 +468,7 @@ unsigned TypeOf (const type* Type)
                    return CF_LONG | CF_UNSIGNED;
 
         case T_FUNC:
-           F = DecodePtr (Type+1);
+           F = DecodePtr (T+1);
            return (F->Flags & FD_ELLIPSIS)? 0 : CF_FIXARGC;
 
         case T_STRUCT:
@@ -484,7 +493,7 @@ type* Indirect (type* T)
     CHECK ((*T & T_MASK_CLASS) == T_CLASS_PTR);
 
     /* Skip the pointer or array token itself */
-    if (*T == T_ARRAY) {
+    if (IsTypeArray (T)) {
                return T + DECODE_SIZE + 1;
     } else {
        return T + 1;
@@ -493,15 +502,29 @@ type* Indirect (type* T)
 
 
 
+int IsConst (const type* T)
+/* Return true if the given type has a const memory image */
+{
+    /* If this is an array, look at the element type, otherwise look at the
+     * type itself.
+     */
+    if (IsTypeArray (T)) {
+       T += DECODE_SIZE + 1;
+    }
+    return ((T[0] & T_QUAL_CONST) == T_QUAL_CONST);
+}
+
+
+
 int IsTypeVoid (const type* T)
 /* Return true if this is a void type */
 {
-    return (T[0] == T_VOID && T[1] == T_END);
+    return ((T[0] & T_MASK_TYPE) == T_TYPE_VOID && T[1] == T_END);
 }
 
 
 
-int IsPtr (const type* T)
+int IsClassPtr (const type* T)
 /* Return true if this is a pointer type */
 {
     return (T[0] & T_MASK_CLASS) == T_CLASS_PTR;
@@ -509,7 +532,7 @@ int IsPtr (const type* T)
 
 
 
-int IsChar (const type* T)
+int IsTypeChar (const type* T)
 /* Return true if this is a character type */
 {
     return (T[0] & T_MASK_TYPE) == T_TYPE_CHAR && T[1] == T_END;
@@ -517,7 +540,7 @@ int IsChar (const type* T)
 
 
 
-int IsInt (const type* T)
+int IsClassInt (const type* T)
 /* Return true if this is an integer type */
 {
     return (T[0] & T_MASK_CLASS) == T_CLASS_INT;
@@ -525,10 +548,10 @@ int IsInt (const type* T)
 
 
 
-int IsLong (const type* T)
+int IsTypeLong (const type* T)
 /* Return true if this is a long type (signed or unsigned) */
 {
-    return (T[0] & T_MASK_SIZE) == T_SIZE_LONG;
+    return (T[0] & T_MASK_TYPE) == T_TYPE_LONG;
 }
 
 
@@ -541,7 +564,7 @@ int IsUnsigned (const type* T)
 
 
 
-int IsStruct (const type* T)
+int IsClassStruct (const type* T)
 /* Return true if this is a struct type */
 {
     return (T[0] & T_MASK_CLASS) == T_CLASS_STRUCT;
@@ -549,10 +572,10 @@ int IsStruct (const type* T)
 
 
 
-int IsFunc (const type* T)
-/* Return true if this is a function type */
+int IsTypeFunc (const type* T)
+/* Return true if this is a function class */
 {
-    return (T[0] == T_FUNC);
+    return ((T[0] & T_MASK_TYPE) == T_TYPE_FUNC);
 }
 
 
@@ -561,25 +584,25 @@ int IsFastCallFunc (const type* T)
 /* Return true if this is a function type with __fastcall__ calling conventions */
 {
     FuncDesc* F;
-    CHECK (T[0] == T_FUNC);
+    CHECK (IsTypeFunc (T));
     F = DecodePtr (T+1);
     return (F->Flags & FD_FASTCALL) != 0;
 }
 
 
 
-int IsFuncPtr (const type* T)
+int IsTypeFuncPtr (const type* T)
 /* Return true if this is a function pointer */
 {
-    return (T[0] == T_PTR && T[1] == T_FUNC);
+    return ((T[0] & T_MASK_TYPE) == T_TYPE_PTR && (T[1] & T_MASK_TYPE) == T_TYPE_FUNC);
 }
 
 
 
-int IsArray (const type* T)
+int IsTypeArray (const type* T)
 /* Return true if this is an array type */
 {
-    return (T[0] == T_ARRAY);
+    return ((T[0] & T_MASK_TYPE) == T_TYPE_ARRAY);
 }
 
 
index 0d65ef289016be7fd9f79232dddfd7cd56272226..cdef535f8f819f4b9a5c342196afbdf036e69508 100644 (file)
@@ -56,16 +56,19 @@ enum {
     // Basic types
     T_TYPE_NONE            = 0x0000,
     T_TYPE_CHAR            = 0x0001,
-    T_TYPE_INT             = 0x0002,
-    T_TYPE_ENUM            = 0x0003,
-    T_TYPE_FLOAT    = 0x0004,
-    T_TYPE_DOUBLE   = 0x0005,
-    T_TYPE_VOID     = 0x0006,
-    T_TYPE_STRUCT   = 0x0007,
-    T_TYPE_UNION    = 0x0008,
-    T_TYPE_ARRAY    = 0x0009,
-    T_TYPE_PTR      = 0x000A,
-    T_TYPE_FUNC     = 0x000B,
+    T_TYPE_SHORT    = 0x0002,
+    T_TYPE_INT             = 0x0003,
+    T_TYPE_LONG            = 0x0004,
+    T_TYPE_LONGLONG = 0x0005,
+    T_TYPE_ENUM            = 0x0006,
+    T_TYPE_FLOAT    = 0x0007,
+    T_TYPE_DOUBLE   = 0x0008,
+    T_TYPE_VOID     = 0x0009,
+    T_TYPE_STRUCT   = 0x000A,
+    T_TYPE_UNION    = 0x000B,
+    T_TYPE_ARRAY    = 0x000C,
+    T_TYPE_PTR      = 0x000D,
+    T_TYPE_FUNC     = 0x000E,
     T_MASK_TYPE            = 0x001F,
 
     // Type classes
@@ -97,26 +100,26 @@ enum {
     T_MASK_QUAL            = 0x3000,
 
     // Types
-    T_CHAR             = T_TYPE_CHAR   | T_CLASS_INT    | T_SIGN_UNSIGNED | T_SIZE_NONE,
-    T_SCHAR    = T_TYPE_CHAR   | T_CLASS_INT    | T_SIGN_SIGNED   | T_SIZE_NONE,
-    T_UCHAR    = T_TYPE_CHAR   | T_CLASS_INT    | T_SIGN_UNSIGNED | T_SIZE_NONE,
-    T_SHORT    = T_TYPE_INT    | T_CLASS_INT    | T_SIGN_SIGNED   | T_SIZE_SHORT,
-    T_USHORT    = T_TYPE_INT    | T_CLASS_INT    | T_SIGN_UNSIGNED | T_SIZE_SHORT,
-    T_INT      = T_TYPE_INT    | T_CLASS_INT    | T_SIGN_SIGNED   | T_SIZE_NONE,
-    T_UINT     = T_TYPE_INT    | T_CLASS_INT    | T_SIGN_UNSIGNED | T_SIZE_NONE,
-    T_LONG     = T_TYPE_INT    | T_CLASS_INT    | T_SIGN_SIGNED   | T_SIZE_LONG,
-    T_ULONG    = T_TYPE_INT    | T_CLASS_INT    | T_SIGN_UNSIGNED | T_SIZE_LONG,
-    T_LONGLONG         = T_TYPE_INT    | T_CLASS_INT    | T_SIGN_SIGNED   | T_SIZE_LONGLONG,
-    T_ULONGLONG        = T_TYPE_INT    | T_CLASS_INT    | T_SIGN_UNSIGNED | T_SIZE_LONGLONG,
-    T_ENUM             = T_TYPE_ENUM   | T_CLASS_INT    | T_SIGN_SIGNED   | T_SIZE_NONE,
-    T_FLOAT    = T_TYPE_FLOAT  | T_CLASS_FLOAT  | T_SIGN_NONE     | T_SIZE_NONE,
-    T_DOUBLE   = T_TYPE_DOUBLE | T_CLASS_FLOAT  | T_SIGN_NONE     | T_SIZE_NONE,
-    T_VOID     = T_TYPE_VOID   | T_CLASS_NONE   | T_SIGN_NONE     | T_SIZE_NONE,
-    T_STRUCT    = T_TYPE_STRUCT | T_CLASS_STRUCT | T_SIGN_NONE     | T_SIZE_NONE,
-    T_UNION     = T_TYPE_UNION  | T_CLASS_STRUCT | T_SIGN_NONE     | T_SIZE_NONE,
-    T_ARRAY    = T_TYPE_ARRAY  | T_CLASS_PTR    | T_SIGN_NONE     | T_SIZE_NONE,
-    T_PTR      = T_TYPE_PTR    | T_CLASS_PTR    | T_SIGN_NONE     | T_SIZE_NONE,
-    T_FUNC             = T_TYPE_FUNC   | T_CLASS_FUNC   | T_SIGN_NONE     | T_SIZE_NONE,
+    T_CHAR             = T_TYPE_CHAR     | T_CLASS_INT    | T_SIGN_UNSIGNED | T_SIZE_NONE,
+    T_SCHAR            = T_TYPE_CHAR     | T_CLASS_INT    | T_SIGN_SIGNED   | T_SIZE_NONE,
+    T_UCHAR            = T_TYPE_CHAR     | T_CLASS_INT    | T_SIGN_UNSIGNED | T_SIZE_NONE,
+    T_SHORT            = T_TYPE_SHORT    | T_CLASS_INT    | T_SIGN_SIGNED   | T_SIZE_SHORT,
+    T_USHORT    = T_TYPE_SHORT    | T_CLASS_INT    | T_SIGN_UNSIGNED | T_SIZE_SHORT,
+    T_INT              = T_TYPE_INT      | T_CLASS_INT    | T_SIGN_SIGNED   | T_SIZE_NONE,
+    T_UINT             = T_TYPE_INT      | T_CLASS_INT    | T_SIGN_UNSIGNED | T_SIZE_NONE,
+    T_LONG             = T_TYPE_LONG     | T_CLASS_INT    | T_SIGN_SIGNED   | T_SIZE_LONG,
+    T_ULONG            = T_TYPE_LONG     | T_CLASS_INT    | T_SIGN_UNSIGNED | T_SIZE_LONG,
+    T_LONGLONG         = T_TYPE_LONGLONG | T_CLASS_INT    | T_SIGN_SIGNED   | T_SIZE_LONGLONG,
+    T_ULONGLONG        = T_TYPE_LONGLONG | T_CLASS_INT    | T_SIGN_UNSIGNED | T_SIZE_LONGLONG,
+    T_ENUM             = T_TYPE_ENUM     | T_CLASS_INT    | T_SIGN_SIGNED   | T_SIZE_NONE,
+    T_FLOAT            = T_TYPE_FLOAT    | T_CLASS_FLOAT  | T_SIGN_NONE     | T_SIZE_NONE,
+    T_DOUBLE           = T_TYPE_DOUBLE   | T_CLASS_FLOAT  | T_SIGN_NONE     | T_SIZE_NONE,
+    T_VOID             = T_TYPE_VOID     | T_CLASS_NONE   | T_SIGN_NONE     | T_SIZE_NONE,
+    T_STRUCT    = T_TYPE_STRUCT   | T_CLASS_STRUCT | T_SIGN_NONE     | T_SIZE_NONE,
+    T_UNION     = T_TYPE_UNION    | T_CLASS_STRUCT | T_SIGN_NONE     | T_SIZE_NONE,
+    T_ARRAY            = T_TYPE_ARRAY    | T_CLASS_PTR    | T_SIGN_NONE     | T_SIZE_NONE,
+    T_PTR              = T_TYPE_PTR      | T_CLASS_PTR    | T_SIGN_NONE     | T_SIZE_NONE,
+    T_FUNC             = T_TYPE_FUNC     | T_CLASS_FUNC   | T_SIGN_NONE     | T_SIZE_NONE,
 
 };
 
@@ -207,6 +210,9 @@ int HasEncode (const type* Type);
 void CopyEncode (const type* Source, type* Target);
 /* Copy encoded data from Source to Target */
 
+type UnqualifiedType (type T);
+/* Return the unqalified type */
+
 unsigned SizeOf (const type* Type);
 /* Compute size of object represented by type array. */
 
@@ -221,37 +227,40 @@ type* Indirect (type* Type);
  * given type points to.
  */
 
+int IsConst (const type* T);
+/* Return true if the given type has a const memory image */
+
 int IsTypeVoid (const type* Type);
 /* Return true if this is a void type */
 
-int IsPtr (const type* Type);
+int IsClassPtr (const type* Type);
 /* Return true if this is a pointer type */
 
-int IsChar (const type* Type);
+int IsTypeChar (const type* Type);
 /* Return true if this is a character type */
 
-int IsInt (const type* Type);
+int IsClassInt (const type* Type);
 /* Return true if this is an integer type */
 
-int IsLong (const type* Type);
+int IsTypeLong (const type* Type);
 /* Return true if this is a long type (signed or unsigned) */
 
 int IsUnsigned (const type* Type);
 /* Return true if this is an unsigned type */
 
-int IsStruct (const type* Type);
+int IsClassStruct (const type* Type);
 /* Return true if this is a struct type */
 
-int IsFunc (const type* Type);
-/* Return true if this is a function type */
+int IsTypeFunc (const type* Type);
+/* Return true if this is a function class */
 
 int IsFastCallFunc (const type* Type);
 /* Return true if this is a function type with __fastcall__ calling conventions */
 
-int IsFuncPtr (const type* Type);
+int IsTypeFuncPtr (const type* Type);
 /* Return true if this is a function pointer */
 
-int IsArray (const type* Type);
+int IsTypeArray (const type* Type);
 /* Return true if this is an array type */
 
 struct FuncDesc* GetFuncDesc (const type* Type);
index 204355c2f6ab407488311c0983c2a6913a5bf1f2..3f285244b181e1520b437ed4f331a83d7170d49d 100644 (file)
 #include <errno.h>
 #include <ctype.h>
 
-#include "../common/xmalloc.h"
+/* common */
+#include "xmalloc.h"
 
+/* cc65 */
 #include "anonname.h"
 #include "codegen.h"
 #include "datatype.h"
@@ -46,13 +48,39 @@ static void ParseTypeSpec (DeclSpec* D, int Default);
 
 
 
-static void optional_modifiers (void)
-/* Eat optional "const" or "volatile" tokens */
+static type OptionalQualifiers (type Q)
+/* Read type qualifiers if we have any */
 {
     while (curtok == TOK_CONST || curtok == TOK_VOLATILE) {
-       /* Skip it */
-       NextToken ();
+
+       switch (curtok) {
+
+           case TOK_CONST:
+               if (Q & T_QUAL_CONST) {
+                   Error (ERR_DUPLICATE_QUALIFIER, "const");
+               }
+               Q |= T_QUAL_CONST;
+               break;
+
+           case TOK_VOLATILE:
+               if (Q & T_QUAL_VOLATILE) {
+                   Error (ERR_DUPLICATE_QUALIFIER, "volatile");
+               }
+               Q |= T_QUAL_VOLATILE;
+               break;
+
+           default:
+               /* Keep gcc silent */
+               break;
+
+       }
+
+       /* Skip the token */
+       NextToken ();
     }
+
+    /* Return the qualifiers read */
+    return Q;
 }
 
 
@@ -93,7 +121,7 @@ static void InitDeclaration (Declaration* D)
 /* Initialize the Declaration struct for use */
 {
     D->Ident[0]                = '\0';
-    D->Type[0]         = T_END;
+    D->Type[0]         = T_END;
     D->T               = D->Type;
 }
 
@@ -278,15 +306,16 @@ static SymEntry* ParseStructDecl (const char* Name, type StructType)
 static void ParseTypeSpec (DeclSpec* D, int Default)
 /* Parse a type specificier */
 {
-    ident      Ident;
+    ident      Ident;
     SymEntry*  Entry;
     type       StructType;
+    type       Qualifiers;     /* Type qualifiers */
 
     /* Assume we have an explicit type */
     D->Flags &= ~DS_DEF_TYPE;
 
-    /* Skip const or volatile modifiers if needed */
-    optional_modifiers ();
+    /* Read type qualifiers if we have any */
+    Qualifiers = OptionalQualifiers (T_QUAL_NONE);
 
     /* Look at the data type */
     switch (curtok) {
@@ -306,29 +335,29 @@ static void ParseTypeSpec (DeclSpec* D, int Default)
        case TOK_LONG:
            NextToken ();
            if (curtok == TOK_UNSIGNED) {
-               NextToken ();
-               optionalint ();
-               D->Type[0] = T_ULONG;
-               D->Type[1] = T_END;
+               NextToken ();
+               optionalint ();
+               D->Type[0] = T_ULONG;
+               D->Type[1] = T_END;
            } else {
-               optionalsigned ();
-               optionalint ();
-               D->Type[0] = T_LONG;
-               D->Type[1] = T_END;
+               optionalsigned ();
+               optionalint ();
+               D->Type[0] = T_LONG;
+               D->Type[1] = T_END;
            }
            break;
 
        case TOK_SHORT:
            NextToken ();
            if (curtok == TOK_UNSIGNED) {
-               NextToken ();
-               optionalint ();
-               D->Type[0] = T_USHORT;
-               D->Type[1] = T_END;
+               NextToken ();
+               optionalint ();
+               D->Type[0] = T_USHORT;
+               D->Type[1] = T_END;
            } else {
-               optionalsigned ();
-               optionalint ();
-               D->Type[0] = T_SHORT;
+               optionalsigned ();
+               optionalint ();
+               D->Type[0] = T_SHORT;
                D->Type[1] = T_END;
            }
            break;
@@ -480,6 +509,9 @@ static void ParseTypeSpec (DeclSpec* D, int Default)
            }
            break;
     }
+
+    /* There may also be qualifiers *after* the initial type */
+    D->Type[0] |= OptionalQualifiers (Qualifiers);
 }
 
 
@@ -489,7 +521,7 @@ static type* ParamTypeCvt (type* T)
  * resulting type.
  */
 {
-    if (IsArray (T)) {
+    if (IsTypeArray (T)) {
                T += DECODE_SIZE;
        T[0] = T_PTR;
     }
@@ -717,12 +749,14 @@ static FuncDesc* ParseFuncDecl (void)
 static void Decl (Declaration* D, unsigned Mode)
 /* Recursively process declarators. Build a type array in reverse order. */
 {
+
     if (curtok == TOK_STAR) {
+       type T = T_PTR;
                NextToken ();
-       /* Allow optional const or volatile modifiers */
-       optional_modifiers ();
+       /* Allow optional const or volatile qualifiers */
+       T |= OptionalQualifiers (T_QUAL_NONE);
                Decl (D, Mode);
-               *D->T++ = T_PTR;
+               *D->T++ = T;
                return;
     } else if (curtok == TOK_LPAREN) {
                NextToken ();
@@ -736,7 +770,7 @@ static void Decl (Declaration* D, unsigned Mode)
        /* Parse the function */
        Decl (D, Mode);
        /* Set the fastcall flag */
-       if (!IsFunc (T)) {
+       if (!IsTypeFunc (T)) {
            Error (ERR_ILLEGAL_MODIFIER);
        } else {
            FuncDesc* F = DecodePtr (T+1);
@@ -840,7 +874,7 @@ void ParseDecl (const DeclSpec* Spec, Declaration* D, unsigned Mode)
     TypeCpy (D->T, Spec->Type);
 
     /* Check the size of the generated type */
-    if (!IsFunc (D->Type) && !IsTypeVoid (D->Type) && SizeOf (D->Type) >= 0x10000) {
+    if (!IsTypeFunc (D->Type) && !IsTypeVoid (D->Type) && SizeOf (D->Type) >= 0x10000) {
        Error (ERR_ILLEGAL_SIZE);
     }
 }
@@ -979,10 +1013,8 @@ static void ParseStructInit (type* Type)
 
 
 
-
-
-void ParseInit (type *tptr)
-/* Parse initialization of variables */
+void ParseInit (type* T)
+/* Parse initialization of variables. */
 {
     int count;
     struct expent lval;
@@ -990,7 +1022,7 @@ void ParseInit (type *tptr)
     const char* str;
     int sz;
 
-    switch (*tptr) {
+    switch (UnqualifiedType (*T)) {
 
        case T_SCHAR:
        case T_UCHAR:
@@ -999,7 +1031,7 @@ void ParseInit (type *tptr)
                /* Make it byte sized */
                lval.e_const &= 0xFF;
            }
-           assignadjust (tptr, &lval);
+           assignadjust (T, &lval);
            DefineData (&lval);
            break;
 
@@ -1013,7 +1045,7 @@ void ParseInit (type *tptr)
                /* Make it word sized */
                lval.e_const &= 0xFFFF;
            }
-           assignadjust (tptr, &lval);
+           assignadjust (T, &lval);
            DefineData (&lval);
            break;
 
@@ -1024,14 +1056,14 @@ void ParseInit (type *tptr)
                /* Make it long sized */
                lval.e_const &= 0xFFFFFFFF;
            }
-           assignadjust (tptr, &lval);
+           assignadjust (T, &lval);
            DefineData (&lval);
            break;
 
        case T_ARRAY:
-           sz = Decode (tptr + 1);
-           t = tptr + DECODE_SIZE + 1;
-                   if ((t [0] == T_CHAR || t [0] == T_UCHAR) && curtok == TOK_SCONST) {
+           sz = 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 */
@@ -1042,7 +1074,7 @@ void ParseInit (type *tptr)
                ConsumeLCurly ();
                count = 0;
                while (curtok != TOK_RCURLY) {
-                   ParseInit (tptr + DECODE_SIZE + 1);
+                   ParseInit (T + DECODE_SIZE + 1);
                    ++count;
                    if (curtok != TOK_COMMA)
                        break;
@@ -1051,9 +1083,9 @@ void ParseInit (type *tptr)
                ConsumeRCurly ();
            }
            if (sz == 0) {
-               Encode (tptr + 1, count);
+               Encode (T + 1, count);
            } else if (count < sz) {
-               g_zerobytes ((sz - count) * SizeOf (tptr + DECODE_SIZE + 1));
+               g_zerobytes ((sz - count) * SizeOf (T + DECODE_SIZE + 1));
            } else if (count > sz) {
                Error (ERR_TOO_MANY_INITIALIZERS);
            }
@@ -1061,7 +1093,7 @@ void ParseInit (type *tptr)
 
         case T_STRUCT:
         case T_UNION:
-           ParseStructInit (tptr);
+           ParseStructInit (T);
            break;
 
        case T_VOID:
index 5ff18ce0a2952013052c418644ee3d37b9a4b5dd..1edf38e2168dbac922c542f6819b2c237fab1488 100644 (file)
@@ -74,7 +74,7 @@ void CheckEmptyDecl (const DeclSpec* D);
  */
 
 void ParseInit (type* tptr);
-/* Parse initialization of variables */
+/* Parse initialization of variables. */
 
 
 
index a668814dacd84e089418694fbcef564a0f9fd05a..0821189e1f8256b7c8e0957710920ad508d2808b 100644 (file)
@@ -135,6 +135,7 @@ static char* ErrMsg [ERR_COUNT-1] = {
     "Illegal hex digit",
     "Illegal character constant",
     "Illegal modifier",
+    "Illegal type qualifier",
     "Illegal storage class",
     "Illegal segment name: `%s'",
     "Division by zero",
@@ -150,6 +151,8 @@ static char* ErrMsg [ERR_COUNT-1] = {
     "__fastcall__ is not allowed for C functions",
     "Variable has unknown size",
     "Unknown identifier: `%s'",
+    "Duplicate qualifier: `%s'",
+    "Assignment to const",
 };
 
 
index 0d41463424f6119c1ba8c3926a121e2259fcdc3f..623dae4ff553459a7e3625f473d8f23774360d9c 100644 (file)
@@ -130,6 +130,7 @@ enum Errors {
     ERR_ILLEGAL_HEX_DIGIT,
     ERR_ILLEGAL_CHARCONST,
     ERR_ILLEGAL_MODIFIER,
+    ERR_ILLEGAL_QUALIFIER,
     ERR_ILLEGAL_STORAGE_CLASS,
     ERR_ILLEGAL_SEG_NAME,
     ERR_DIV_BY_ZERO,
@@ -145,6 +146,8 @@ enum Errors {
     ERR_FASTCALL,
     ERR_UNKNOWN_SIZE,
     ERR_UNKNOWN_IDENT,
+    ERR_DUPLICATE_QUALIFIER,
+    ERR_CONST_ASSIGN,
     ERR_COUNT                          /* Error count */
 };
 
index 995e042689ff7412a2e65a990af7fcad9740f9f8..7717c780f4d2b136feb9cf8731996924ab9e1fe5 100644 (file)
@@ -116,7 +116,7 @@ static unsigned GlobalModeFlags (unsigned flags)
 static int IsNullPtr (struct expent* lval)
 /* Return true if this is the NULL pointer constant */
 {
-    return (IsInt (lval->e_tptr) &&            /* Is it an int? */
+    return (IsClassInt (lval->e_tptr) &&       /* Is it an int? */
                    lval->e_flags == E_MCONST &&        /* Is it constant? */
            lval->e_const == 0);                /* And is it's value zero? */
 }
@@ -131,7 +131,7 @@ static type* promoteint (type* lhst, type* rhst)
      *   - If one of the values        is unsigned, the result is also unsigned.
      *   - Otherwise the result is an int.
      */
-    if (IsLong (lhst) || IsLong (rhst)) {
+    if (IsTypeLong (lhst) || IsTypeLong (rhst)) {
        if (IsUnsigned (lhst) || IsUnsigned (rhst)) {
                    return type_ulong;
        } else {
@@ -209,11 +209,11 @@ unsigned assignadjust (type* lhst, struct expent* rhs)
         * error message.
         */
                Error (ERR_ILLEGAL_TYPE);
-    } else if (IsInt (lhst)) {
-       if (IsPtr (rhst)) {
+    } else if (IsClassInt (lhst)) {
+               if (IsClassPtr (rhst)) {
            /* Pointer -> int conversion */
            Warning (WARN_PTR_TO_INT_CONV);
-               } else if (!IsInt (rhst)) {
+               } else if (!IsClassInt (rhst)) {
            Error (ERR_INCOMPATIBLE_TYPES);
        } else {
            /* Adjust the int types. To avoid manipulation of TOS mark lhs
@@ -225,8 +225,8 @@ unsigned assignadjust (type* lhst, struct expent* rhs)
            }
            return g_typeadjust (TypeOf (lhst) | CF_CONST, flags);
         }
-    } else if (IsPtr (lhst)) {
-       if (IsPtr (rhst)) {
+    } else if (IsClassPtr (lhst)) {
+       if (IsClassPtr (rhst)) {
            /* Pointer to pointer assignment is valid, if:
             *   - both point to the same types, or
             *   - the rhs pointer is a void pointer, or
@@ -237,12 +237,12 @@ unsigned assignadjust (type* lhst, struct expent* rhs)
                    if (!EqualTypes (left, right) && *left != T_VOID && *right != T_VOID) {
                Error (ERR_INCOMPATIBLE_POINTERS);
            }
-       } else if (IsInt (rhst)) {
+       } else if (IsClassInt (rhst)) {
            /* Int to pointer assignment is valid only for constant zero */
            if ((rhs->e_flags & E_MCONST) == 0 || rhs->e_const != 0) {
                Warning (WARN_INT_TO_PTR_CONV);
            }
-       } else if (IsFuncPtr (lhst) && IsFunc(rhst)) {
+       } else if (IsTypeFuncPtr (lhst) && IsTypeFunc(rhst)) {
            /* Assignment of function to function pointer is allowed, provided
             * that both functions have the same parameter list.
             */
@@ -785,7 +785,7 @@ static int primary (struct expent* lval)
 
            /* The symbol is referenced now */
            Sym->Flags |= SC_REF;
-                   if (IsFunc (lval->e_tptr) || IsArray (lval->e_tptr)) {
+                   if (IsTypeFunc (lval->e_tptr) || IsTypeArray (lval->e_tptr)) {
                return 0;
            }
            return 1;
@@ -917,7 +917,7 @@ static int arrayref (int k, struct expent* lval)
            exprhs (CF_NONE, k, lval);
        }
 
-       if (IsPtr (tptr1)) {
+       if (IsClassPtr (tptr1)) {
 
            /* Scale the subscript value according to element size */
            lval2.e_const *= PSizeOf (tptr1);
@@ -928,7 +928,7 @@ static int arrayref (int k, struct expent* lval)
            /* Handle constant base array on stack. Be sure NOT to
             * handle pointers the same way, this won't work.
             */
-           if (IsArray (tptr1) &&
+           if (IsTypeArray (tptr1) &&
                ((lval->e_flags & ~E_MCTYPE) == E_MCONST ||
                (lval->e_flags & ~E_MCTYPE) == E_MLOCAL ||
                (lval->e_flags & E_MGLOBAL) != 0 ||
@@ -950,7 +950,7 @@ static int arrayref (int k, struct expent* lval)
            /* Done */
            goto end_array;
 
-               } else if (IsPtr (tptr2 = lval2.e_tptr)) {
+               } else if (IsClassPtr (tptr2 = lval2.e_tptr)) {
            /* Subscript is pointer, get element type */
            lval2.e_tptr = Indirect (tptr2);
 
@@ -975,7 +975,7 @@ static int arrayref (int k, struct expent* lval)
         exprhs (CF_NONE, l, &lval2);
 
        tptr2 = lval2.e_tptr;
-       if (IsPtr (tptr1)) {
+       if (IsClassPtr (tptr1)) {
 
            /* Get the element type */
            lval->e_tptr = Indirect (tptr1);
@@ -986,7 +986,7 @@ static int arrayref (int k, struct expent* lval)
             */
            g_scale (CF_INT, SizeOf (lval->e_tptr));
 
-       } else if (IsPtr (tptr2)) {
+       } else if (IsClassPtr (tptr2)) {
 
            /* Get the element type */
            lval2.e_tptr = Indirect (tptr2);
@@ -1065,7 +1065,7 @@ static int arrayref (int k, struct expent* lval)
                    g_inc (CF_INT | CF_UNSIGNED, lval->e_const);
                } else if (lflags == E_MLOCAL) {
                    /* Base address is a local variable address */
-                   if (IsArray (tptr1)) {
+                   if (IsTypeArray (tptr1)) {
                        g_addaddr_local (CF_INT, lval->e_const);
                    } else {
                        g_addlocal (CF_PTR, lval->e_const);
@@ -1074,7 +1074,7 @@ static int arrayref (int k, struct expent* lval)
                    /* Base address is a static variable address */
                    unsigned flags = CF_INT;
                    flags |= GlobalModeFlags (lval->e_flags);
-                   if (IsArray (tptr1)) {
+                   if (IsTypeArray (tptr1)) {
                        g_addaddr_static (flags, lval->e_name, lval->e_const);
                    } else {
                        g_addstatic (flags, lval->e_name, lval->e_const);
@@ -1086,7 +1086,7 @@ static int arrayref (int k, struct expent* lval)
     lval->e_flags = E_MEXPR;
 end_array:
     ConsumeRBrack ();
-    return !IsArray (lval->e_tptr);
+    return !IsTypeArray (lval->e_tptr);
 
 }
 
@@ -1132,7 +1132,7 @@ static int structref (int k, struct expent* lval)
        lval->e_flags = E_MEOFFS;
     }
     lval->e_tptr = Field->Type;
-    return !IsArray (Field->Type);
+    return !IsTypeArray (Field->Type);
 }
 
 
@@ -1162,8 +1162,8 @@ static int hie11 (struct expent *lval)
            /* Function call. Skip the opening parenthesis */
            NextToken ();
            tptr = lval->e_tptr;
-           if (IsFunc (tptr) || IsFuncPtr (tptr)) {
-               if (IsFuncPtr (tptr)) {
+           if (IsTypeFunc (tptr) || IsTypeFuncPtr (tptr)) {
+               if (IsTypeFuncPtr (tptr)) {
                    /* Pointer to function. Handle transparently */
                    exprhs (CF_NONE, k, lval);  /* Function pointer to A/X */
                    ++lval->e_tptr;             /* Skip T_PTR */
@@ -1179,7 +1179,7 @@ static int hie11 (struct expent *lval)
 
        } else if (curtok == TOK_DOT) {
 
-           if (!IsStruct (lval->e_tptr)) {
+           if (!IsClassStruct (lval->e_tptr)) {
                Error (ERR_STRUCT_EXPECTED);
            }
            k = structref (0, lval);
@@ -1474,7 +1474,7 @@ static int hie10 (struct expent* lval)
                lval->e_const = 0;              /* Offset is zero now */
            }
            t = lval->e_tptr;
-                   if (IsPtr (t)) {
+                   if (IsClassPtr (t)) {
                        lval->e_tptr = Indirect (t);
            } else {
                Error (ERR_ILLEGAL_INDIRECT);
@@ -1486,7 +1486,7 @@ static int hie10 (struct expent* lval)
            k = hie10 (lval);
            if (k == 0) {
                /* Allow the & operator with an array */
-               if (!IsArray (lval->e_tptr)) {
+               if (!IsTypeArray (lval->e_tptr)) {
                    Error (ERR_ILLEGAL_ADDRESS);
                }
            } else {
@@ -1566,7 +1566,7 @@ static int hie_internal (GenDesc** ops,           /* List of generators */
        *UsedGen = 1;
 
        /* All operators that call this function expect an int on the lhs */
-       if (!IsInt (lval->e_tptr)) {
+       if (!IsClassInt (lval->e_tptr)) {
            Error (ERR_INT_EXPR_EXPECTED);
        }
 
@@ -1592,7 +1592,7 @@ static int hie_internal (GenDesc** ops,           /* List of generators */
        rconst = (evalexpr (CF_NONE, hienext, &lval2) == 0);
 
        /* Check the type of the rhs */
-       if (!IsInt (lval2.e_tptr)) {
+       if (!IsClassInt (lval2.e_tptr)) {
            Error (ERR_INT_EXPR_EXPECTED);
        }
 
@@ -1692,12 +1692,12 @@ static int hie_compare (GenDesc** ops,          /* List of generators */
        rconst = (evalexpr (CF_NONE, hienext, &lval2) == 0);
 
        /* Make sure, the types are compatible */
-       if (IsInt (lval->e_tptr)) {
-           if (!IsInt (lval2.e_tptr) && !(IsPtr(lval2.e_tptr) && IsNullPtr(lval))) {
+       if (IsClassInt (lval->e_tptr)) {
+           if (!IsClassInt (lval2.e_tptr) && !(IsClassPtr(lval2.e_tptr) && IsNullPtr(lval))) {
                Error (ERR_INCOMPATIBLE_TYPES);
            }
-       } else if (IsPtr (lval->e_tptr)) {
-           if (IsPtr (lval2.e_tptr)) {
+       } else if (IsClassPtr (lval->e_tptr)) {
+           if (IsClassPtr (lval2.e_tptr)) {
                /* Both pointers are allowed in comparison if they point to
                 * the same type, or if one of them is a void pointer.
                 */
@@ -1744,7 +1744,7 @@ static int hie_compare (GenDesc** ops,            /* List of generators */
             * operation as char operation. Otherwise the default
             * promotions are used.
             */
-           if (IsChar (lval->e_tptr) && (IsChar (lval2.e_tptr) || rconst)) {
+           if (IsTypeChar (lval->e_tptr) && (IsTypeChar (lval2.e_tptr) || rconst)) {
                flags |= CF_CHAR;
                if (IsUnsigned (lval->e_tptr) || IsUnsigned (lval2.e_tptr)) {
                    flags |= CF_UNSIGNED;
@@ -1818,16 +1818,16 @@ static void parseadd (int k, struct expent* lval)
            rhst = lval2.e_tptr;
 
            /* Both expressions are constants. Check for pointer arithmetic */
-                   if (IsPtr (lhst) && IsInt (rhst)) {
+                   if (IsClassPtr (lhst) && IsClassInt (rhst)) {
                        /* Left is pointer, right is int, must scale rhs */
                lval->e_const = lval->e_const + lval2.e_const * PSizeOf (lhst);
                /* Result type is a pointer */
-           } else if (IsInt (lhst) && IsPtr (rhst)) {
+           } else if (IsClassInt (lhst) && IsClassPtr (rhst)) {
                /* Left is int, right is pointer, must scale lhs */
                        lval->e_const = lval->e_const * PSizeOf (rhst) + lval2.e_const;
                /* Result type is a pointer */
                lval->e_tptr = lval2.e_tptr;
-                   } else if (IsInt (lhst) && IsInt (rhst)) {
+                   } else if (IsClassInt (lhst) && IsClassInt (rhst)) {
                /* Integer addition */
                lval->e_const += lval2.e_const;
                typeadjust (lval, &lval2, 1);
@@ -1845,18 +1845,18 @@ static void parseadd (int k, struct expent* lval)
            rhst = lval2.e_tptr;
 
            /* Check for pointer arithmetic */
-           if (IsPtr (lhst) && IsInt (rhst)) {
+           if (IsClassPtr (lhst) && IsClassInt (rhst)) {
                /* Left is pointer, right is int, must scale rhs */
                g_scale (CF_INT, PSizeOf (lhst));
                /* Operate on pointers, result type is a pointer */
                flags = CF_PTR;
-           } else if (IsInt (lhst) && IsPtr (rhst)) {
+           } else if (IsClassInt (lhst) && IsClassPtr (rhst)) {
                /* Left is int, right is pointer, must scale lhs */
                        lval->e_const *= PSizeOf (rhst);
                /* Operate on pointers, result type is a pointer */
                flags = CF_PTR;
                lval->e_tptr = lval2.e_tptr;
-                   } else if (IsInt (lhst) && IsInt (rhst)) {
+                   } else if (IsClassInt (lhst) && IsClassInt (rhst)) {
                /* Integer addition */
                        flags = typeadjust (lval, &lval2, 1);
            } else {
@@ -1891,18 +1891,18 @@ static void parseadd (int k, struct expent* lval)
            pop (TypeOf (lval->e_tptr));
 
                    /* Check for pointer arithmetic */
-                   if (IsPtr (lhst) && IsInt (rhst)) {
+                   if (IsClassPtr (lhst) && IsClassInt (rhst)) {
                /* Left is pointer, right is int, must scale rhs */
                lval2.e_const *= PSizeOf (lhst);
                /* Operate on pointers, result type is a pointer */
                flags = CF_PTR;
-           } else if (IsInt (lhst) && IsPtr (rhst)) {
+           } else if (IsClassInt (lhst) && IsClassPtr (rhst)) {
                /* Left is int, right is pointer, must scale lhs (ptr only) */
                        g_scale (CF_INT | CF_CONST, PSizeOf (rhst));
                        /* Operate on pointers, result type is a pointer */
                flags = CF_PTR;
                lval->e_tptr = lval2.e_tptr;
-                   } else if (IsInt (lhst) && IsInt (rhst)) {
+                   } else if (IsClassInt (lhst) && IsClassInt (rhst)) {
                /* Integer addition */
                flags = typeadjust (lval, &lval2, 1);
                    } else {
@@ -1923,12 +1923,12 @@ static void parseadd (int k, struct expent* lval)
            rhst = lval2.e_tptr;
 
            /* Check for pointer arithmetic */
-           if (IsPtr (lhst) && IsInt (rhst)) {
+           if (IsClassPtr (lhst) && IsClassInt (rhst)) {
                /* Left is pointer, right is int, must scale rhs */
                g_scale (CF_INT, PSizeOf (lhst));
                /* Operate on pointers, result type is a pointer */
                flags = CF_PTR;
-           } else if (IsInt (lhst) && IsPtr (rhst)) {
+           } else if (IsClassInt (lhst) && IsClassPtr (rhst)) {
                /* Left is int, right is pointer, must scale lhs */
                g_tosint (TypeOf (rhst));       /* Make sure, TOS is int */
                g_swap (CF_INT);                /* Swap TOS and primary */
@@ -1936,7 +1936,7 @@ static void parseadd (int k, struct expent* lval)
                /* Operate on pointers, result type is a pointer */
                flags = CF_PTR;
                lval->e_tptr = lval2.e_tptr;
-                   } else if (IsInt (lhst) && IsInt (rhst)) {
+                   } else if (IsClassInt (lhst) && IsClassInt (rhst)) {
                /* Integer addition */
                        flags = typeadjust (lval, &lval2, 0);
            } else {
@@ -2001,11 +2001,11 @@ static void parsesub (int k, struct expent* lval)
            pop (TypeOf (lhst));        /* Clean up the stack */
 
            /* Check for pointer arithmetic */
-           if (IsPtr (lhst) && IsInt (rhst)) {
+           if (IsClassPtr (lhst) && IsClassInt (rhst)) {
                /* Left is pointer, right is int, must scale rhs */
                lval->e_const -= lval2.e_const * PSizeOf (lhst);
                /* Operate on pointers, result type is a pointer */
-           } else if (IsPtr (lhst) && IsPtr (rhst)) {
+           } else if (IsClassPtr (lhst) && IsClassPtr (rhst)) {
                /* Left is pointer, right is pointer, must scale result */
                if (TypeCmp (Indirect (lhst), Indirect (rhst)) != 0) {
                    Error (ERR_INCOMPATIBLE_POINTERS);
@@ -2014,7 +2014,7 @@ static void parsesub (int k, struct expent* lval)
                }
                /* Operate on pointers, result type is an integer */
                lval->e_tptr = type_int;
-           } else if (IsInt (lhst) && IsInt (rhst)) {
+           } else if (IsClassInt (lhst) && IsClassInt (rhst)) {
                /* Integer subtraction */
                        typeadjust (lval, &lval2, 1);
                lval->e_const -= lval2.e_const;
@@ -2035,12 +2035,12 @@ static void parsesub (int k, struct expent* lval)
            RemoveCode (Mark2);
            pop (TypeOf (lhst));
 
-           if (IsPtr (lhst) && IsInt (rhst)) {
+           if (IsClassPtr (lhst) && IsClassInt (rhst)) {
                /* Left is pointer, right is int, must scale rhs */
                        lval2.e_const *= PSizeOf (lhst);
                /* Operate on pointers, result type is a pointer */
                flags = CF_PTR;
-           } else if (IsPtr (lhst) && IsPtr (rhst)) {
+           } else if (IsClassPtr (lhst) && IsClassPtr (rhst)) {
                /* Left is pointer, right is pointer, must scale result */
                if (TypeCmp (Indirect (lhst), Indirect (rhst)) != 0) {
                    Error (ERR_INCOMPATIBLE_POINTERS);
@@ -2050,7 +2050,7 @@ static void parsesub (int k, struct expent* lval)
                /* Operate on pointers, result type is an integer */
                flags = CF_PTR;
                lval->e_tptr = type_int;
-           } else if (IsInt (lhst) && IsInt (rhst)) {
+           } else if (IsClassInt (lhst) && IsClassInt (rhst)) {
                /* Integer subtraction */
                        flags = typeadjust (lval, &lval2, 1);
            } else {
@@ -2078,12 +2078,12 @@ static void parsesub (int k, struct expent* lval)
        rhst = lval2.e_tptr;
 
                /* Check for pointer arithmetic */
-       if (IsPtr (lhst) && IsInt (rhst)) {
+       if (IsClassPtr (lhst) && IsClassInt (rhst)) {
            /* Left is pointer, right is int, must scale rhs */
            g_scale (CF_INT, PSizeOf (lhst));
            /* Operate on pointers, result type is a pointer */
            flags = CF_PTR;
-       } else if (IsPtr (lhst) && IsPtr (rhst)) {
+       } else if (IsClassPtr (lhst) && IsClassPtr (rhst)) {
            /* Left is pointer, right is pointer, must scale result */
            if (TypeCmp (Indirect (lhst), Indirect (rhst)) != 0) {
                Error (ERR_INCOMPATIBLE_POINTERS);
@@ -2093,7 +2093,7 @@ static void parsesub (int k, struct expent* lval)
            /* Operate on pointers, result type is an integer */
            flags = CF_PTR;
            lval->e_tptr = type_int;
-       } else if (IsInt (lhst) && IsInt (rhst)) {
+       } else if (IsClassInt (lhst) && IsClassInt (rhst)) {
            /* Integer subtraction. If the left hand side descriptor says that
             * the lhs is const, we have to remove this mark, since this is no
             * longer true, lhs is on stack instead.
@@ -2409,7 +2409,7 @@ static int hieQuest (struct expent *lval)
         */
        type2 = lval2.e_tptr;
        type3 = lval3.e_tptr;
-       if (IsInt (type2) && IsInt (type3)) {
+       if (IsClassInt (type2) && IsClassInt (type3)) {
 
            /* Get common type */
            rtype = promoteint (type2, type3);
@@ -2442,17 +2442,17 @@ static int hieQuest (struct expent *lval)
                labt = 0;               /* Mark other label as invalid */
            }
 
-       } else if (IsPtr (type2) && IsPtr (type3)) {
+       } else if (IsClassPtr (type2) && IsClassPtr (type3)) {
            /* Must point to same type */
            if (TypeCmp (Indirect (type2), Indirect (type3)) != 0) {
                Error (ERR_INCOMPATIBLE_TYPES);
            }
            /* Result has the common type */
            rtype = lval2.e_tptr;
-       } else if (IsPtr (type2) && IsNullPtr (&lval3)) {
+       } else if (IsClassPtr (type2) && IsNullPtr (&lval3)) {
            /* Result type is pointer, no cast needed */
            rtype = lval2.e_tptr;
-       } else if (IsNullPtr (&lval2) && IsPtr (type3)) {
+       } else if (IsNullPtr (&lval2) && IsClassPtr (type3)) {
            /* Result type is pointer, no cast needed */
            rtype = lval3.e_tptr;
        } else {
@@ -2656,11 +2656,16 @@ static void Assignment (struct expent* lval)
     unsigned flags;
     type* ltype = lval->e_tptr;
 
+    /* Check for assignment to const */
+    if (IsConst (ltype)) {
+       Error (ERR_CONST_ASSIGN);
+    }
+
     /* cc65 does not have full support for handling structs by value. Since
      * assigning structs is one of the more useful operations from this
      * familiy, allow it here.
      */
-    if (IsStruct (ltype)) {
+    if (IsClassStruct (ltype)) {
 
                /* Bring the address of the lhs into the primary and push it */
        exprhs (0, 0, lval);
@@ -2889,7 +2894,7 @@ void intexpr (struct expent* lval)
 /* Get an integer expression */
 {
     expression (lval);
-    if (!IsInt (lval->e_tptr)) {
+    if (!IsClassInt (lval->e_tptr)) {
        Error (ERR_INT_EXPR_EXPECTED);
        /* To avoid any compiler errors, make the expression a valid int */
        lval->e_flags = E_MCONST;
@@ -2910,7 +2915,7 @@ void boolexpr (struct expent* lval)
      * the pointer used in a boolean context is also ok (Ootherwise check if it's a pointer
      * expression.
      */
-    if (!IsInt (lval->e_tptr) && !IsPtr (lval->e_tptr)) {
+    if (!IsClassInt (lval->e_tptr) && !IsClassPtr (lval->e_tptr)) {
        Error (ERR_INT_EXPR_EXPECTED);
        /* To avoid any compiler errors, make the expression a valid int */
        lval->e_flags = E_MCONST;
index 3cf6c61276de5dff567003145b51c89d748105e9..25fb3262f5629650f1fc4f69e242fa6136919c13 100644 (file)
@@ -146,7 +146,7 @@ static void ParseOneDecl (const DeclSpec* Spec)
     ParseDecl (Spec, &Decl, DM_NEED_IDENT);
 
     /* Set the correct storage class for functions */
-    if (IsFunc (Decl.Type)) {
+    if (IsTypeFunc (Decl.Type)) {
        /* Function prototypes are always external */
        if ((SC & SC_EXTERN) == 0) {
                    Warning (WARN_FUNC_MUST_BE_EXTERN);
index ff016ac10f0136893380d6b4c6ac6be46ad32567..496843c2fc1b8dcdd35d075f10cf26fd0aaf947e 100644 (file)
 #include <stdio.h>
 #include <string.h>
 
-#include "../common/xmalloc.h"
-
+/* common */
+#include "xmalloc.h"
+         
+/* cc65 */
 #include "asmcode.h"
 #include "asmlabel.h"
 #include "codegen.h"
@@ -298,7 +300,7 @@ static void cascadeswitch (struct expent* eval)
 
                    /* Read the selector expression */
                    constexpr (&lval);
-                   if (!IsInt (lval.e_tptr)) {
+                   if (!IsClassInt (lval.e_tptr)) {
                        Error (ERR_ILLEGAL_TYPE);
                    }
 
@@ -456,7 +458,7 @@ static void tableswitch (struct expent* eval)
                if (curtok == TOK_CASE) {
                            NextToken ();
                    constexpr (&lval);
-                   if (!IsInt (lval.e_tptr)) {
+                   if (!IsClassInt (lval.e_tptr)) {
                        Error (ERR_ILLEGAL_TYPE);
                    }
                    p->sw_const = lval.e_const;
@@ -538,7 +540,7 @@ static void doswitch (void)
     ConsumeLCurly ();
 
     /* Now decide which sort of switch we will create: */
-    if (IsChar (eval.e_tptr) || (FavourSize == 0 && IsInt (eval.e_tptr))) {
+    if (IsTypeChar (eval.e_tptr) || (FavourSize == 0 && IsClassInt (eval.e_tptr))) {
                cascadeswitch (&eval);
     } else {
        tableswitch (&eval);
index 79fb1d50aee0d2aaef58c2098b0157f38aa03218..7a80b81be110ca60b53ea21005b92670cda3635f 100644 (file)
@@ -467,7 +467,7 @@ SymEntry* FindStructField (const type* Type, const char* Name)
     }
 
     /* Non-structs do not have any struct fields... */
-    if (IsStruct (Type)) {
+    if (IsClassStruct (Type)) {
 
        const SymTable* Tab;
 
@@ -664,7 +664,7 @@ SymEntry* AddGlobalSym (const char* Name, type* Type, unsigned Flags)
 /* Add an external or global symbol to the symbol table and return the entry */
 {
     /* Functions must be inserted in the global symbol table */
-    SymTable* Tab = IsFunc (Type)? SymTab0 : SymTab;
+    SymTable* Tab = IsTypeFunc (Type)? SymTab0 : SymTab;
 
     /* Do we have an entry with this name already? */
     SymEntry* Entry = FindSymInTable (Tab, Name, HashStr (Name));
@@ -685,7 +685,7 @@ SymEntry* AddGlobalSym (const char* Name, type* Type, unsigned Flags)
         * incomplete declaration. Accept this, and if the exsting entry is
         * incomplete, complete it.
         */
-       if (IsArray (Type) && IsArray (EType)) {
+       if (IsTypeArray (Type) && IsTypeArray (EType)) {
 
            /* Get the array sizes */
            unsigned Size  = Decode (Type + 1);
@@ -713,7 +713,7 @@ SymEntry* AddGlobalSym (const char* Name, type* Type, unsigned Flags)
             * contains pointers to the new symbol tables that are needed if
             * an actual function definition follows.
             */
-           if (IsFunc (Type)) {
+           if (IsTypeFunc (Type)) {
                CopyEncode (Type+1, EType+1);
            }
        }