From 6230b6a81397ce9e9b1fa67f8da5adc7fa9fbc5a Mon Sep 17 00:00:00 2001 From: Greg King Date: Mon, 9 Mar 2015 18:53:45 -0400 Subject: [PATCH] Completed the cc65 code that recognizes __CDECL__ as a calling convention qualifier. --- src/cc65/datatype.c | 14 +++++------ src/cc65/datatype.h | 12 ++++++++- src/cc65/declare.c | 59 +++++++++++++++++++++++++++------------------ 3 files changed, 53 insertions(+), 32 deletions(-) diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index 053810b50..8d17d2851 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -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; } diff --git a/src/cc65/datatype.h b/src/cc65/datatype.h index 598d0a228..92b3d0122 100644 --- a/src/cc65/datatype.h +++ b/src/cc65/datatype.h @@ -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 diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 693c2116e..e6417c6a8 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -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 */ -- 2.39.5