#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 } IntegralType; // This is probably actually called AtomType / TypeAtom 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; }; enum { STRUCT_TYPE_STRUCT = 0, STRUCT_TYPE_UNION = 1, STRUCT_TYPE_CLASS = 2, STRUCT_TYPE_3 = 3, 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 }; //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; struct ClassList { // checked via CPrec ClassList *next; TypeClass *base; SInt32 offset; SInt32 voffset; AccessType access; Boolean is_virtual; }; struct VClassList { // checked via CPrec VClassList *next; TypeClass *base; SInt32 offset; // offset within the class instance SInt32 voffset; // offset within the vtable Boolean has_override; char alignsave; }; 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; }; typedef enum { CLASS_MODE_0 = 0, // struct CLASS_MODE_1 = 1, // union CLASS_MODE_2 = 2 // class } ClassMode; enum { CLASS_FLAGS_1 = 1, CLASS_FLAGS_2 = 2, // completed class? CLASS_FLAGS_ABSTRACT = 8, CLASS_FLAGS_10 = 0x10, CLASS_FLAGS_20 = 0x20, CLASS_FLAGS_40 = 0x40, CLASS_FLAGS_80 = 0x80, CLASS_FLAGS_100 = 0x100, // is TemplClass CLASS_FLAGS_800 = 0x800, // is TemplClassInst CLASS_FLAGS_900 = 0x900, CLASS_FLAGS_1000 = 0x1000, // is empty class CLASS_FLAGS_2000 = 0x2000, CLASS_FLAGS_4000 = 0x4000, CLASS_FLAGS_8000 = 0x8000 }; /// maps to TypeClass::eflags enum { CLASS_EFLAGS_INTERNAL = 1, CLASS_EFLAGS_IMPORT = 2, CLASS_EFLAGS_EXPORT = 4, CLASS_EFLAGS_F0 = 0xF0 }; enum { CLASS_ACTION_0 = 0, CLASS_ACTION_1 = 1, CLASS_ACTION_2 = 2, CLASS_ACTION_3 = 3 // __javaobject }; struct ExceptSpecList { ExceptSpecList *next; Type *type; UInt32 qual; }; 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 FUNC_FLAGS_2 = 2, // member function that has an inline definition? FUNC_FLAGS_4 = 4, FUNC_FLAGS_8 = 8, // abstract FUNC_FLAGS_METHOD = 0x10, FUNC_FLAGS_20 = 0x20, FUNC_FLAGS_40 = 0x40, // func that's like "operator SomeOtherType()" FUNC_FLAGS_80 = 0x80, FUNC_FLAGS_100 = 0x100, FUNC_FLAGS_200 = 0x200, // intrinsic? FUNC_FLAGS_NOTHROW = 0x400, FUNC_FLAGS_800 = 0x800, // autoinlined? FUNC_FLAGS_1000 = 0x1000, // is ctor FUNC_FLAGS_2000 = 0x2000, // is dtor FUNC_FLAGS_4000 = 0x4000, // objc method? FUNC_FLAGS_CONST = 0x8000, FUNC_FLAGS_VOLATILE = 0x10000, FUNC_FLAGS_CV = FUNC_FLAGS_CONST | FUNC_FLAGS_VOLATILE, FUNC_FLAGS_100000 = 0x100000, // is template? FUNC_FLAGS_200000 = 0x200000, FUNC_FLAGS_400000 = 0x400000, // covariant? FUNC_FLAGS_800000 = 0x800000, FUNC_FLAGS_900000 = 0x900000, FUNC_FLAGS_4000000 = 0x4000000, FUNC_FLAGS_10000000 = 0x10000000, FUNC_FLAGS_F0000000 = 0xF0000000 }; // This is actually called TypeMemberFunc... // 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; SInt32 x1E; // vtable offset? SInt32 x22; // browser index? Boolean x26; // is static }; struct TypeBitfield { TypeType type; SInt32 size; Type *bitfieldtype; char unkA; // offset in bits char unkB; // size in bits }; // 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; }; /// Always has Q_100000 set struct TypeObjCID { TypePointer pointer; ObjCProtocolList *protocols; short x12; }; struct TypeList { TypeList *next; Type *type; }; // Not sure if these existed originally, but they'll help #define TYPE(ty) ((Type *) (ty)) #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) #define TYPE_OBJC_ID(ty) ((TypeObjCID *) (ty)) #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) ) #define IS_TYPE_STRUCT(ty) ( (ty)->type == TYPESTRUCT ) #define IS_TYPE_CLASS(ty) ( (ty)->type == TYPECLASS ) #define IS_TYPE_SOM_CLASS(ty) ( (ty)->type == TYPECLASS && TYPE_CLASS((ty))->sominfo ) #define IS_TYPE_OBJC_CLASS(ty) ( (ty)->type == TYPECLASS && TYPE_CLASS((ty))->objcinfo ) #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)) ) #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 ) #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 ) #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 ) #define IS_TYPESTRUCT_VECTOR(ty) ( (ty)->stype >= STRUCT_TYPE_4 && (ty)->stype <= STRUCT_TYPE_E ) #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) ) #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) ) #ifdef __MWERKS__ #pragma options align=reset #endif #endif