/* */
/* */
/* */
-/* (C) 1998-2006 Ullrich von Bassewitz */
-/* Römerstraße 52 */
+/* (C) 1998-2008 Ullrich von Bassewitz */
+/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
#include <string.h>
/* common */
+#include "addrsize.h"
#include "check.h"
+#include "mmodel.h"
#include "xmalloc.h"
/* cc65 */
#include "codegen.h"
#include "datatype.h"
#include "error.h"
+#include "fp.h"
#include "funcdesc.h"
#include "global.h"
#include "symtab.h"
-Type* TypeCpy (Type* Dest, const Type* Src)
+Type* TypeCopy (Type* Dest, const Type* Src)
/* Copy a type string */
{
Type* Orig = Dest;
F->TagTab = &EmptySymTab;
/* Fill the type string */
- T[0].C = T_FUNC;
+ T[0].C = T_FUNC | CodeAddrSizeQualifier ();
T[0].A.P = F;
T[1].C = T_INT;
T[2].C = T_END;
Type* P = TypeAlloc (Size + 1);
/* Create the return type... */
- P[0].C = T_PTR;
+ P[0].C = T_PTR | (T[0].C & T_QUAL_ADDRSIZE);
memcpy (P+1, T, Size * sizeof (Type));
/* ...and return it */
/* Get the type code */
TypeCode C = T->C;
- /* Print any qualifiers */
+ /* Print any qualifiers */
C = PrintTypeComp (F, C, T_QUAL_CONST, "const");
- C = PrintTypeComp (F, C, T_QUAL_VOLATILE, "volatile");
+ C = PrintTypeComp (F, C, T_QUAL_VOLATILE, "volatile");
C = PrintTypeComp (F, C, T_QUAL_RESTRICT, "restrict");
+ C = PrintTypeComp (F, C, T_QUAL_NEAR, "__near__");
+ C = PrintTypeComp (F, C, T_QUAL_FAR, "__far__");
+ C = PrintTypeComp (F, C, T_QUAL_FASTCALL, "__fastcall__");
+ C = PrintTypeComp (F, C, T_QUAL_CDECL, "__cdecl__");
- /* Signedness. Omit the signedness specifier for long and int */
+ /* Signedness. Omit the signedness specifier for long and int */
if ((C & T_MASK_TYPE) != T_TYPE_INT && (C & T_MASK_TYPE) != T_TYPE_LONG) {
- C = PrintTypeComp (F, C, T_SIGN_SIGNED, "signed");
- }
- C = PrintTypeComp (F, C, T_SIGN_UNSIGNED, "unsigned");
+ C = PrintTypeComp (F, C, T_SIGN_SIGNED, "signed");
+ }
+ C = PrintTypeComp (F, C, T_SIGN_UNSIGNED, "unsigned");
- /* Now check the real type */
+ /* Now check the real type */
switch (C & T_MASK_TYPE) {
- case T_TYPE_CHAR:
- fprintf (F, "char");
- break;
- case T_TYPE_SHORT:
- fprintf (F, "short");
- break;
- case T_TYPE_INT:
- fprintf (F, "int");
- break;
- case T_TYPE_LONG:
- fprintf (F, "long");
- break;
- case T_TYPE_LONGLONG:
- fprintf (F, "long long");
- break;
- case T_TYPE_FLOAT:
- fprintf (F, "float");
- break;
- case T_TYPE_DOUBLE:
- fprintf (F, "double");
- break;
+ case T_TYPE_CHAR:
+ fprintf (F, "char");
+ break;
+ case T_TYPE_SHORT:
+ fprintf (F, "short");
+ break;
+ case T_TYPE_INT:
+ fprintf (F, "int");
+ break;
+ case T_TYPE_LONG:
+ fprintf (F, "long");
+ break;
+ case T_TYPE_LONGLONG:
+ fprintf (F, "long long");
+ break;
+ case T_TYPE_FLOAT:
+ fprintf (F, "float");
+ break;
+ case T_TYPE_DOUBLE:
+ fprintf (F, "double");
+ break;
case T_TYPE_VOID:
fprintf (F, "void");
- break;
- case T_TYPE_STRUCT:
- fprintf (F, "struct %s", ((SymEntry*) T->A.P)->Name);
- break;
- case T_TYPE_UNION:
- fprintf (F, "union %s", ((SymEntry*) T->A.P)->Name);
- break;
- case T_TYPE_ARRAY:
- /* Recursive call */
- PrintType (F, T + 1);
- if (T->A.L == UNSPECIFIED) {
- fprintf (F, "[]");
- } else {
- fprintf (F, "[%ld]", T->A.L);
- }
- return;
- case T_TYPE_PTR:
- /* Recursive call */
- PrintType (F, T + 1);
- fprintf (F, "*");
- return;
- case T_TYPE_FUNC:
- fprintf (F, "function returning ");
- break;
- default:
- fprintf (F, "unknown type: %04lX", T->C);
- }
+ break;
+ case T_TYPE_STRUCT:
+ fprintf (F, "struct %s", ((SymEntry*) T->A.P)->Name);
+ break;
+ case T_TYPE_UNION:
+ fprintf (F, "union %s", ((SymEntry*) T->A.P)->Name);
+ break;
+ case T_TYPE_ARRAY:
+ /* Recursive call */
+ PrintType (F, T + 1);
+ if (T->A.L == UNSPECIFIED) {
+ fprintf (F, "[]");
+ } else {
+ fprintf (F, "[%ld]", T->A.L);
+ }
+ return;
+ case T_TYPE_PTR:
+ /* Recursive call */
+ PrintType (F, T + 1);
+ fprintf (F, "*");
+ return;
+ case T_TYPE_FUNC:
+ fprintf (F, "function returning ");
+ break;
+ default:
+ fprintf (F, "unknown type: %04lX", T->C);
+ }
/* Next element */
++T;
/* Print a comment with the function signature */
PrintType (F, GetFuncReturn (T));
- if (D->Flags & FD_NEAR) {
+ if (IsQualNear (T)) {
fprintf (F, " __near__");
}
- if (D->Flags & FD_FAR) {
+ if (IsQualFar (T)) {
fprintf (F, " __far__");
}
- if (D->Flags & FD_FASTCALL) {
+ if (IsQualFastcall (T)) {
fprintf (F, " __fastcall__");
}
+ if (IsQualCDecl (T)) {
+ fprintf (F, " __cdecl__");
+ }
fprintf (F, " %s (", Name);
/* Parameters */
if (D->Flags & FD_VOID_PARAM) {
- fprintf (F, "void");
+ fprintf (F, "void");
} else {
- unsigned I;
- SymEntry* E = D->SymTab->SymHead;
- for (I = 0; I < D->ParamCount; ++I) {
- if (I > 0) {
- fprintf (F, ", ");
- }
+ unsigned I;
+ SymEntry* E = D->SymTab->SymHead;
+ for (I = 0; I < D->ParamCount; ++I) {
+ if (I > 0) {
+ fprintf (F, ", ");
+ }
if (SymIsRegVar (E)) {
fprintf (F, "register ");
}
- PrintType (F, E->Type);
- E = E->NextSym;
- }
+ PrintType (F, E->Type);
+ E = E->NextSym;
+ }
}
/* End of parameter list */
-Type* ArrayToPtr (const Type* T)
+Type* ArrayToPtr (Type* T)
/* Convert an array to a pointer to it's first element */
{
- /* Function must only be called for an array */
- CHECK (IsTypeArray (T));
-
/* Return pointer to first element */
- return PointerTo (T + 1);
-}
-
-
-
-TypeCode GetQualifier (const Type* T)
-/* Get the qualifier from the given type string */
-{
- /* If this is an array, look at the element type, otherwise look at the
- * type itself.
- */
- if (IsTypeArray (T)) {
- ++T;
- }
- return (T->C & T_MASK_QUAL);
-}
-
-
-
-int IsFastCallFunc (const Type* T)
-/* Return true if this is a function type or pointer to function with
- * __fastcall__ calling conventions
- */
-{
- FuncDesc* F = GetFuncDesc (T);
- return (F->Flags & FD_FASTCALL) != 0;
+ return PointerTo (GetElementType (T));
}
+TypeCode AddrSizeQualifier (unsigned AddrSize)
+/* Return T_QUAL_NEAR or T_QUAL_FAR depending on the address size */
+{
+ switch (AddrSize) {
+
+ case ADDR_SIZE_ABS:
+ return T_QUAL_NEAR;
+
+ case ADDR_SIZE_FAR:
+ return T_QUAL_FAR;
+
+ default:
+ Error ("Invalid address size");
+ return T_QUAL_NEAR;
+
+ }
+}
+
+