/* */
/* */
/* */
-/* (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 */
}
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;
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;
}
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;
}
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 */
static void ParseOldStyleParamList (FuncDesc* F)
/* Parse an old style (K&R) parameter list */
{
+ /* Some fix point tokens that are used for error recovery */
+ static const token_t TokenList[] = { TOK_COMMA, TOK_RPAREN, TOK_SEMI };
+
/* Parse params */
while (CurTok.Tok != TOK_RPAREN) {
/* List of identifiers expected */
- if (CurTok.Tok != TOK_IDENT) {
- Error ("Identifier expected");
- }
+ if (CurTok.Tok == TOK_IDENT) {
- /* Create a symbol table entry with type int */
- AddLocalSym (CurTok.Ident, type_int, SC_AUTO | SC_PARAM | SC_DEF | SC_DEFTYPE, 0);
+ /* Create a symbol table entry with type int */
+ AddLocalSym (CurTok.Ident, type_int, SC_AUTO | SC_PARAM | SC_DEF | SC_DEFTYPE, 0);
- /* Count arguments */
- ++F->ParamCount;
+ /* Count arguments */
+ ++F->ParamCount;
- /* Skip the identifier */
- NextToken ();
+ /* Skip the identifier */
+ NextToken ();
+
+ } else {
+ /* Not a parameter name */
+ Error ("Identifier expected");
+
+ /* Try some smart error recovery */
+ SkipTokens (TokenList, sizeof(TokenList) / sizeof(TokenList[0]));
+ }
/* Check for more parameters */
if (CurTok.Tok == TOK_COMMA) {
DeclSpec Spec;
Declaration Decl;
- DeclAttr Attr;
+ SymEntry* Sym;
/* Allow an ellipsis as last parameter */
if (CurTok.Tok == TOK_ELLIPSIS) {
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;
* 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");
- }
- }
}
/* Parse params */
if ((F->Flags & FD_OLDSTYLE) == 0) {
+
/* New style function */
ParseAnsiParamList (F);
+
} else {
/* Old style function */
ParseOldStyleParamList (F);
/* We cannot specify fastcall for variadic functions */
if ((F->Flags & FD_VARIADIC) && (Qualifiers & T_QUAL_FASTCALL)) {
- Error ("Variadic functions cannot be `__fastcall'");
+ Error ("Variadic functions cannot be `__fastcall__'");
Qualifiers &= ~T_QUAL_FASTCALL;
}
if (Qualifiers & T_QUAL_FASTCALL) {
Error ("Invalid `__fastcall__' qualifier");
}
+ if (Qualifiers & T_QUAL_CDECL) {
+ Error ("Invalid `__cdecl__' qualifier");
+ }
}
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)) {
/* 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.
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) {
}
/* 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