X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Fcc65%2Fdeclare.c;h=587d7ce74b34a2ab84cf0fb83ae0e1d4b2069dbe;hb=05f72963695f843cca3fd3dac1be0175b470b179;hp=29103dbb12f6519f5538581a972a6defc1106228;hpb=9f7ca16001e4bdee942191479aa295d10d1d615d;p=cc65 diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 29103dbb1..587d7ce74 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (C) 1998-2008 Ullrich von Bassewitz */ -/* Roemerstrasse 52 */ -/* D-70794 Filderstadt */ -/* EMail: uz@cc65.org */ +/* (C) 1998-2010, Ullrich von Bassewitz */ +/* Roemerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -185,6 +185,17 @@ static TypeCode OptionalQualifiers (TypeCode Allowed) } break; + case TOK_CDECL: + if (Allowed & T_QUAL_CDECL) { + if (Q & T_QUAL_CDECL) { + DuplicateQualifier ("cdecl"); + } + Q |= T_QUAL_CDECL; + } else { + goto Done; + } + break; + default: goto Done; @@ -208,6 +219,19 @@ Done: Q &= ~T_QUAL_ADDRSIZE; } + /* We cannot have more than one calling convention specifier */ + switch (Q & T_QUAL_CCONV) { + + case T_QUAL_NONE: + case T_QUAL_FASTCALL: + case T_QUAL_CDECL: + break; + + default: + Error ("Cannot specify more than one calling convention qualifier"); + Q &= ~T_QUAL_CCONV; + } + /* Return the qualifiers read */ return Q; } @@ -249,9 +273,10 @@ static void InitDeclSpec (DeclSpec* D) static void InitDeclaration (Declaration* D) /* Initialize the Declaration struct for use */ { - D->Ident[0] = '\0'; - D->Type[0].C = T_END; - D->Index = 0; + D->Ident[0] = '\0'; + D->Type[0].C = T_END; + D->Index = 0; + D->Attributes = 0; } @@ -294,7 +319,7 @@ static void FixQualifiers (Type* DataType) while (T->C != T_END) { if (IsTypeArray (T)) { /* Extract any type qualifiers */ - Q |= T->C & T_MASK_QUAL; + Q |= GetQualifier (T); T->C = UnqualifiedType (T->C); } else { /* Add extracted type qualifiers here */ @@ -723,8 +748,8 @@ static SymEntry* ParseStructDecl (const char* Name) } /* Add a field entry to the table */ - if (FieldWidth > 0) { - /* Add full byte from the bit offset to the variable offset. + if (FieldWidth > 0) { + /* Add full byte from the bit offset to the variable offset. * This simplifies handling he bit-field as a char type * in expressions. */ @@ -738,7 +763,9 @@ static SymEntry* ParseStructDecl (const char* Name) } } else { AddLocalSym (Decl.Ident, Decl.Type, SC_STRUCTFIELD, StructSize); - StructSize += CheckedSizeOf (Decl.Type); + if (!FlexibleMember) { + StructSize += CheckedSizeOf (Decl.Type); + } } NextMember: if (CurTok.Tok != TOK_COMMA) { @@ -1121,7 +1148,7 @@ static void ParseAnsiParamList (FuncDesc* F) DeclSpec Spec; Declaration Decl; - DeclAttr Attr; + SymEntry* Sym; /* Allow an ellipsis as last parameter */ if (CurTok.Tok == TOK_ELLIPSIS) { @@ -1159,11 +1186,21 @@ static void ParseAnsiParamList (FuncDesc* F) Decl.StorageClass &= ~SC_DEF; } - /* Parse an attribute ### */ - ParseAttribute (&Decl, &Attr); + /* Parse attributes for this parameter */ + ParseAttribute (&Decl); /* Create a symbol table entry */ - AddLocalSym (Decl.Ident, ParamTypeCvt (Decl.Type), Decl.StorageClass, 0); + Sym = AddLocalSym (Decl.Ident, ParamTypeCvt (Decl.Type), Decl.StorageClass, 0); + + /* Add attributes if we have any */ + SymUseAttr (Sym, &Decl); + + /* If the parameter is a struct or union, emit a warning */ + if (IsClassStruct (Decl.Type)) { + if (IS_Get (&WarnStructParam)) { + Warning ("Passing struct by value for parameter `%s'", Decl.Ident); + } + } /* Count arguments */ ++F->ParamCount; @@ -1180,17 +1217,6 @@ static void ParseAnsiParamList (FuncDesc* F) * the breaks above bail out without checking. */ ConsumeRParen (); - - /* Check if this is a function definition */ - if (CurTok.Tok == TOK_LCURLY) { - /* Print an error if we have unnamed parameters and cc65 extensions - * are disabled. - */ - if (IS_Get (&Standard) != STD_CC65 && - (F->Flags & FD_UNNAMED_PARAMS) != 0) { - Error ("Parameter name omitted"); - } - } } @@ -1229,8 +1255,10 @@ static FuncDesc* ParseFuncDecl (void) /* Parse params */ if ((F->Flags & FD_OLDSTYLE) == 0) { + /* New style function */ ParseAnsiParamList (F); + } else { /* Old style function */ ParseOldStyleParamList (F); @@ -1401,6 +1429,9 @@ static void Declarator (const DeclSpec* Spec, Declaration* D, declmode_t Mode) if (Qualifiers & T_QUAL_FASTCALL) { Error ("Invalid `__fastcall__' qualifier"); } + if (Qualifiers & T_QUAL_CDECL) { + Error ("Invalid `__cdecl__' qualifier"); + } } @@ -1457,6 +1488,9 @@ void ParseDecl (const DeclSpec* Spec, Declaration* D, declmode_t Mode) D->StorageClass |= SC_FUNC; } + /* Parse attributes for this declaration */ + ParseAttribute (D); + /* Check several things for function or function pointer types */ if (IsTypeFunc (D->Type) || IsTypeFuncPtr (D->Type)) { @@ -1756,12 +1790,12 @@ static unsigned ParseArrayInit (Type* T, int AllowFlexibleMembers) /* Special handling for a character array initialized by a literal */ if (IsTypeChar (ElementType) && - (CurTok.Tok == TOK_SCONST || - (CurTok.Tok == TOK_LCURLY && NextTok.Tok == TOK_SCONST))) { + (CurTok.Tok == TOK_SCONST || CurTok.Tok == TOK_WCSCONST || + (CurTok.Tok == TOK_LCURLY && + (NextTok.Tok == TOK_SCONST || NextTok.Tok == TOK_WCSCONST)))) { /* Char array initialized by string constant */ int NeedParen; - const char* Str; /* If we initializer is enclosed in brackets, remember this fact and * skip the opening bracket. @@ -1771,16 +1805,13 @@ static unsigned ParseArrayInit (Type* T, int AllowFlexibleMembers) NextToken (); } - /* Get the initializer string and its size */ - Str = GetLiteral (CurTok.IVal); - Count = GetLiteralPoolOffs () - CurTok.IVal; - /* Translate into target charset */ - TranslateLiteralPool (CurTok.IVal); + TranslateLiteral (CurTok.SVal); /* If the array is one too small for the string literal, omit the * trailing zero. */ + Count = GetLiteralSize (CurTok.SVal); if (ElementCount != UNSPECIFIED && ElementCount != FLEXIBLE && Count == ElementCount + 1) { @@ -1789,10 +1820,9 @@ static unsigned ParseArrayInit (Type* T, int AllowFlexibleMembers) } /* Output the data */ - g_defbytes (Str, Count); + g_defbytes (GetLiteralStr (CurTok.SVal), Count); - /* Remove string from pool */ - ResetLiteralPoolOffs (CurTok.IVal); + /* Skip the string */ NextToken (); /* If the initializer was enclosed in curly braces, we need a closing