-/*
- * declare.c
- *
- * Ullrich von Bassewitz, 20.06.1998
- */
+/*****************************************************************************/
+/* */
+/* declare.c */
+/* */
+/* Parse variable and function declarations */
+/* */
+/* */
+/* */
+/* (C) 1998-2001 Ullrich von Bassewitz */
+/* Wacholderweg 14 */
+/* D-70597 Stuttgart */
+/* EMail: uz@musoftware.de */
+/* */
+/* */
+/* This software is provided 'as-is', without any expressed or implied */
+/* warranty. In no event will the authors be held liable for any damages */
+/* arising from the use of this software. */
+/* */
+/* Permission is granted to anyone to use this software for any purpose, */
+/* including commercial applications, and to alter it and redistribute it */
+/* freely, subject to the following restrictions: */
+/* */
+/* 1. The origin of this software must not be misrepresented; you must not */
+/* claim that you wrote the original software. If you use this software */
+/* in a product, an acknowledgment in the product documentation would be */
+/* appreciated but is not required. */
+/* 2. Altered source versions must be plainly marked as such, and must not */
+/* be misrepresented as being the original software. */
+/* 3. This notice may not be removed or altered from any source */
+/* distribution. */
+/* */
+/*****************************************************************************/
static type OptionalQualifiers (type Q)
/* Read type qualifiers if we have any */
{
- while (curtok == TOK_CONST || curtok == TOK_VOLATILE) {
+ while (CurTok.Tok == TOK_CONST || CurTok.Tok == TOK_VOLATILE) {
- switch (curtok) {
+ switch (CurTok.Tok) {
case TOK_CONST:
if (Q & T_QUAL_CONST) {
static void optionalint (void)
/* Eat an optional "int" token */
{
- if (curtok == TOK_INT) {
+ if (CurTok.Tok == TOK_INT) {
/* Skip it */
NextToken ();
}
static void optionalsigned (void)
/* Eat an optional "signed" token */
{
- if (curtok == TOK_SIGNED) {
+ if (CurTok.Tok == TOK_SIGNED) {
/* Skip it */
NextToken ();
}
D->Flags &= ~DS_DEF_STORAGE;
/* Check the storage class given */
- switch (curtok) {
+ switch (CurTok.Tok) {
case TOK_EXTERN:
D->StorageClass = SC_EXTERN | SC_STATIC;
ident Ident;
/* Accept forward definitions */
- if (curtok != TOK_LCURLY) {
+ if (CurTok.Tok != TOK_LCURLY) {
return;
}
/* Read the enum tags */
EnumVal = 0;
- while (curtok != TOK_RCURLY) {
+ while (CurTok.Tok != TOK_RCURLY) {
/* We expect an identifier */
- if (curtok != TOK_IDENT) {
+ if (CurTok.Tok != TOK_IDENT) {
Error ("Identifier expected");
continue;
}
NextToken ();
/* Check for an assigned value */
- if (curtok == TOK_ASSIGN) {
- struct expent lval;
+ if (CurTok.Tok == TOK_ASSIGN) {
+ ExprDesc lval;
NextToken ();
constexpr (&lval);
- EnumVal = lval.e_const;
+ EnumVal = lval.ConstVal;
}
/* Add an entry to the symbol table */
- AddEnumSym (Ident, EnumVal++);
+ AddConstSym (Ident, type_int, SC_ENUM, EnumVal++);
/* Check for end of definition */
- if (curtok != TOK_COMMA)
+ if (CurTok.Tok != TOK_COMMA)
break;
NextToken ();
}
SymEntry* Entry;
- if (curtok != TOK_LCURLY) {
+ if (CurTok.Tok != TOK_LCURLY) {
/* Just a forward declaration. Try to find a struct with the given
* name. If there is none, insert a forward declaration into the
* current lexical level.
/* Parse struct fields */
Size = 0;
- while (curtok != TOK_RCURLY) {
+ while (CurTok.Tok != TOK_RCURLY) {
/* Get the type of the entry */
DeclSpec Spec;
}
}
- if (curtok != TOK_COMMA)
+ if (CurTok.Tok != TOK_COMMA)
break;
NextToken ();
}
Qualifiers = OptionalQualifiers (T_QUAL_NONE);
/* Look at the data type */
- switch (curtok) {
+ switch (CurTok.Tok) {
case TOK_VOID:
NextToken ();
case TOK_LONG:
NextToken ();
- if (curtok == TOK_UNSIGNED) {
+ if (CurTok.Tok == TOK_UNSIGNED) {
NextToken ();
optionalint ();
D->Type[0] = T_ULONG;
case TOK_SHORT:
NextToken ();
- if (curtok == TOK_UNSIGNED) {
+ if (CurTok.Tok == TOK_UNSIGNED) {
NextToken ();
optionalint ();
D->Type[0] = T_USHORT;
case TOK_SIGNED:
NextToken ();
- switch (curtok) {
+ switch (CurTok.Tok) {
case TOK_CHAR:
NextToken ();
case TOK_UNSIGNED:
NextToken ();
- switch (curtok) {
+ switch (CurTok.Tok) {
case TOK_CHAR:
NextToken ();
case TOK_STRUCT:
case TOK_UNION:
- StructType = (curtok == TOK_STRUCT)? T_STRUCT : T_UNION;
+ StructType = (CurTok.Tok == TOK_STRUCT)? T_STRUCT : T_UNION;
NextToken ();
/* */
- if (curtok == TOK_IDENT) {
+ if (CurTok.Tok == TOK_IDENT) {
strcpy (Ident, CurTok.Ident);
NextToken ();
} else {
case TOK_ENUM:
NextToken ();
- if (curtok != TOK_LCURLY) {
+ if (CurTok.Tok != TOK_LCURLY) {
/* Named enum */
- if (curtok == TOK_IDENT) {
+ if (CurTok.Tok == TOK_IDENT) {
/* Find an entry with this name */
Entry = FindTagSym (CurTok.Ident);
if (Entry) {
/* Parse an old style (K&R) parameter list */
{
/* Parse params */
- while (curtok != TOK_RPAREN) {
+ while (CurTok.Tok != TOK_RPAREN) {
/* List of identifiers expected */
- if (curtok != TOK_IDENT) {
+ if (CurTok.Tok != TOK_IDENT) {
Error ("Identifier expected");
}
NextToken ();
/* Check for more parameters */
- if (curtok == TOK_COMMA) {
+ if (CurTok.Tok == TOK_COMMA) {
NextToken ();
} else {
break;
ConsumeRParen ();
/* An optional list of type specifications follows */
- while (curtok != TOK_LCURLY) {
+ while (CurTok.Tok != TOK_LCURLY) {
DeclSpec Spec;
}
}
- if (curtok == TOK_COMMA) {
+ if (CurTok.Tok == TOK_COMMA) {
NextToken ();
} else {
break;
/* Parse a new style (ANSI) parameter list */
{
/* Parse params */
- while (curtok != TOK_RPAREN) {
+ while (CurTok.Tok != TOK_RPAREN) {
DeclSpec Spec;
Declaration Decl;
DeclAttr Attr;
/* Allow an ellipsis as last parameter */
- if (curtok == TOK_ELLIPSIS) {
+ if (CurTok.Tok == TOK_ELLIPSIS) {
NextToken ();
- F->Flags |= FD_ELLIPSIS;
+ F->Flags |= FD_VARIADIC;
break;
}
++F->ParamCount;
/* Check for more parameters */
- if (curtok == TOK_COMMA) {
+ if (CurTok.Tok == TOK_COMMA) {
NextToken ();
} else {
break;
ConsumeRParen ();
/* Check if this is a function definition */
- if (curtok == TOK_LCURLY) {
+ if (CurTok.Tok == TOK_LCURLY) {
/* Print an error if in strict ANSI mode and we have unnamed
* parameters.
*/
EnterFunctionLevel ();
/* Check for several special parameter lists */
- if (curtok == TOK_RPAREN) {
+ if (CurTok.Tok == TOK_RPAREN) {
/* Parameter list is empty */
- F->Flags |= (FD_EMPTY | FD_ELLIPSIS);
- } else if (curtok == TOK_VOID && nxttok == TOK_RPAREN) {
+ F->Flags |= (FD_EMPTY | FD_VARIADIC);
+ } else if (CurTok.Tok == TOK_VOID && NextTok.Tok == TOK_RPAREN) {
/* Parameter list declared as void */
NextToken ();
F->Flags |= FD_VOID_PARAM;
- } else if (curtok == TOK_IDENT && (nxttok == TOK_COMMA || nxttok == TOK_RPAREN)) {
- /* Old style (K&R) function. Assume variable param list. */
- F->Flags |= (FD_OLDSTYLE | FD_ELLIPSIS);
+ } else if (CurTok.Tok == TOK_IDENT &&
+ (NextTok.Tok == TOK_COMMA || NextTok.Tok == TOK_RPAREN)) {
+ /* If the identifier is a typedef, we have a new style parameter list,
+ * if it's some other identifier, it's an old style parameter list.
+ */
+ Sym = FindSym (CurTok.Ident);
+ if (Sym == 0 || !IsTypeDef (Sym)) {
+ /* Old style (K&R) function. Assume variable param list. */
+ F->Flags |= (FD_OLDSTYLE | FD_VARIADIC);
+ }
}
/* Parse params */
/* Assign offsets. If the function has a variable parameter list,
* there's one additional byte (the arg size).
*/
- Offs = (F->Flags & FD_ELLIPSIS)? 1 : 0;
+ Offs = (F->Flags & FD_VARIADIC)? 1 : 0;
Sym = GetSymTab()->SymTail;
while (Sym) {
unsigned Size = SizeOf (Sym->Type);
/* Recursively process declarators. Build a type array in reverse order. */
{
- if (curtok == TOK_STAR) {
+ if (CurTok.Tok == TOK_STAR) {
type T = T_PTR;
NextToken ();
/* Allow optional const or volatile qualifiers */
Decl (D, Mode);
*D->T++ = T;
return;
- } else if (curtok == TOK_LPAREN) {
+ } else if (CurTok.Tok == TOK_LPAREN) {
NextToken ();
Decl (D, Mode);
ConsumeRParen ();
- } else if (curtok == TOK_FASTCALL) {
+ } else if (CurTok.Tok == TOK_FASTCALL) {
/* Remember the current type pointer */
type* T = D->T;
/* Skip the fastcall token */
/* Set the fastcall flag */
if (!IsTypeFunc (T)) {
Error ("__fastcall__ modifier applied to non function");
- } else if (IsEllipsisFunc (T)) {
+ } else if (IsVariadicFunc (T)) {
Error ("Cannot apply __fastcall__ to functions with variable parameter list");
- } else {
- FuncDesc* F = DecodePtr (T+1);
+ } else {
+ FuncDesc* F = (FuncDesc*) DecodePtr (T+1);
F->Flags |= FD_FASTCALL;
}
return;
*/
if (Mode == DM_NO_IDENT) {
D->Ident[0] = '\0';
- } else if (curtok == TOK_IDENT) {
+ } else if (CurTok.Tok == TOK_IDENT) {
strcpy (D->Ident, CurTok.Ident);
NextToken ();
} else {
}
}
- while (curtok == TOK_LBRACK || curtok == TOK_LPAREN) {
- if (curtok == TOK_LPAREN) {
+ while (CurTok.Tok == TOK_LBRACK || CurTok.Tok == TOK_LPAREN) {
+ if (CurTok.Tok == TOK_LPAREN) {
/* Function declaration */
FuncDesc* F;
NextToken ();
unsigned long Size = 0;
NextToken ();
/* Read the size if it is given */
- if (curtok != TOK_RBRACK) {
- struct expent lval;
+ if (CurTok.Tok != TOK_RBRACK) {
+ ExprDesc lval;
constexpr (&lval);
- Size = lval.e_const;
+ Size = lval.ConstVal;
}
ConsumeRBrack ();
*D->T++ = T_ARRAY;
static void ParseVoidInit (void)
/* Parse an initialization of a void variable (special cc65 extension) */
{
- struct expent lval;
+ ExprDesc lval;
/* Allow an arbitrary list of values */
ConsumeLCurly ();
do {
constexpr (&lval);
- switch (lval.e_tptr[0]) {
+ switch (lval.Type[0]) {
case T_SCHAR:
case T_UCHAR:
- if ((lval.e_flags & E_MCTYPE) == E_TCONST) {
+ if ((lval.Flags & E_MCTYPE) == E_TCONST) {
/* Make it byte sized */
- lval.e_const &= 0xFF;
+ lval.ConstVal &= 0xFF;
}
DefineData (&lval);
break;
case T_UINT:
case T_PTR:
case T_ARRAY:
- if ((lval.e_flags & E_MCTYPE) == E_TCONST) {
+ if ((lval.Flags & E_MCTYPE) == E_TCONST) {
/* Make it word sized */
- lval.e_const &= 0xFFFF;
+ lval.ConstVal &= 0xFFFF;
}
DefineData (&lval);
break;
}
- if (curtok != TOK_COMMA) {
+ if (CurTok.Tok != TOK_COMMA) {
break;
}
NextToken ();
- } while (curtok != TOK_RCURLY);
+ } while (CurTok.Tok != TOK_RCURLY);
ConsumeRCurly ();
}
/* Get a pointer to the list of symbols */
Entry = Tab->SymHead;
- while (curtok != TOK_RCURLY) {
+ while (CurTok.Tok != TOK_RCURLY) {
if (Entry == 0) {
Error ("Too many initializers");
return;
}
ParseInit (Entry->Type);
Entry = Entry->NextSym;
- if (curtok != TOK_COMMA)
+ if (CurTok.Tok != TOK_COMMA)
break;
NextToken ();
}
void ParseInit (type* T)
/* Parse initialization of variables. */
{
- int count;
- struct expent lval;
+ ExprDesc lval;
type* t;
const char* str;
- int sz;
+ int Count;
+ int Size;
switch (UnqualifiedType (*T)) {
case T_SCHAR:
case T_UCHAR:
constexpr (&lval);
- if ((lval.e_flags & E_MCTYPE) == E_TCONST) {
+ if ((lval.Flags & E_MCTYPE) == E_TCONST) {
/* Make it byte sized */
- lval.e_const &= 0xFF;
+ lval.ConstVal &= 0xFF;
}
assignadjust (T, &lval);
DefineData (&lval);
case T_UINT:
case T_PTR:
constexpr (&lval);
- if ((lval.e_flags & E_MCTYPE) == E_TCONST) {
+ if ((lval.Flags & E_MCTYPE) == E_TCONST) {
/* Make it word sized */
- lval.e_const &= 0xFFFF;
+ lval.ConstVal &= 0xFFFF;
}
assignadjust (T, &lval);
DefineData (&lval);
case T_LONG:
case T_ULONG:
constexpr (&lval);
- if ((lval.e_flags & E_MCTYPE) == E_TCONST) {
+ if ((lval.Flags & E_MCTYPE) == E_TCONST) {
/* Make it long sized */
- lval.e_const &= 0xFFFFFFFF;
+ lval.ConstVal &= 0xFFFFFFFF;
}
assignadjust (T, &lval);
DefineData (&lval);
break;
case T_ARRAY:
- sz = Decode (T + 1);
+ Size = Decode (T + 1);
t = T + DECODE_SIZE + 1;
- if (IsTypeChar(t) && curtok == TOK_SCONST) {
- str = GetLiteral (curval);
- count = strlen (str) + 1;
- TranslateLiteralPool (curval); /* Translate into target charset */
- g_defbytes (str, count);
- ResetLiteralOffs (curval); /* Remove string from pool */
+ if (IsTypeChar(t) && CurTok.Tok == TOK_SCONST) {
+ str = GetLiteral (CurTok.IVal);
+ Count = strlen (str) + 1;
+ TranslateLiteralPool (CurTok.IVal); /* Translate into target charset */
+ g_defbytes (str, Count);
+ ResetLiteralPoolOffs (CurTok.IVal); /* Remove string from pool */
NextToken ();
} else {
ConsumeLCurly ();
- count = 0;
- while (curtok != TOK_RCURLY) {
+ Count = 0;
+ while (CurTok.Tok != TOK_RCURLY) {
ParseInit (T + DECODE_SIZE + 1);
- ++count;
- if (curtok != TOK_COMMA)
+ ++Count;
+ if (CurTok.Tok != TOK_COMMA)
break;
NextToken ();
}
ConsumeRCurly ();
}
- if (sz == 0) {
- Encode (T + 1, count);
- } else if (count < sz) {
- g_zerobytes ((sz - count) * SizeOf (T + DECODE_SIZE + 1));
- } else if (count > sz) {
+ if (Size == 0) {
+ Encode (T + 1, Count);
+ } else if (Count < Size) {
+ g_zerobytes ((Size - Count) * SizeOf (T + DECODE_SIZE + 1));
+ } else if (Count > Size) {
Error ("Too many initializers");
}
break;