}
/* Check for legal symbol types */
- if ((Sym->Flags & SC_ENUM) == SC_ENUM) {
+ if ((Sym->Flags & SC_CONST) == SC_CONST) {
+ /* Enum or some other numeric constant */
lval->e_flags = E_MCONST;
lval->e_const = Sym->V.EnumVal;
return 0;
/* Reenter the lexical level */
ReenterFunctionLevel (D);
+ /* Declare two special functions symbols: __fixargs__ and __argsize__.
+ * The latter is different depending on the type of the function (variadic
+ * or not).
+ */
+ AddLocalSym ("__fixargs__", type_uint, SC_DEF | SC_CONST, D->ParamSize);
+ if (D->Flags & FD_ELLIPSIS) {
+ /* Variadic function. The variable must be const. */
+ static const type T [] = { T_UCHAR | T_QUAL_CONST, T_END };
+ AddLocalSym ("__argsize__", T, SC_DEF | SC_REF | SC_AUTO, 0);
+ } else {
+ /* Non variadic */
+ AddLocalSym ("__argsize__", type_uchar, SC_DEF | SC_CONST, D->ParamSize);
+ }
+
/* Function body now defined */
Func->Flags |= SC_DEF;
g_defgloblabel (Func->Name);
/* If this is a fastcall function, push the last parameter onto the stack */
- if (IsFastCallFunc (Func->Type) && D->ParamCount > 0 && (D->Flags & FD_ELLIPSIS) == 0) {
+ if (IsFastCallFunc (Func->Type) && D->ParamCount > 0) {
+ SymEntry* LastParam;
unsigned Flags;
+ /* Fastcall functions may never have an ellipsis or the compiler is buggy */
+ CHECK ((D->Flags & FD_ELLIPSIS) == 0);
+
/* Get a pointer to the last parameter entry */
- SymEntry* LastParam = D->SymTab->SymTail;
+ LastParam = D->SymTab->SymTail;
/* Generate the push */
if (IsTypeFunc (LastParam->Type)) {
nxtval = GetCurrentLine();
nxttype = type_int;
return;
- } else if (strcmp (token, "__fixargs__") == 0) {
- nxttok = TOK_ICONST;
- nxtval = GetParamSize (CurrentFunc);
- nxttype = type_uint;
- return;
} else if (strcmp (token, "__func__") == 0) {
/* __func__ is only defined in functions */
if (CurrentFunc) {
#include <string.h>
-
+
/* common */
#include "xmalloc.h"
-
+
/* cc65 */
#include "symentry.h"
/* Code */
/*****************************************************************************/
-
+
SymEntry* NewSymEntry (const char* Name, unsigned Flags)
/* Create a new symbol table with the given name */
{ "SC_STATIC", SC_STATIC },
{ "SC_EXTERN", SC_EXTERN },
{ "SC_ENUM", SC_ENUM },
+ { "SC_CONST", SC_CONST },
{ "SC_LABEL", SC_LABEL },
{ "SC_PARAM", SC_PARAM },
{ "SC_FUNC", SC_FUNC },
#define SC_STATIC 0x0004U
#define SC_EXTERN 0x0008U
-#define SC_ENUM 0x0010U /* An enum (numeric constant) */
-#define SC_LABEL 0x0020U /* A goto label */
-#define SC_PARAM 0x0040U /* This is a function parameter */
-#define SC_FUNC 0x0080U /* Function entry */
-
-#define SC_STORAGE 0x0100U /* Symbol with associated storage */
-#define SC_DEFAULT 0x0200U /* Flag: default storage class was used */
-
-#define SC_DEF 0x0400U /* Symbol is defined */
-#define SC_REF 0x0800U /* Symbol is referenced */
-
-#define SC_TYPE 0x1000U /* This is a type, struct, typedef, etc. */
-#define SC_STRUCT 0x1001U /* Struct or union */
-#define SC_SFLD 0x1002U /* Struct or union field */
-#define SC_TYPEDEF 0x1003U /* A typedef */
+#define SC_ENUM 0x0030U /* An enum (numeric constant) */
+#define SC_CONST 0x0020U /* A numeric constant with a type */
+#define SC_LABEL 0x0040U /* A goto label */
+#define SC_PARAM 0x0080U /* This is a function parameter */
+#define SC_FUNC 0x0100U /* Function entry */
+
+#define SC_STORAGE 0x0400U /* Symbol with associated storage */
+#define SC_DEFAULT 0x0800U /* Flag: default storage class was used */
+
+#define SC_DEF 0x1000U /* Symbol is defined */
+#define SC_REF 0x2000U /* Symbol is referenced */
+
+#define SC_TYPE 0x4000U /* This is a type, struct, typedef, etc. */
+#define SC_STRUCT 0x4001U /* Struct or union */
+#define SC_SFLD 0x4002U /* Struct or union field */
+#define SC_TYPEDEF 0x4003U /* A typedef */
#define SC_ZEROPAGE 0x8000U /* Symbol marked as zeropage */
-SymEntry* AddLocalSym (const char* Name, type* Type, unsigned Flags, int Offs)
+SymEntry* AddLocalSym (const char* Name, const type* Type, unsigned Flags, int Offs)
/* Add a local symbol and return the symbol entry */
{
/* Do we have an entry with this name already? */
-SymEntry* AddGlobalSym (const char* Name, type* Type, unsigned Flags)
+SymEntry* AddGlobalSym (const char* Name, const type* Type, unsigned Flags)
/* Add an external or global symbol to the symbol table and return the entry */
{
/* Functions must be inserted in the global symbol table */
/* Create a new entry */
Entry = NewSymEntry (Name, Flags);
- /* Set the symbol attributes */
+ /* Set the symbol attributes */
Entry->Type = TypeDup (Type);
/* Add the entry to the symbol table */
SymEntry* AddLabelSym (const char* Name, unsigned Flags);
/* Add a goto label to the symbol table */
-SymEntry* AddLocalSym (const char* Name, type* Type, unsigned Flags, int Offs);
+SymEntry* AddLocalSym (const char* Name, const type* Type, unsigned Flags, int Offs);
/* Add a local symbol and return the symbol entry */
-SymEntry* AddGlobalSym (const char* Name, type* Type, unsigned Flags);
+SymEntry* AddGlobalSym (const char* Name, const type* Type, unsigned Flags);
/* Add an external or global symbol to the symbol table and return the entry */