Completed the cc65 code that recognizes __CDECL__ as a calling convention qualifier.
This commit is contained in:
@@ -6,7 +6,7 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2012, Ullrich von Bassewitz */
|
/* (C) 1998-2015, Ullrich von Bassewitz */
|
||||||
/* Roemerstrasse 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
@@ -290,18 +290,18 @@ void PrintType (FILE* F, const Type* T)
|
|||||||
fprintf (F, "union %s", ((SymEntry*) T->A.P)->Name);
|
fprintf (F, "union %s", ((SymEntry*) T->A.P)->Name);
|
||||||
break;
|
break;
|
||||||
case T_TYPE_ARRAY:
|
case T_TYPE_ARRAY:
|
||||||
|
if (T->A.L == UNSPECIFIED) {
|
||||||
|
fprintf (F, "[] ");
|
||||||
|
} else {
|
||||||
|
fprintf (F, "[%ld] ", T->A.L);
|
||||||
|
}
|
||||||
/* Recursive call */
|
/* Recursive call */
|
||||||
PrintType (F, T + 1);
|
PrintType (F, T + 1);
|
||||||
if (T->A.L == UNSPECIFIED) {
|
|
||||||
fprintf (F, "[]");
|
|
||||||
} else {
|
|
||||||
fprintf (F, "[%ld]", T->A.L);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
case T_TYPE_PTR:
|
case T_TYPE_PTR:
|
||||||
|
fprintf (F, "* ");
|
||||||
/* Recursive call */
|
/* Recursive call */
|
||||||
PrintType (F, T + 1);
|
PrintType (F, T + 1);
|
||||||
fprintf (F, "*");
|
|
||||||
return;
|
return;
|
||||||
case T_TYPE_FUNC:
|
case T_TYPE_FUNC:
|
||||||
fprintf (F, "function returning ");
|
fprintf (F, "function returning ");
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2012, Ullrich von Bassewitz */
|
/* (C) 1998-2015, Ullrich von Bassewitz */
|
||||||
/* Roemerstrasse 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
@@ -603,6 +603,16 @@ INLINE int IsQualCDecl (const Type* T)
|
|||||||
# define IsQualCDecl(T) (((T)->C & T_QUAL_CDECL) != 0)
|
# define IsQualCDecl(T) (((T)->C & T_QUAL_CDECL) != 0)
|
||||||
#endif
|
#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));
|
int IsVariadicFunc (const Type* T) attribute ((const));
|
||||||
/* Return true if this is a function type or pointer to function type with
|
/* Return true if this is a function type or pointer to function type with
|
||||||
** variable parameter list
|
** variable parameter list
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2013, Ullrich von Bassewitz */
|
/* (C) 1998-2015, Ullrich von Bassewitz */
|
||||||
/* Roemerstrasse 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
@@ -85,7 +85,7 @@ struct StructInitData {
|
|||||||
|
|
||||||
|
|
||||||
static void ParseTypeSpec (DeclSpec* D, long Default, TypeCode Qualifiers);
|
static void ParseTypeSpec (DeclSpec* D, long Default, TypeCode Qualifiers);
|
||||||
/* Parse a type specificier */
|
/* Parse a type specifier */
|
||||||
|
|
||||||
static unsigned ParseInitInternal (Type* T, int AllowFlexibleMembers);
|
static unsigned ParseInitInternal (Type* T, int AllowFlexibleMembers);
|
||||||
/* Parse initialization of variables. Return the number of data bytes. */
|
/* Parse initialization of variables. Return the number of data bytes. */
|
||||||
@@ -336,17 +336,28 @@ static void FixQualifiers (Type* DataType)
|
|||||||
while (T->C != T_END) {
|
while (T->C != T_END) {
|
||||||
if (IsTypePtr (T)) {
|
if (IsTypePtr (T)) {
|
||||||
|
|
||||||
/* Fastcall qualifier on the pointer? */
|
/* Calling convention qualifier on the pointer? */
|
||||||
if (IsQualFastcall (T)) {
|
if (IsQualCConv (T)) {
|
||||||
/* Pointer to function which is not fastcall? */
|
/* Pull the convention off of the pointer */
|
||||||
if (IsTypeFunc (T+1) && !IsQualFastcall (T+1)) {
|
Q = T[0].C & T_QUAL_CCONV;
|
||||||
/* Move the fastcall qualifier from the pointer to
|
T[0].C &= ~T_QUAL_CCONV;
|
||||||
** the function.
|
/* Pointer to a function which doesn't have an explicit convention? */
|
||||||
*/
|
if (IsTypeFunc (T + 1)) {
|
||||||
T[0].C &= ~T_QUAL_FASTCALL;
|
if (IsQualCConv (T + 1)) {
|
||||||
T[1].C |= T_QUAL_FASTCALL;
|
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 {
|
} 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) {
|
if (Q == T_QUAL_NONE) {
|
||||||
/* No address size qualifiers specified */
|
/* No address size qualifiers specified */
|
||||||
if (IsTypeFunc (T+1)) {
|
if (IsTypeFunc (T+1)) {
|
||||||
/* Pointer to function. Use the qualifier from the function
|
/* Pointer to function. Use the qualifier from the function,
|
||||||
** or the default if the function don't has one.
|
** or the default if the function doesn't have one.
|
||||||
*/
|
*/
|
||||||
Q = (T[1].C & T_QUAL_ADDRSIZE);
|
Q = (T[1].C & T_QUAL_ADDRSIZE);
|
||||||
if (Q == T_QUAL_NONE) {
|
if (Q == T_QUAL_NONE) {
|
||||||
@@ -368,7 +379,7 @@ static void FixQualifiers (Type* DataType)
|
|||||||
T[0].C |= Q;
|
T[0].C |= Q;
|
||||||
} else {
|
} else {
|
||||||
/* We have address size qualifiers. If followed by a function,
|
/* 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)) {
|
if (IsTypeFunc (T+1)) {
|
||||||
TypeCode FQ = (T[1].C & T_QUAL_ADDRSIZE);
|
TypeCode FQ = (T[1].C & T_QUAL_ADDRSIZE);
|
||||||
@@ -489,7 +500,7 @@ static void ParseEnumDecl (void)
|
|||||||
|
|
||||||
|
|
||||||
static int ParseFieldWidth (Declaration* Decl)
|
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.
|
** 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)
|
static void ParseTypeSpec (DeclSpec* D, long Default, TypeCode Qualifiers)
|
||||||
/* Parse a type specificier */
|
/* Parse a type specifier */
|
||||||
{
|
{
|
||||||
ident Ident;
|
ident Ident;
|
||||||
SymEntry* Entry;
|
SymEntry* Entry;
|
||||||
@@ -1376,13 +1387,13 @@ static FuncDesc* ParseFuncDecl (void)
|
|||||||
static void Declarator (const DeclSpec* Spec, Declaration* D, declmode_t Mode)
|
static void Declarator (const DeclSpec* Spec, Declaration* D, declmode_t Mode)
|
||||||
/* Recursively process declarators. Build a type array in reverse order. */
|
/* Recursively process declarators. Build a type array in reverse order. */
|
||||||
{
|
{
|
||||||
/* Read optional function or pointer qualifiers. These modify the
|
/* Read optional function or pointer qualifiers. They modify the
|
||||||
** identifier or token to the right. For convenience, we allow the fastcall
|
** identifier or token to the right. For convenience, we allow a calling
|
||||||
** qualifier also for pointers here. If it is a pointer-to-function, the
|
** convention also for pointers here. If it's a pointer-to-function, the
|
||||||
** qualifier will later be transfered to the function itself. If it's a
|
** qualifier later will be transfered to the function itself. If it's a
|
||||||
** pointer to something else, it will be flagged as an error.
|
** 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 */
|
/* Pointer to something */
|
||||||
if (CurTok.Tok == TOK_STAR) {
|
if (CurTok.Tok == TOK_STAR) {
|
||||||
@@ -1390,10 +1401,10 @@ static void Declarator (const DeclSpec* Spec, Declaration* D, declmode_t Mode)
|
|||||||
/* Skip the star */
|
/* Skip the star */
|
||||||
NextToken ();
|
NextToken ();
|
||||||
|
|
||||||
/* Allow const, restrict and volatile qualifiers */
|
/* Allow const, restrict, and volatile qualifiers */
|
||||||
Qualifiers |= OptionalQualifiers (T_QUAL_CONST | T_QUAL_VOLATILE | T_QUAL_RESTRICT);
|
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);
|
Declarator (Spec, D, Mode);
|
||||||
|
|
||||||
/* Add the type */
|
/* Add the type */
|
||||||
|
|||||||
Reference in New Issue
Block a user