Completed the cc65 code that recognizes __CDECL__ as a calling convention qualifier.

This commit is contained in:
Greg King 2015-03-09 18:53:45 -04:00
parent f014800d3c
commit 6230b6a813
3 changed files with 54 additions and 33 deletions

View 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:
if (T->A.L == UNSPECIFIED) {
fprintf (F, "[] ");
} else {
fprintf (F, "[%ld] ", T->A.L);
}
/* Recursive call */
PrintType (F, T + 1);
if (T->A.L == UNSPECIFIED) {
fprintf (F, "[]");
} else {
fprintf (F, "[%ld]", T->A.L);
}
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;
}

View 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

View 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 */