MWCC/includes/compiler/types.h

455 lines
12 KiB
C
Raw Normal View History

2022-10-25 19:30:28 +00:00
#ifndef COMPILER_TYPES_H
#define COMPILER_TYPES_H
#include "compiler/common.h"
#ifdef __MWERKS__
#pragma options align=mac68k
#endif
typedef enum TypeType {
TYPEVOID = 0,
TYPEINT,
TYPEFLOAT,
TYPEENUM,
TYPESTRUCT,
TYPECLASS,
TYPEFUNC,
TYPEBITFIELD,
TYPELABEL,
TYPETEMPLATE,
TYPEMEMBERPOINTER,
TYPEPOINTER,
TYPEARRAY,
TYPEOBJCID,
TYPETEMPLDEPEXPR,
TYPEILLEGAL = -1
} TypeType;
/// Common fields across all kinds of types
struct Type {
TypeType type;
SInt32 size;
};
typedef enum IntegralType {
IT_BOOL = 0,
IT_CHAR = 1,
IT_SCHAR = 2,
IT_UCHAR = 3,
IT_WCHAR_T = 4,
IT_SHORT = 5,
IT_USHORT = 6,
IT_INT = 7,
IT_UINT = 8,
IT_LONG = 9,
IT_ULONG = 10,
IT_LONGLONG = 11,
IT_ULONGLONG = 12,
IT_FLOAT = 13,
IT_SHORTDOUBLE = 14,
IT_DOUBLE = 15,
IT_LONGDOUBLE = 16,
IT_17 = 17,
IT_18 = 18,
IT_19 = 19,
IT_20 = 20,
IT_21 = 21,
IT_22 = 22,
IT_23 = 23,
IT_24 = 24
2022-10-25 19:30:28 +00:00
} IntegralType;
// This is probably actually called AtomType / TypeAtom
2022-10-25 19:30:28 +00:00
struct TypeIntegral {
TypeType type;
SInt32 size;
unsigned char integral;
};
struct TypeEnum { // checked via CPrec
TypeType type;
SInt32 size;
NameSpace *nspace;
ObjEnumConst *enumlist;
Type *enumtype;
HashNameNode *enumname;
};
struct TypeStruct {
TypeType type;
SInt32 size;
HashNameNode *name;
StructMember *members;
char stype;
SInt16 align;
};
struct StructMember {
StructMember *next;
Type *type;
HashNameNode *name;
SInt32 offset;
UInt32 qual;
};
2023-01-11 22:29:53 +00:00
enum {
2022-10-25 19:30:28 +00:00
STRUCT_TYPE_STRUCT = 0,
STRUCT_TYPE_UNION = 1,
2022-11-07 03:06:21 +00:00
STRUCT_TYPE_CLASS = 2,
STRUCT_TYPE_3 = 3,
2022-10-25 19:30:28 +00:00
STRUCT_TYPE_4 = 4,
STRUCT_TYPE_5 = 5,
STRUCT_TYPE_6 = 6,
STRUCT_TYPE_7 = 7,
STRUCT_TYPE_8 = 8,
STRUCT_TYPE_9 = 9,
STRUCT_TYPE_A = 10,
STRUCT_TYPE_B = 11,
STRUCT_TYPE_C = 12,
STRUCT_TYPE_D = 13,
STRUCT_TYPE_E = 14
2023-01-11 22:29:53 +00:00
};
//const char STRUCT_TYPE_STRUCT = 0;
//const char STRUCT_TYPE_UNION = 1;
//const char STRUCT_TYPE_CLASS = 2;
//const char STRUCT_TYPE_3 = 3;
//const char STRUCT_TYPE_4 = 4;
//const char STRUCT_TYPE_5 = 5;
//const char STRUCT_TYPE_6 = 6;
//const char STRUCT_TYPE_7 = 7;
//const char STRUCT_TYPE_8 = 8;
//const char STRUCT_TYPE_9 = 9;
//const char STRUCT_TYPE_A = 10;
//const char STRUCT_TYPE_B = 11;
//const char STRUCT_TYPE_C = 12;
//const char STRUCT_TYPE_D = 13;
//const char STRUCT_TYPE_E = 14;
2022-10-25 19:30:28 +00:00
2022-11-07 03:06:21 +00:00
struct ClassList { // checked via CPrec
ClassList *next;
2022-10-25 19:30:28 +00:00
TypeClass *base;
SInt32 offset;
SInt32 voffset;
AccessType access;
Boolean is_virtual;
2022-11-07 03:06:21 +00:00
};
2022-10-25 19:30:28 +00:00
2022-11-07 03:06:21 +00:00
struct VClassList { // checked via CPrec
VClassList *next;
2022-10-25 19:30:28 +00:00
TypeClass *base;
2023-01-10 11:05:21 +00:00
SInt32 offset; // offset within the class instance
SInt32 voffset; // offset within the vtable
2022-10-25 19:30:28 +00:00
Boolean has_override;
char alignsave;
2022-11-07 03:06:21 +00:00
};
2022-10-25 19:30:28 +00:00
typedef struct ClassFriend { // checked via CPrec
struct ClassFriend *next;
union {
TypeClass *theclass;
Object *obj;
} u;
Boolean isclass;
} ClassFriend;
struct BClassList { // checked via CPrec
struct BClassList *next;
Type *type;
};
typedef struct VTable { // checked via CPrec
Object *object;
TypeClass *owner;
SInt32 offset;
SInt32 size;
} VTable;
struct TypeClass {
TypeType type;
SInt32 size;
NameSpace *nspace;
HashNameNode *classname;
ClassList *bases;
VClassList *vbases;
ObjMemberVar *ivars;
ClassFriend *friends;
VTable *vtable;
SOMInfo *sominfo;
ObjCInfo *objcinfo;
UInt16 flags;
SInt8 mode;
SInt8 action;
SInt16 align;
UInt8 eflags;
};
2022-11-07 03:06:21 +00:00
typedef enum {
2022-12-29 12:32:55 +00:00
CLASS_MODE_0 = 0, // struct
CLASS_MODE_1 = 1, // union
CLASS_MODE_2 = 2 // class
2022-11-07 03:06:21 +00:00
} ClassMode;
2022-10-25 19:30:28 +00:00
enum {
2022-11-07 03:06:21 +00:00
CLASS_FLAGS_1 = 1,
2022-12-29 12:32:55 +00:00
CLASS_FLAGS_2 = 2, // completed class?
2022-11-07 03:06:21 +00:00
CLASS_FLAGS_ABSTRACT = 8,
CLASS_FLAGS_10 = 0x10,
2022-10-25 19:30:28 +00:00
CLASS_FLAGS_20 = 0x20,
2022-11-07 03:06:21 +00:00
CLASS_FLAGS_40 = 0x40,
CLASS_FLAGS_80 = 0x80,
2022-10-25 19:30:28 +00:00
CLASS_FLAGS_100 = 0x100, // is TemplClass
CLASS_FLAGS_800 = 0x800, // is TemplClassInst
2022-11-07 03:06:21 +00:00
CLASS_FLAGS_900 = 0x900,
2023-01-10 11:05:21 +00:00
CLASS_FLAGS_1000 = 0x1000, // is empty class
2022-11-07 03:06:21 +00:00
CLASS_FLAGS_2000 = 0x2000,
CLASS_FLAGS_4000 = 0x4000,
CLASS_FLAGS_8000 = 0x8000
2022-10-25 19:30:28 +00:00
};
2022-11-07 03:06:21 +00:00
/// maps to TypeClass::eflags
enum {
CLASS_EFLAGS_INTERNAL = 1,
CLASS_EFLAGS_IMPORT = 2,
2023-01-10 11:05:21 +00:00
CLASS_EFLAGS_EXPORT = 4,
CLASS_EFLAGS_F0 = 0xF0
2022-11-07 03:06:21 +00:00
};
enum {
CLASS_ACTION_0 = 0,
CLASS_ACTION_1 = 1,
CLASS_ACTION_2 = 2,
CLASS_ACTION_3 = 3 // __javaobject
};
2022-10-25 19:30:28 +00:00
2022-12-29 12:32:55 +00:00
struct ExceptSpecList {
ExceptSpecList *next;
2022-10-25 19:30:28 +00:00
Type *type;
UInt32 qual;
2022-12-29 12:32:55 +00:00
};
2022-10-25 19:30:28 +00:00
struct FuncArg { // ok
struct FuncArg *next;
HashNameNode *name;
ENode *dexpr;
Type *type;
UInt32 qual;
SInt16 sclass;
Boolean is_array;
Boolean has_defdefarg;
};
struct TypeFunc {
TypeType type;
SInt32 size;
FuncArg *args;
ExceptSpecList *exspecs;
Type *functype;
UInt32 qual;
UInt32 flags;
};
enum {
FUNC_FLAGS_PASCAL = 1, // on TypeFunc::flags
2022-12-29 12:32:55 +00:00
FUNC_FLAGS_2 = 2, // member function that has an inline definition?
2022-11-07 03:06:21 +00:00
FUNC_FLAGS_4 = 4,
2022-12-29 12:32:55 +00:00
FUNC_FLAGS_8 = 8, // abstract
2022-10-25 19:30:28 +00:00
FUNC_FLAGS_METHOD = 0x10,
2022-12-29 12:32:55 +00:00
FUNC_FLAGS_20 = 0x20,
2022-10-25 19:30:28 +00:00
FUNC_FLAGS_40 = 0x40, // func that's like "operator SomeOtherType()"
2022-11-07 03:06:21 +00:00
FUNC_FLAGS_80 = 0x80,
FUNC_FLAGS_100 = 0x100,
FUNC_FLAGS_200 = 0x200, // intrinsic?
2022-11-07 03:06:21 +00:00
FUNC_FLAGS_NOTHROW = 0x400,
2022-12-29 12:32:55 +00:00
FUNC_FLAGS_800 = 0x800, // autoinlined?
FUNC_FLAGS_1000 = 0x1000, // is ctor
FUNC_FLAGS_2000 = 0x2000, // is dtor
FUNC_FLAGS_4000 = 0x4000, // objc method?
2022-11-07 03:06:21 +00:00
FUNC_FLAGS_CONST = 0x8000,
FUNC_FLAGS_VOLATILE = 0x10000,
2023-01-10 11:05:21 +00:00
FUNC_FLAGS_CV = FUNC_FLAGS_CONST | FUNC_FLAGS_VOLATILE,
2022-11-07 03:06:21 +00:00
FUNC_FLAGS_100000 = 0x100000, // is template?
2022-12-29 12:32:55 +00:00
FUNC_FLAGS_200000 = 0x200000,
2023-01-10 11:05:21 +00:00
FUNC_FLAGS_400000 = 0x400000, // covariant?
2022-11-07 03:06:21 +00:00
FUNC_FLAGS_800000 = 0x800000,
FUNC_FLAGS_900000 = 0x900000,
FUNC_FLAGS_4000000 = 0x4000000,
FUNC_FLAGS_10000000 = 0x10000000,
FUNC_FLAGS_F0000000 = 0xF0000000
2022-10-25 19:30:28 +00:00
};
2022-11-07 03:06:21 +00:00
// This is actually called TypeMemberFunc...
2022-10-25 19:30:28 +00:00
// There seems to be a version of this which adds a class pointer at the end
struct TypeMethod {
TypeType type;
SInt32 size;
FuncArg *args;
ExceptSpecList *exspecs;
Type *functype;
UInt32 qual;
UInt32 flags;
TypeClass *theclass;
2022-11-07 03:06:21 +00:00
SInt32 x1E; // vtable offset?
2022-12-29 12:32:55 +00:00
SInt32 x22; // browser index?
Boolean x26; // is static
2022-10-25 19:30:28 +00:00
};
struct TypeBitfield {
TypeType type;
SInt32 size;
Type *bitfieldtype;
2022-12-29 12:32:55 +00:00
char unkA; // offset in bits
char unkB; // size in bits
2022-10-25 19:30:28 +00:00
};
// Label
typedef enum TypeTemplDepType {
TEMPLDEP_ARGUMENT,
TEMPLDEP_QUALNAME,
TEMPLDEP_TEMPLATE,
TEMPLDEP_ARRAY,
TEMPLDEP_QUALTEMPL,
TEMPLDEP_BITFIELD,
TEMPLDEP_VALUEDEP, // not in v7?
TEMPLDEP_ENUMVAL, // not in v7?
TEMPLDEP_TYPEOF // not in v7?
} TypeTemplDepType;
struct TypeTemplDep {
TypeType type;
SInt32 size;
TypeTemplDepType dtype;
union {
TemplParamID pid;
struct {
TypeTemplDep *type;
HashNameNode *name;
} qual;
struct {
TemplClass *templ;
TemplArg *args;
} templ;
struct {
Type *type;
ENode *index;
} array;
struct {
TypeTemplDep *type;
TemplArg *args;
} qualtempl;
struct {
Type *type;
ENode *size;
} bitfield;
// the following ones may not be in v7
Type *vdep;
ENode *tof;
struct {
TypeEnum *etype;
ENode *expr;
} enumval;
} u;
};
struct TypeMemberPointer {
TypeType type;
SInt32 size;
Type *ty1;
Type *ty2;
UInt32 qual;
};
/// Used for TYPEPOINTER and TYPEARRAY
struct TypePointer {
TypeType type;
SInt32 size;
Type *target;
UInt32 qual;
};
2022-12-29 12:32:55 +00:00
/// Always has Q_100000 set
struct TypeObjCID {
TypePointer pointer;
ObjCProtocolList *protocols;
short x12;
};
2022-10-25 19:30:28 +00:00
2022-11-07 03:06:21 +00:00
struct TypeList {
TypeList *next;
Type *type;
};
2022-10-25 19:30:28 +00:00
// Not sure if these existed originally, but they'll help
2022-11-07 03:06:21 +00:00
#define TYPE(ty) ((Type *) (ty))
2022-10-25 19:30:28 +00:00
#define TYPE_INTEGRAL(ty) ((TypeIntegral *) (ty))
#define TYPE_ENUM(ty) ((TypeEnum *) (ty))
#define TYPE_STRUCT(ty) ((TypeStruct *) (ty))
#define TYPE_CLASS(ty) ((TypeClass *) (ty))
#define TYPE_FUNC(ty) ((TypeFunc *) (ty))
#define TYPE_METHOD(ty) ((TypeMethod *) (ty))
#define TYPE_BITFIELD(ty) ((TypeBitfield *) (ty))
#define TYPE_TEMPLATE(ty) ((TypeTemplDep *) (ty))
#define TYPE_MEMBER_POINTER(ty) ((TypeMemberPointer *) (ty))
#define TYPE_POINTER(ty) ((TypePointer *) (ty))
#define TPTR_TARGET(ty) (TYPE_POINTER(ty)->target)
#define TPTR_QUAL(ty) (TYPE_POINTER(ty)->qual)
2022-12-29 12:32:55 +00:00
#define TYPE_OBJC_ID(ty) ((TypeObjCID *) (ty))
2022-10-25 19:30:28 +00:00
2022-11-07 03:06:21 +00:00
#define IS_TYPE_VOID(ty) ( (ty)->type == TYPEVOID )
#define IS_TYPE_INT(ty) ( (ty)->type == TYPEINT )
#define IS_TYPE_ENUM(ty) ( (ty)->type == TYPEENUM )
#define IS_TYPE_INT_OR_ENUM(ty) ( IS_TYPE_INT(ty) || IS_TYPE_ENUM(ty) )
#define IS_TYPE_FLOAT(ty) ( (ty)->type == TYPEFLOAT )
#define IS_TYPE_INT_OR_FLOAT(ty) ( IS_TYPE_INT(ty) || IS_TYPE_FLOAT(ty) )
2022-11-07 03:06:21 +00:00
#define IS_TYPE_STRUCT(ty) ( (ty)->type == TYPESTRUCT )
#define IS_TYPE_CLASS(ty) ( (ty)->type == TYPECLASS )
2023-01-10 11:05:21 +00:00
#define IS_TYPE_SOM_CLASS(ty) ( (ty)->type == TYPECLASS && TYPE_CLASS((ty))->sominfo )
2022-12-29 12:32:55 +00:00
#define IS_TYPE_OBJC_CLASS(ty) ( (ty)->type == TYPECLASS && TYPE_CLASS((ty))->objcinfo )
2022-11-07 03:06:21 +00:00
#define IS_TYPE_FUNC(ty) ( (ty)->type == TYPEFUNC )
#define IS_TYPEFUNC_METHOD(ty) ( (ty)->flags & FUNC_FLAGS_METHOD )
#define IS_TYPE_METHOD(ty) ( IS_TYPE_FUNC(ty) && IS_TYPEFUNC_METHOD(TYPE_FUNC(ty)) )
2023-01-10 11:05:21 +00:00
#define IS_TYPE_NONMETHOD(ty) ( IS_TYPE_FUNC(ty) && !IS_TYPEFUNC_METHOD(TYPE_FUNC(ty)) )
#define IS_TYPE_NONSTATIC_METHOD(ty) ( IS_TYPE_FUNC(ty) && IS_TYPEFUNC_METHOD(TYPE_FUNC(ty)) && !TYPE_METHOD(ty)->x26 )
#define IS_TYPE_STATIC_METHOD(ty) ( IS_TYPE_FUNC(ty) && IS_TYPEFUNC_METHOD(TYPE_FUNC(ty)) && TYPE_METHOD(ty)->x26 )
2022-12-29 12:32:55 +00:00
#define IS_TYPEFUNC_NONSTATIC_METHOD(ty) ( IS_TYPEFUNC_METHOD(ty) && !TYPE_METHOD(ty)->x26 )
#define IS_TYPEFUNC_STATIC_METHOD(ty) ( IS_TYPEFUNC_METHOD(ty) && TYPE_METHOD(ty)->x26 )
2022-11-07 03:06:21 +00:00
#define IS_TYPE_TEMPLATE(ty) ( (ty)->type == TYPETEMPLATE )
#define IS_TYPE_POINTER(ty) ( (ty)->type == TYPEPOINTER || (ty)->type == TYPEARRAY )
#define IS_TYPE_POINTER_ONLY(ty) ( (ty)->type == TYPEPOINTER )
#define IS_TYPE_REFERENCE(ty) ( (ty)->type == TYPEPOINTER && (TYPE_POINTER(ty)->qual & Q_REFERENCE) )
#define IS_TYPEPOINTER_REFERENCE(ty) ( (ty)->qual & Q_REFERENCE )
#define IS_TYPE_ARRAY(ty) ( (ty)->type == TYPEARRAY )
#define IS_TYPE_BITFIELD(ty) ( (ty)->type == TYPEBITFIELD )
#define IS_TYPE_TEMPLDEPEXPR(ty) ( (ty)->type == TYPETEMPLDEPEXPR )
2023-01-10 11:05:21 +00:00
#define IS_TYPESTRUCT_VECTOR(ty) ( (ty)->stype >= STRUCT_TYPE_4 && (ty)->stype <= STRUCT_TYPE_E )
2022-11-07 03:06:21 +00:00
#define IS_TYPE_VECTOR(ty) ( (ty)->type == TYPESTRUCT && IS_TYPESTRUCT_VECTOR(TYPE_STRUCT(ty)) )
#define IS_TYPE_NONVECTOR_STRUCT(ty) ( (ty)->type == TYPESTRUCT && !IS_TYPESTRUCT_VECTOR(TYPE_STRUCT(ty)) )
#define IS_TYPE_MEMBERPOINTER(ty) ( (ty)->type == TYPEMEMBERPOINTER )
#define IS_TYPE_4BYTES_MEMBERPOINTER(ty) ( ((ty)->type == TYPEMEMBERPOINTER) && ((ty)->size == 4u) )
#define IS_TYPE_12BYTES_MEMBERPOINTER(ty) ( ((ty)->type == TYPEMEMBERPOINTER) && ((ty)->size == 12u) )
#define TYPE_FITS_IN_REGISTER(ty) ( ((ty)->type == TYPEINT) || ((ty)->type == TYPEENUM) || (IS_TYPE_POINTER(ty) && ((ty)->type != TYPEARRAY)) || IS_TYPE_4BYTES_MEMBERPOINTER(ty) )
#define TYPE_IS_8BYTES(ty) ( (((ty)->type == TYPEINT) || ((ty)->type == TYPEENUM)) && ((ty)->size == 8) )
#define TYPE_FITS_IN_REGISTER_2(ty) ( ((ty)->type == TYPEINT) || ((ty)->type == TYPEENUM) || IS_TYPE_POINTER(ty) || IS_TYPE_4BYTES_MEMBERPOINTER(ty) )
2022-11-07 03:06:21 +00:00
#define OBJ_GET_TARGET_VOLATILE(obj) ( IS_TYPE_POINTER((obj)->type) ? (TYPE_POINTER((obj)->type)->qual & Q_VOLATILE) : ((obj)->qual & Q_VOLATILE) )
#define OBJ_GET_TARGET_CONST(obj) ( IS_TYPE_POINTER((obj)->type) ? (TYPE_POINTER((obj)->type)->qual & Q_CONST) : ((obj)->qual & Q_CONST) )
2022-10-25 19:30:28 +00:00
#ifdef __MWERKS__
#pragma options align=reset
#endif
#endif