X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Fcc65%2Fdeclare.c;h=9f0a94a27d9f267b4fadc266d0fdd5222e44a5b8;hb=3f4096d3030095605f28b4cfa73563c53a563df6;hp=8bd0b0b87cf81735a6fccfd1eeaff277e4ed3d2a;hpb=f1b0fb97638c83c7f060dc698a6f118d3060ab0b;p=cc65 diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 8bd0b0b87..9f0a94a27 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -6,8 +6,8 @@ /* */ /* */ /* */ -/* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* (C) 1998-2004 Ullrich von Bassewitz */ +/* Römerstraße 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ @@ -38,6 +38,8 @@ #include /* common */ +#include "addrsize.h" +#include "mmodel.h" #include "xmalloc.h" /* cc65 */ @@ -843,6 +845,13 @@ static FuncDesc* ParseFuncDecl (const DeclSpec* Spec) Sym = Sym->PrevSym; } + /* Add the default address size for the function */ + if (CodeAddrSize == ADDR_SIZE_FAR) { + F->Flags |= FD_FAR; + } else { + F->Flags |= FD_NEAR; + } + /* Leave the lexical level remembering the symbol tables */ RememberFunctionLevel (F); @@ -852,39 +861,114 @@ static FuncDesc* ParseFuncDecl (const DeclSpec* Spec) +static unsigned FunctionModifierFlags (void) +/* Parse __fastcall__, __near__ and __far__ and return the matching FD_ flags */ +{ + /* Read the flags */ + unsigned Flags = FD_NONE; + while (CurTok.Tok == TOK_FASTCALL || CurTok.Tok == TOK_NEAR || CurTok.Tok == TOK_FAR) { + + /* Get the flag bit for the next token */ + unsigned F = FD_NONE; + switch (CurTok.Tok) { + case TOK_FASTCALL: F = FD_FASTCALL; break; + case TOK_NEAR: F = FD_NEAR; break; + case TOK_FAR: F = FD_FAR; break; + default: Internal ("Unexpected token: %d", CurTok.Tok); + } + + /* Remember the flag for this modifier */ + if (Flags & F) { + Error ("Duplicate modifier"); + } + Flags |= F; + + /* Skip the token */ + NextToken (); + } + + /* Sanity check */ + if ((Flags & (FD_NEAR | FD_FAR)) == (FD_NEAR | FD_FAR)) { + Error ("Cannot specify both, `__near__' and `__far__' modifiers"); + Flags &= ~(FD_NEAR | FD_FAR); + } + + /* Return the flags read */ + return Flags; +} + + + +static void ApplyFunctionModifiers (type* T, unsigned Flags) +/* Apply a set of function modifier flags to a function */ +{ + /* Get the function descriptor */ + FuncDesc* F = GetFuncDesc (T); + + /* Special check for __fastcall__ */ + if ((Flags & FD_FASTCALL) != 0 && IsVariadicFunc (T)) { + Error ("Cannot apply `__fastcall__' to functions with " + "variable parameter list"); + Flags &= ~FD_FASTCALL; + } + + /* Remove the default function address size modifiers */ + F->Flags &= ~(FD_NEAR | FD_FAR); + + /* Add the new modifers */ + F->Flags |= Flags; +} + + + static void Decl (const DeclSpec* Spec, Declaration* D, unsigned Mode) /* Recursively process declarators. Build a type array in reverse order. */ { - + /* Pointer to something */ if (CurTok.Tok == TOK_STAR) { - type T = T_PTR; + + type T; + + /* Skip the star */ NextToken (); + /* Allow optional const or volatile qualifiers */ - T |= OptionalQualifiers (T_QUAL_NONE); + T = T_PTR | OptionalQualifiers (T_QUAL_NONE); + + /* Parse the type, the pointer points to */ Decl (Spec, D, Mode); + *D->T++ = T; return; - } else if (CurTok.Tok == TOK_LPAREN) { - NextToken (); - Decl (Spec, D, Mode); - ConsumeRParen (); - } else if (CurTok.Tok == TOK_FASTCALL) { + } + + /* Function modifiers */ + if (CurTok.Tok == TOK_FASTCALL || CurTok.Tok == TOK_NEAR || CurTok.Tok == TOK_FAR) { + /* Remember the current type pointer */ type* T = D->T; - /* Skip the fastcall token */ - NextToken (); + + /* Read the flags */ + unsigned Flags = FunctionModifierFlags (); + /* Parse the function */ Decl (Spec, D, Mode); - /* Set the fastcall flag */ + + /* Check that we have a function */ if (!IsTypeFunc (T) && !IsTypeFuncPtr (T)) { - Error ("__fastcall__ modifier applied to non function"); - } else if (IsVariadicFunc (T)) { - Error ("Cannot apply __fastcall__ to functions with variable parameter list"); + Error ("Function modifier applied to non function"); } else { - FuncDesc* F = GetFuncDesc (T); - F->Flags |= FD_FASTCALL; - } + ApplyFunctionModifiers (T, Flags); + } + + /* Done */ return; + } + + if (CurTok.Tok == TOK_LPAREN) { + NextToken (); + Decl (Spec, D, Mode); + ConsumeRParen (); } else { /* Things depend on Mode now: * - Mode == DM_NEED_IDENT means: @@ -964,7 +1048,6 @@ type* ParseType (type* Type) ParseTypeSpec (&Spec, -1); /* Parse additional declarators */ - InitDeclaration (&Decl); ParseDecl (&Spec, &Decl, DM_NO_IDENT); /* Copy the type to the target buffer */