]> git.sur5r.net Git - cc65/commitdiff
Completed the cc65 code that recognizes __CDECL__ as a calling convention qualifier.
authorGreg King <gregdk@users.sf.net>
Mon, 9 Mar 2015 22:53:45 +0000 (18:53 -0400)
committerGreg King <gregdk@users.sf.net>
Mon, 9 Mar 2015 23:39:04 +0000 (19:39 -0400)
src/cc65/datatype.c
src/cc65/datatype.h
src/cc65/declare.c

index 053810b50c0b1356825700dc8bf216abd6fa92d6..8d17d28510db2511b1d4240d3bdb019a442a8480 100644 (file)
@@ -6,7 +6,7 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 1998-2012, Ullrich von Bassewitz                                      */
+/* (C) 1998-2015, Ullrich von Bassewitz                                      */
 /*                Roemerstrasse 52                                           */
 /*                D-70794 Filderstadt                                        */
 /* EMail:         uz@cc65.org                                                */
@@ -290,18 +290,18 @@ void PrintType (FILE* F, const Type* T)
                 fprintf (F, "union %s", ((SymEntry*) T->A.P)->Name);
                 break;
             case T_TYPE_ARRAY:
-                /* Recursive call */
-                PrintType (F, T + 1);
                 if (T->A.L == UNSPECIFIED) {
-                    fprintf (F, "[]");
+                    fprintf (F, "[] ");
                 } else {
-                    fprintf (F, "[%ld]", T->A.L);
+                    fprintf (F, "[%ld] ", T->A.L);
                 }
+                /* Recursive call */
+                PrintType (F, T + 1);
                 return;
             case T_TYPE_PTR:
+                fprintf (F, "* ");
                 /* Recursive call */
                 PrintType (F, T + 1);
-                fprintf (F, "*");
                 return;
             case T_TYPE_FUNC:
                 fprintf (F, "function returning ");
@@ -659,7 +659,7 @@ Type* GetBaseElementType (Type* T)
 ** will return. Otherwise it will return the base element type, which means
 ** the element type that is not an array.
 */
-{     
+{
     while (IsTypeArray (T)) {
         ++T;
     }
index 598d0a22859919f66fc33a624f92e93835a4b2f2..92b3d0122d3d71f475ddea95bf4d690f3a9d28ac 100644 (file)
@@ -6,7 +6,7 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 1998-2012, Ullrich von Bassewitz                                      */
+/* (C) 1998-2015, Ullrich von Bassewitz                                      */
 /*                Roemerstrasse 52                                           */
 /*                D-70794 Filderstadt                                        */
 /* EMail:         uz@cc65.org                                                */
@@ -603,6 +603,16 @@ INLINE int IsQualCDecl (const Type* T)
 #  define IsQualCDecl(T)        (((T)->C & T_QUAL_CDECL) != 0)
 #endif
 
+#if defined(HAVE_INLINE)
+INLINE int IsQualCConv (const Type* T)
+/* Return true if the given type has a calling convention qualifier */
+{
+    return (T->C & T_QUAL_CCONV) != 0;
+}
+#else
+#  define IsQualCConv(T)        (((T)->C & T_QUAL_CCONV) != 0)
+#endif
+
 int IsVariadicFunc (const Type* T) attribute ((const));
 /* Return true if this is a function type or pointer to function type with
 ** variable parameter list
index 693c2116e5c830ce836855089e7796ee336e517c..e6417c6a819937f83babf8b34c8b56f3d3e72b7c 100644 (file)
@@ -6,7 +6,7 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 1998-2013, Ullrich von Bassewitz                                      */
+/* (C) 1998-2015, Ullrich von Bassewitz                                      */
 /*                Roemerstrasse 52                                           */
 /*                D-70794 Filderstadt                                        */
 /* EMail:         uz@cc65.org                                                */
@@ -85,7 +85,7 @@ struct StructInitData {
 
 
 static void ParseTypeSpec (DeclSpec* D, long Default, TypeCode Qualifiers);
-/* Parse a type specificier */
+/* Parse a type specifier */
 
 static unsigned ParseInitInternal (Type* T, int AllowFlexibleMembers);
 /* Parse initialization of variables. Return the number of data bytes. */
@@ -336,17 +336,28 @@ static void FixQualifiers (Type* DataType)
     while (T->C != T_END) {
         if (IsTypePtr (T)) {
 
-            /* Fastcall qualifier on the pointer? */
-            if (IsQualFastcall (T)) {
-                /* Pointer to function which is not fastcall? */
-                if (IsTypeFunc (T+1) && !IsQualFastcall (T+1)) {
-                    /* Move the fastcall qualifier from the pointer to
-                    ** the function.
-                    */
-                    T[0].C &= ~T_QUAL_FASTCALL;
-                    T[1].C |= T_QUAL_FASTCALL;
+            /* Calling convention qualifier on the pointer? */
+            if (IsQualCConv (T)) {
+                /* Pull the convention off of the pointer */
+                Q = T[0].C & T_QUAL_CCONV;
+                T[0].C &= ~T_QUAL_CCONV;
+                /* Pointer to a function which doesn't have an explicit convention? */
+                if (IsTypeFunc (T + 1)) {
+                    if (IsQualCConv (T + 1)) {
+                        if (T[1].C == Q) {
+                            /* TODO: The end of Declarator() catches this error.
+                            ** Try to make it let the error be caught here, instead.
+                            */
+                            Warning ("Pointer duplicates function's calling convention");
+                        } else {
+                            Error ("Mismatch between pointer's and function's calling conventions");
+                        }
+                    } else {
+                        /* Move the qualifier from the pointer to the function. */
+                        T[1].C |= Q;
+                    }
                 } else {
-                    Error ("Invalid `_fastcall__' qualifier for pointer");
+                    Error ("Not pointer to a function; can't use a calling convention");
                 }
             }
 
@@ -355,8 +366,8 @@ static void FixQualifiers (Type* DataType)
             if (Q == T_QUAL_NONE) {
                 /* No address size qualifiers specified */
                 if (IsTypeFunc (T+1)) {
-                    /* Pointer to function. Use the qualifier from the function
-                    ** or the default if the function don't has one.
+                    /* Pointer to function. Use the qualifier from the function,
+                    ** or the default if the function doesn't have one.
                     */
                     Q = (T[1].C & T_QUAL_ADDRSIZE);
                     if (Q == T_QUAL_NONE) {
@@ -368,7 +379,7 @@ static void FixQualifiers (Type* DataType)
                 T[0].C |= Q;
             } else {
                 /* We have address size qualifiers. If followed by a function,
-                ** apply these also to the function.
+                ** apply them to the function also.
                 */
                 if (IsTypeFunc (T+1)) {
                     TypeCode FQ = (T[1].C & T_QUAL_ADDRSIZE);
@@ -489,7 +500,7 @@ static void ParseEnumDecl (void)
 
 
 static int ParseFieldWidth (Declaration* Decl)
-/* Parse an optional field width. Returns -1 if no field width is speficied,
+/* Parse an optional field width. Returns -1 if no field width is specified,
 ** otherwise the width of the field.
 */
 {
@@ -862,7 +873,7 @@ NextMember: if (CurTok.Tok != TOK_COMMA) {
 
 
 static void ParseTypeSpec (DeclSpec* D, long Default, TypeCode Qualifiers)
-/* Parse a type specificier */
+/* Parse a type specifier */
 {
     ident       Ident;
     SymEntry*   Entry;
@@ -1376,13 +1387,13 @@ static FuncDesc* ParseFuncDecl (void)
 static void Declarator (const DeclSpec* Spec, Declaration* D, declmode_t Mode)
 /* Recursively process declarators. Build a type array in reverse order. */
 {
-    /* Read optional function or pointer qualifiers. These modify the
-    ** identifier or token to the right. For convenience, we allow the fastcall
-    ** qualifier also for pointers here. If it is a pointer-to-function, the
-    ** qualifier will later be transfered to the function itself. If it's a
+    /* Read optional function or pointer qualifiers. They modify the
+    ** identifier or token to the right. For convenience, we allow a calling
+    ** convention also for pointers here. If it's a pointer-to-function, the
+    ** qualifier later will be transfered to the function itself. If it's a
     ** pointer to something else, it will be flagged as an error.
     */
-    TypeCode Qualifiers = OptionalQualifiers (T_QUAL_ADDRSIZE | T_QUAL_FASTCALL);
+    TypeCode Qualifiers = OptionalQualifiers (T_QUAL_ADDRSIZE | T_QUAL_CCONV);
 
     /* Pointer to something */
     if (CurTok.Tok == TOK_STAR) {
@@ -1390,10 +1401,10 @@ static void Declarator (const DeclSpec* Spec, Declaration* D, declmode_t Mode)
         /* Skip the star */
         NextToken ();
 
-        /* Allow const, restrict and volatile qualifiers */
+        /* Allow const, restrict, and volatile qualifiers */
         Qualifiers |= OptionalQualifiers (T_QUAL_CONST | T_QUAL_VOLATILE | T_QUAL_RESTRICT);
 
-        /* Parse the type, the pointer points to */
+        /* Parse the type that the pointer points to */
         Declarator (Spec, D, Mode);
 
         /* Add the type */