move lots of source files around to match their actual placement in the original tree

This commit is contained in:
Ash Wolf
2023-01-26 11:30:47 +00:00
parent fc0c4c0df7
commit 094b96ca1d
120 changed files with 400 additions and 392 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,737 @@
#include "compiler/CBrowse.h"
#include "compiler/CDecl.h"
#include "compiler/CError.h"
#include "compiler/CMangler.h"
#include "compiler/CParser.h"
#include "compiler/CPrep.h"
#include "compiler/CompilerTools.h"
#include "compiler/Unmangle.h"
#include "compiler/objects.h"
#include "compiler/templates.h"
#include "cos.h"
#include "plugin.h"
Boolean gUseTokenStreamSource;
Boolean gForceSourceLoc;
Boolean gUseNameTable;
static GList gBrowseData;
static GList gClassData;
static GList gMemberFuncList;
static int gNextMemberFuncID;
enum ELanguage {
langUnknown,
langC,
langCPlus,
langPascal,
langObjectPascal,
langJava,
langAssembler,
langFortran,
langRez
};
enum EBrowserItem {
browseFunction,
browseGlobal,
browseClass,
browseMacro,
browseEnum,
browseTypedef,
browseConstant,
browseTemplate,
browsePackage,
browseCompSymbolStart = 0x70,
browseEnd = 0xFF
};
enum {
kAbstract = 1,
kStatic = 2,
kFinal = 4,
kMember = 8,
kInterface = 0x80,
kPublic = 0x100,
kInline = 0x80,
kPascal = 0x100,
kAsm = 0x200,
kVirtual = 0x400,
kCtor = 0x800,
kDtor = 0x1000,
kNative = 0x2000,
kSynch = 0x4000,
kIntrinsic = 0x8000,
kConst = 0x10000,
kTransient = 0x80,
kVolatile = 0x100
};
enum EAccess {
accessNone = 0,
accessPrivate = 1,
accessProtected = 2,
accessPublic = 4
};
enum EMember {
memberFunction,
memberData,
memberEnd = 0xFF
};
enum ETemplateType {
templateClass,
templateFunction
};
static enum EAccess gFromAccessType[] = {
accessPublic,
accessPrivate,
accessProtected,
accessNone
};
typedef struct BrowseHeader {
SInt32 browse_header;
SInt32 browse_version;
SInt16 browse_language;
SInt16 uses_name_table;
SInt32 earliest_compatible_version;
SInt32 reserved[15];
} BrowseHeader;
// forward decls
static void RecordUndefinedMemberFunctions(void);
void CBrowse_Setup(CompilerLinkerParamBlk *params) {
BrowseHeader hdr;
CError_ASSERT(123, params != NULL);
params->object.browsedata = NULL;
InitGList(&gBrowseData, 0x10000);
InitGList(&gMemberFuncList, 1024);
gNextMemberFuncID = 1;
gForceSourceLoc = 0;
gUseNameTable = 0;
memclrw(&hdr, sizeof(hdr));
hdr.browse_header = 0xBEABBAEB;
hdr.browse_version = 2;
hdr.earliest_compatible_version = 2;
hdr.browse_language = copts.cplusplus ? langCPlus : langC;
hdr.uses_name_table = gUseNameTable;
AppendGListData(&gBrowseData, &hdr, sizeof(hdr));
}
void CBrowse_Finish(CompilerLinkerParamBlk *params) {
CWMemHandle hnd;
CError_ASSERT(151, params != NULL);
if (gBrowseData.size >= sizeof(BrowseHeader)) {
RecordUndefinedMemberFunctions();
AppendGListByte(&gBrowseData, -1);
COS_ResizeHandle(gBrowseData.data, gBrowseData.size);
if (CWSecretAttachHandle(params->context, gBrowseData.data, &hnd) == cwNoErr) {
params->object.browsedata = hnd;
gBrowseData.data = NULL;
}
}
}
void CBrowse_Cleanup(CompilerLinkerParamBlk *params) {
FreeGList(&gBrowseData);
FreeGList(&gClassData);
FreeGList(&gMemberFuncList);
}
static void AppendGList(GList *dst, GList *src) {
SInt32 offset = dst->size;
AppendGListNoData(dst, src->size);
memcpy(*dst->data + offset, *src->data, src->size);
}
static void RecordName(GList *gl, const char *str, SInt32 id) {
HashNameNode *name;
CError_ASSERT(190, gl && str && *str);
if (id < 0 && gUseNameTable) {
for (name = name_hash_nodes[CHash(str)]; name; name = name->next) {
if (!strcmp(str, name->name)) {
id = name->id;
break;
}
}
}
if (id >= 0 && gUseNameTable) {
AppendGListWord(gl, -1);
AppendGListLong(gl, id);
} else {
int len = strlen(str);
AppendGListWord(gl, len);
if (len)
AppendGListData(gl, str, len + 1);
}
}
void CBrowse_BeginClass(DeclInfo *di, GList *gl) {
char *buf;
ClassList *base;
SInt32 i;
TypeClass *tclass;
CError_ASSERT(227, di && di->thetype && gl);
*gl = gClassData;
if (
!di->file ||
!di->file->fileID ||
!di->file->recordbrowseinfo ||
!di->file2 ||
!di->file2->fileID ||
di->sourceoffset <= 0
)
{
memclrw(&gClassData, sizeof(gClassData));
return;
}
if (IsTempName(TYPE_CLASS(di->thetype)->classname)) {
memclrw(&gClassData, sizeof(gClassData));
return;
}
InitGList(&gClassData, 0x4000);
AppendGListByte(&gClassData, browseClass);
AppendGListWord(&gClassData, di->file->fileID);
AppendGListWord(&gClassData, di->file2->fileID);
AppendGListLong(&gClassData, di->sourceoffset - 1);
CError_ASSERT(270, gClassData.size == 9);
AppendGListLong(&gClassData, di->sourceoffset - 1);
AppendGListLong(&gClassData, 0);
RecordName(&gClassData, TYPE_CLASS(di->thetype)->classname->name, TYPE_CLASS(di->thetype)->classname->id);
CMangler_MangleType(di->thetype, 0);
AppendGListByte(&name_mangle_list, 0);
buf = lalloc(name_mangle_list.size + 1);
strcpy(buf, *name_mangle_list.data);
while (*buf && *buf >= '0' && *buf <= '9')
buf++;
if (strcmp(TYPE_CLASS(di->thetype)->classname->name, buf))
RecordName(&gClassData, buf, -1);
else
AppendGListWord(&gClassData, 0);
AppendGListLong(&gClassData, 0);
i = 0;
base = TYPE_CLASS(di->thetype)->bases;
while (base) {
base = base->next;
i++;
}
AppendGListByte(&gClassData, i);
for (base = TYPE_CLASS(di->thetype)->bases; base; base = base->next) {
AppendGListByte(&gClassData, gFromAccessType[base->access]);
AppendGListByte(&gClassData, base->is_virtual);
tclass = base->base;
if ((tclass->flags & CLASS_IS_TEMPL_INST) && !TEMPL_CLASS_INST(tclass)->is_specialized)
tclass = TYPE_CLASS(TEMPL_CLASS_INST(tclass)->templ);
CMangler_MangleType(TYPE(tclass), 0);
AppendGListByte(&name_mangle_list, 0);
buf = lalloc(name_mangle_list.size + 1);
strcpy(buf, *name_mangle_list.data);
while (*buf && *buf >= '0' && *buf <= '9')
buf++;
i = base->base->classname->id;
while (*buf && *buf >= '0' && *buf <= '9') {
i = -1;
buf++;
}
RecordName(&gClassData, buf, i);
}
}
void CBrowse_AddClassMemberVar(ObjMemberVar *ivar, SInt32 startOffset, SInt32 endOffset) {
short len;
CError_ASSERT(360, ivar);
if (gClassData.data && startOffset > 0 && endOffset >= startOffset) {
if (tk == ';')
endOffset++;
AppendGListByte(&gClassData, memberData);
AppendGListByte(&gClassData, gFromAccessType[ivar->access]);
AppendGListLong(&gClassData, 0);
AppendGListLong(&gClassData, startOffset - 1);
AppendGListLong(&gClassData, endOffset - 1);
len = strlen(ivar->name->name);
AppendGListWord(&gClassData, len);
AppendGListData(&gClassData, ivar->name->name, len + 1);
}
}
void CBrowse_AddClassMemberFunction(Object *object, SInt32 startOffset, SInt32 endOffset) {
SInt32 flags;
SInt32 id;
TypeMemberFunc *tfunc;
CError_ASSERT(380, object);
if (
!IsTempName(object->name) &&
gClassData.data &&
startOffset > 0 &&
endOffset >= startOffset
)
{
flags = 0;
CError_ASSERT(391, object->type && IS_TYPE_FUNC(object->type));
tfunc = TYPE_METHOD(object->type);
if (tfunc->flags & FUNC_AUTO_GENERATED)
return;
if (object->datatype == DVFUNC)
flags |= kVirtual;
if (tfunc->flags & FUNC_PURE)
flags |= kAbstract;
if (tfunc->is_static)
flags |= kStatic;
if (tfunc->flags & FUNC_IS_CTOR)
flags |= kCtor;
if (tfunc->flags & FUNC_IS_DTOR)
flags |= kDtor;
AppendGListByte(&gClassData, memberFunction);
AppendGListByte(&gClassData, gFromAccessType[object->access]);
AppendGListLong(&gClassData, flags);
id = tfunc->funcid;
if (id <= 0) {
// TODO: this is not 64-bit safe
if (!(tfunc->flags & FUNC_DEFINED) || id == -1)
AppendGListLong(&gMemberFuncList, (SInt32) object);
tfunc->funcid = id = gNextMemberFuncID++;
}
AppendGListLong(&gClassData, id);
AppendGListLong(&gClassData, startOffset - 1);
AppendGListLong(&gClassData, endOffset);
}
}
void CBrowse_AddClassMemberData(Object *object, SInt32 startOffset, SInt32 endOffset) {
short len;
CError_ASSERT(435, object);
if (gClassData.data && startOffset > 0 && endOffset >= startOffset && object->datatype == DDATA) {
if (tk == ';')
endOffset++;
AppendGListByte(&gClassData, memberData);
AppendGListByte(&gClassData, gFromAccessType[object->access]);
AppendGListLong(&gClassData, kStatic);
AppendGListLong(&gClassData, startOffset - 1);
AppendGListLong(&gClassData, endOffset - 1);
len = strlen(object->name->name);
AppendGListWord(&gClassData, len);
AppendGListData(&gClassData, object->name->name, len + 1);
}
}
void CBrowse_EndClass(SInt32 offset, GList *gl) {
CError_ASSERT(453, gl);
if (gClassData.data) {
if (gClassData.size > 0) {
if (tk == ';')
offset++;
memcpy(*gClassData.data + 9, &offset, 4);
AppendGList(&gBrowseData, &gClassData);
AppendGListByte(&gBrowseData, memberEnd);
}
FreeGList(&gClassData);
}
gClassData = *gl;
}
void CBrowse_BeginStruct(DeclInfo *di, TypeStruct *tstruct, GList *gl) {
HashNameNode *name;
CError_ASSERT(480, di && gl);
*gl = gClassData;
if (
!di->file ||
!di->file->fileID ||
!di->file->recordbrowseinfo ||
!di->file2 ||
!di->file2->fileID ||
di->sourceoffset <= 0
)
{
memclrw(&gClassData, sizeof(gClassData));
return;
}
name = tstruct->name;
if (!name || IsTempName(name)) {
memclrw(&gClassData, sizeof(gClassData));
return;
}
InitGList(&gClassData, 0x4000);
AppendGListByte(&gClassData, browseClass);
AppendGListWord(&gClassData, di->file->fileID);
AppendGListWord(&gClassData, di->file2->fileID);
AppendGListLong(&gClassData, di->sourceoffset - 1);
CError_ASSERT(521, gClassData.size == 9);
AppendGListLong(&gClassData, di->sourceoffset - 1);
AppendGListLong(&gClassData, 0);
RecordName(&gClassData, name->name, name->id);
AppendGListWord(&gClassData, 0);
AppendGListLong(&gClassData, 0);
AppendGListByte(&gClassData, 0);
}
void CBrowse_AddStructMember(StructMember *member, SInt32 startOffset, SInt32 endOffset) {
short len;
if (tk == ';')
endOffset++;
if (gClassData.data && member && startOffset > 0 && endOffset >= startOffset) {
AppendGListByte(&gClassData, memberData);
AppendGListByte(&gClassData, accessPublic);
AppendGListLong(&gClassData, 0);
AppendGListLong(&gClassData, startOffset - 1);
AppendGListLong(&gClassData, endOffset - 1);
len = strlen(member->name->name);
AppendGListWord(&gClassData, len);
AppendGListData(&gClassData, member->name->name, len + 1);
}
}
void CBrowse_EndStruct(SInt32 offset, GList *gl) {
CError_ASSERT(558, gl);
if (gClassData.data) {
if (offset > 0 && gClassData.size > 0) {
memcpy(*gClassData.data + 9, &offset, 4);
AppendGList(&gBrowseData, &gClassData);
AppendGListByte(&gBrowseData, memberEnd);
}
FreeGList(&gClassData);
}
gClassData = *gl;
}
static void EmitStandardData(int item, int fileID1, int fileID2, SInt32 startOffset, SInt32 endOffset, const char *str, SInt32 id, const char *str2, SInt32 id2) {
CError_ASSERT(584, str);
AppendGListByte(&gBrowseData, item);
AppendGListWord(&gBrowseData, fileID1);
AppendGListWord(&gBrowseData, fileID2);
AppendGListLong(&gBrowseData, startOffset - 1);
AppendGListLong(&gBrowseData, endOffset - 1);
AppendGListLong(&gBrowseData, 0);
RecordName(&gBrowseData, str, id);
if (str2 && str2 != str)
RecordName(&gBrowseData, str2, id2);
else
AppendGListWord(&gBrowseData, 0);
}
void CBrowse_NewTypedef(NameSpace *nspace, HashNameNode *name, CPrepFileInfo *file1, CPrepFileInfo *file2, SInt32 startOffset, SInt32 endOffset) {
CError_ASSERT(618, file1 && file1->recordbrowseinfo);
if (file2 && file2->fileID && startOffset > 0 && endOffset >= startOffset) {
EmitStandardData(browseTypedef,
file1->fileID, file2->fileID,
startOffset, endOffset,
name->name, name->id,
CError_GetQualifiedName(nspace, name), -1);
}
}
void CBrowse_NewEnum(NameSpace *nspace, HashNameNode *name, CPrepFileInfo *file1, CPrepFileInfo *file2, SInt32 startOffset, SInt32 endOffset) {
CError_ASSERT(632, file1 && file1->recordbrowseinfo);
if (file2 && file2->fileID && startOffset > 0 && endOffset >= startOffset) {
EmitStandardData(browseEnum,
file1->fileID, file2->fileID,
startOffset, endOffset,
name->name, name->id,
CError_GetQualifiedName(nspace, name), -1);
}
}
void CBrowse_NewEnumConstant(NameSpace *nspace, HashNameNode *name, CPrepFileInfo *file1, CPrepFileInfo *file2, SInt32 startOffset, SInt32 endOffset) {
CError_ASSERT(646, file1 && file1->recordbrowseinfo);
if (tk == ',')
endOffset++;
if (file2 && file2->fileID && startOffset > 0 && endOffset >= startOffset) {
EmitStandardData(browseConstant,
file1->fileID, file2->fileID,
startOffset, endOffset,
name->name, name->id,
CError_GetQualifiedName(nspace, name), -1);
}
}
static HashNameNode *CBrowse_GetLinkName(Object *object) {
return CMangler_GetLinkName(object);
}
static void RecordFunction(Object *object, int fileID1, int fileID2, SInt32 startOffset, SInt32 endOffset) {
TypeFunc *tfunc;
char *tmp;
Boolean flag;
char *str29;
HashNameNode *linkname;
SInt32 flags;
char *namestr;
SInt32 nameid;
char *namestr2;
SInt32 nameid2;
int funcid;
char buf[2048];
char buf2[256];
CError_ASSERT(740, object->type && IS_TYPE_FUNC(object->type));
if (IsTempName(object->name))
return;
tfunc = TYPE_FUNC(object->type);
if ((tfunc->flags & (FUNC_AUTO_GENERATED | FUNC_INTRINSIC)) && (!fileID2 || startOffset < 0))
return;
linkname = object->name;
tmp = linkname->name;
if (!(linkname->name[0] == '_' && linkname->name[1] == '_')) {
namestr = tmp;
nameid = linkname->id;
switch (tmp[0]) {
case '.':
nameid = -1;
namestr += 1;
break;
case '_':
switch (tmp[1]) {
case '#':
case '%':
case '@':
nameid = -1;
namestr += 2;
break;
}
break;
}
} else {
flag = 1;
if (tfunc->flags & (FUNC_IS_CTOR | FUNC_IS_DTOR)) {
tmp = TYPE_METHOD(tfunc)->theclass->classname->name;
while (*tmp >= '0' && *tmp <= '9')
tmp++;
MWUnmangleClassName(tmp, buf, sizeof(buf));
str29 = buf;
if ((tmp = strrchr(str29, ':')))
str29 = tmp + 1;
if (tfunc->flags & FUNC_IS_DTOR) {
buf2[0] = '~';
strncpy(&buf2[1], str29, sizeof(buf2) - 1);
namestr = buf2;
} else {
namestr = str29;
}
flag = 0;
}
if (flag) {
MWUnmangle(object->name->name, buf, sizeof(buf));
namestr = buf;
}
nameid = -1;
}
while (*namestr >= '0' && *namestr <= '9') {
nameid = -1;
namestr++;
}
namestr2 = NULL;
nameid2 = -1;
linkname = CBrowse_GetLinkName(object);
if (object->name != linkname) {
namestr2 = linkname->name;
if (linkname->name[0] == '.')
namestr2++;
else
nameid2 = linkname->id;
}
EmitStandardData(browseFunction, fileID1, fileID2, startOffset, endOffset, namestr, nameid, namestr2, nameid2);
flags = 0;
if (object->qual & Q_INLINE)
flags |= kInline;
if (object->qual & Q_PASCAL)
flags |= kPascal;
if (object->qual & Q_ASM)
flags |= kAsm;
if (object->sclass == TK_STATIC)
flags |= kStatic;
if (tfunc->flags & FUNC_METHOD)
flags |= kMember;
AppendGListLong(&gBrowseData, flags);
funcid = 0;
if (tfunc->flags & FUNC_METHOD) {
funcid = TYPE_METHOD(tfunc)->funcid;
if (funcid <= 0) {
TYPE_METHOD(tfunc)->funcid = funcid = gNextMemberFuncID++;
}
}
AppendGListLong(&gBrowseData, funcid);
}
void CBrowse_NewFunction(Object *object, CPrepFileInfo *file1, CPrepFileInfo *file2, SInt32 startOffset, SInt32 endOffset) {
CError_ASSERT(890, file1 && file1->recordbrowseinfo);
if (file2 && file2->fileID && startOffset > 0 && (endOffset + 1) >= startOffset)
RecordFunction(object, file1->fileID, file2->fileID, startOffset, endOffset + 1);
}
void CBrowse_NewData(Object *object, CPrepFileInfo *file1, CPrepFileInfo *file2, SInt32 startOffset, SInt32 endOffset) {
char *namestr = NULL;
SInt32 flags = 0;
Boolean is_const = is_const_object(object);
CError_ASSERT(912, file1 && file1->recordbrowseinfo);
CError_ASSERT(913, object);
if (tk == ';')
endOffset++;
if (file2 && file2->fileID && startOffset > 0 && endOffset >= startOffset) {
HashNameNode *name = CBrowse_GetLinkName(object);
if (object->name != name)
namestr = name->name;
EmitStandardData(
is_const ? browseConstant : browseGlobal,
file1->fileID, file2->fileID,
startOffset, endOffset,
object->name->name, object->name->id,
namestr, name->id
);
if (!is_const) {
if (object->sclass == TK_STATIC)
flags |= kStatic;
AppendGListLong(&gBrowseData, flags);
}
}
}
void CBrowse_NewMacro(Macro *macro, CPrepFileInfo *file, SInt32 startOffset, SInt32 endOffset) {
CError_ASSERT(951, !file || (file->recordbrowseinfo && !macro->is_special));
if (file && file->fileID && startOffset > 0 && endOffset >= startOffset)
EmitStandardData(
browseMacro,
file->fileID, file->fileID,
startOffset, endOffset,
macro->name->name, macro->name->id,
NULL, -1
);
}
void CBrowse_NewTemplateClass(TemplClass *tmclass, CPrepFileInfo *file, SInt32 startOffset, SInt32 endOffset) {
CError_ASSERT(965, !file || file->recordbrowseinfo);
if (file && file->fileID && startOffset > 0 && endOffset >= startOffset) {
EmitStandardData(
browseTemplate,
file->fileID, file->fileID,
startOffset, endOffset,
tmclass->theclass.classname->name, tmclass->theclass.classname->id,
NULL, -1
);
AppendGListByte(&gBrowseData, templateClass);
}
}
void CBrowse_NewTemplateFunc(TemplateFunction *tmfunc) {
CError_ASSERT(979, !tmfunc->srcfile || tmfunc->srcfile->recordbrowseinfo);
if (tmfunc->srcfile && tmfunc->srcfile->fileID && tmfunc->startoffset > 0 && tmfunc->endoffset >= tmfunc->startoffset) {
EmitStandardData(
browseTemplate,
tmfunc->srcfile->fileID, tmfunc->srcfile->fileID,
tmfunc->startoffset, tmfunc->endoffset,
tmfunc->name->name, tmfunc->name->id,
NULL, -1
);
AppendGListByte(&gBrowseData, templateFunction);
}
}
static void RecordUndefinedMemberFunctions(void) {
int i;
int count;
Object **array;
COS_LockHandleHi(gMemberFuncList.data);
count = gMemberFuncList.size / sizeof(Object *);
array = (Object **) *gMemberFuncList.data;
for (i = 0; i < count; i++, array++) {
if (IS_TYPE_FUNC((*array)->type) && !(TYPE_FUNC((*array)->type)->flags & FUNC_DEFINED))
RecordFunction(*array, 0, 0, -1, -1);
}
COS_UnlockHandle(gMemberFuncList.data);
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,713 @@
#include "compiler/CMangler.h"
#include "compiler/CError.h"
#include "compiler/CInt64.h"
#include "compiler/CFunc.h"
#include "compiler/CParser.h"
#include "compiler/CTemplateTools.h"
#include "compiler/CompilerTools.h"
#include "compiler/enode.h"
#include "compiler/objects.h"
#include "compiler/scopes.h"
#include "compiler/templates.h"
#include "compiler/types.h"
#include "cos.h"
HashNameNode *constructor_name_node;
HashNameNode *destructor_name_node;
HashNameNode *asop_name_node;
// forward decls
static void CMangler_MangleClassName(TypeClass *tclass);
static void CMangler_MangleTypeAppend(Type *type, UInt32 qual);
static void CMangler_MangleArgs(FuncArg *args);
void CMangler_Setup(void) {
constructor_name_node = GetHashNameNodeExport("__ct");
destructor_name_node = GetHashNameNodeExport("__dt");
asop_name_node = GetHashNameNodeExport("__as");
}
HashNameNode *CMangler_BasicDtorName(void) {
return GetHashNameNodeExport("__dtb");
}
HashNameNode *CMangler_VBaseDtorName(void) {
return GetHashNameNodeExport("__dtv");
}
HashNameNode *CMangler_ArrayDtorName(void) {
return GetHashNameNodeExport("__dta");
}
HashNameNode *CMangler_SDeleteDtorName(void) {
return GetHashNameNodeExport("__dts");
}
HashNameNode *CMangler_DeleteDtorName(void) {
return GetHashNameNodeExport("__dt");
}
char *CMangler_GetOperator(HashNameNode *name) {
char *str;
if (name == asop_name_node)
return "operator=";
str = name->name;
if (!strcmp(str, "__nw")) return "operator new";
if (!strcmp(str, "__dl")) return "operator delete";
if (!strcmp(str, "__nwa")) return "operator new[]";
if (!strcmp(str, "__dla")) return "operator delete[]";
if (!strcmp(str, "__pl")) return "operator+";
if (!strcmp(str, "__mi")) return "operator-";
if (!strcmp(str, "__ml")) return "operator*";
if (!strcmp(str, "__dv")) return "operator/";
if (!strcmp(str, "__md")) return "operator%";
if (!strcmp(str, "__er")) return "operator^";
if (!strcmp(str, "__ad")) return "operator&";
if (!strcmp(str, "__or")) return "operator|";
if (!strcmp(str, "__co")) return "operator~";
if (!strcmp(str, "__nt")) return "operator!";
if (!strcmp(str, "__lt")) return "operator<";
if (!strcmp(str, "__gt")) return "operator>";
if (!strcmp(str, "__apl")) return "operator+=";
if (!strcmp(str, "__ami")) return "operator-=";
if (!strcmp(str, "__amu")) return "operator*=";
if (!strcmp(str, "__adv")) return "operator/=";
if (!strcmp(str, "__amd")) return "operator%=";
if (!strcmp(str, "__aer")) return "operator^=";
if (!strcmp(str, "__aad")) return "operator&=";
if (!strcmp(str, "__aor")) return "operator|=";
if (!strcmp(str, "__ls")) return "operator<<";
if (!strcmp(str, "__rs")) return "operator>>";
if (!strcmp(str, "__als")) return "operator<<=";
if (!strcmp(str, "__ars")) return "operator>>=";
if (!strcmp(str, "__eq")) return "operator==";
if (!strcmp(str, "__ne")) return "operator!=";
if (!strcmp(str, "__le")) return "operator<=";
if (!strcmp(str, "__ge")) return "operator>=";
if (!strcmp(str, "__aa")) return "operator&&";
if (!strcmp(str, "__oo")) return "operator||";
if (!strcmp(str, "__pp")) return "operator++";
if (!strcmp(str, "__mm")) return "operator--";
if (!strcmp(str, "__cm")) return "operator,";
if (!strcmp(str, "__rm")) return "operator->*";
if (!strcmp(str, "__rf")) return "operator*";
if (!strcmp(str, "__cl")) return "operator()";
if (!strcmp(str, "__vc")) return "operator[]";
return NULL;
}
HashNameNode *CMangler_OperatorName(short token) {
switch (token) {
case TK_NEW: return GetHashNameNodeExport("__nw");
case TK_DELETE: return GetHashNameNodeExport("__dl");
case TK_NEW_ARRAY: return GetHashNameNodeExport("__nwa");
case TK_DELETE_ARRAY: return GetHashNameNodeExport("__dla");
case '+': return GetHashNameNodeExport("__pl");
case '-': return GetHashNameNodeExport("__mi");
case '*': return GetHashNameNodeExport("__ml");
case '/': return GetHashNameNodeExport("__dv");
case '%': return GetHashNameNodeExport("__md");
case '^': return GetHashNameNodeExport("__er");
case '&': return GetHashNameNodeExport("__ad");
case '|': return GetHashNameNodeExport("__or");
case '~': return GetHashNameNodeExport("__co");
case '!': return GetHashNameNodeExport("__nt");
case '=': return asop_name_node;
case '<': return GetHashNameNodeExport("__lt");
case '>': return GetHashNameNodeExport("__gt");
case TK_ADD_ASSIGN: return GetHashNameNodeExport("__apl");
case TK_SUB_ASSIGN: return GetHashNameNodeExport("__ami");
case TK_MULT_ASSIGN: return GetHashNameNodeExport("__amu");
case TK_DIV_ASSIGN: return GetHashNameNodeExport("__adv");
case TK_MOD_ASSIGN: return GetHashNameNodeExport("__amd");
case TK_XOR_ASSIGN: return GetHashNameNodeExport("__aer");
case TK_AND_ASSIGN: return GetHashNameNodeExport("__aad");
case TK_OR_ASSIGN: return GetHashNameNodeExport("__aor");
case TK_SHL: return GetHashNameNodeExport("__ls");
case TK_SHR: return GetHashNameNodeExport("__rs");
case TK_SHL_ASSIGN: return GetHashNameNodeExport("__als");
case TK_SHR_ASSIGN: return GetHashNameNodeExport("__ars");
case TK_LOGICAL_EQ: return GetHashNameNodeExport("__eq");
case TK_LOGICAL_NE: return GetHashNameNodeExport("__ne");
case TK_LESS_EQUAL: return GetHashNameNodeExport("__le");
case TK_GREATER_EQUAL: return GetHashNameNodeExport("__ge");
case TK_LOGICAL_AND: return GetHashNameNodeExport("__aa");
case TK_LOGICAL_OR: return GetHashNameNodeExport("__oo");
case TK_INCREMENT: return GetHashNameNodeExport("__pp");
case TK_DECREMENT: return GetHashNameNodeExport("__mm");
case ',': return GetHashNameNodeExport("__cm");
case TK_ARROW_STAR: return GetHashNameNodeExport("__rm");
case TK_ARROW: return GetHashNameNodeExport("__rf");
case '(': return GetHashNameNodeExport("__cl");
case '[': return GetHashNameNodeExport("__vc");
default: return NULL;
}
}
HashNameNode *CMangler_VTableName(TypeClass *theclass) {
HashNameNode *name;
name_mangle_list.size = 0;
AppendGListName(&name_mangle_list, "__vt__");
CMangler_MangleClassName(theclass);
AppendGListByte(&name_mangle_list, 0);
COS_LockHandle(name_mangle_list.data);
name = GetHashNameNodeExport(*name_mangle_list.data);
COS_UnlockHandle(name_mangle_list.data);
return name;
}
HashNameNode *CMangler_RTTIObjectName(Type *type, UInt32 qual) {
HashNameNode *name;
name_mangle_list.size = 0;
AppendGListName(&name_mangle_list, "__RTTI__");
CMangler_MangleTypeAppend(type, qual);
AppendGListByte(&name_mangle_list, 0);
COS_LockHandle(name_mangle_list.data);
name = GetHashNameNodeExport(*name_mangle_list.data);
COS_UnlockHandle(name_mangle_list.data);
return name;
}
HashNameNode *CMangler_ThunkName(Object *vfunc, SInt32 this_delta, SInt32 return_delta, SInt32 ctoroffset) {
HashNameNode *linkname;
HashNameNode *name;
char buf[64];
linkname = CMangler_GetLinkName(vfunc);
name_mangle_list.size = 0;
if (return_delta == 0) {
if (ctoroffset < 0)
sprintf(buf, "_@%" PRId32 "@", -this_delta);
else
sprintf(buf, "_@%" PRId32 "@%" PRId32 "@", -this_delta, ctoroffset);
} else {
sprintf(buf, "_@%" PRId32 "@%" PRId32 "@%" PRId32 "@", -this_delta, ctoroffset, return_delta);
}
AppendGListName(&name_mangle_list, buf);
AppendGListID(&name_mangle_list, linkname->name + 1);
COS_LockHandle(name_mangle_list.data);
name = GetHashNameNodeExport(*name_mangle_list.data);
COS_UnlockHandle(name_mangle_list.data);
return name;
}
static void CMangler_CheckTemplateArguments(TemplArg *arg) {
ENode *expr;
while (arg) {
if (arg->pid.type == TPT_NONTYPE) {
expr = arg->data.paramdecl.expr;
CError_ASSERT(360, expr);
if (expr->rtype->type != TYPETEMPLDEPEXPR) {
switch (expr->type) {
case EINTCONST:
break;
case EOBJREF:
CMangler_GetLinkName(expr->data.objref);
break;
default:
CError_FATAL(383);
}
}
}
arg = arg->next;
}
}
static void CMangler_AppendTemplateArgumentList(TemplArg *arg) {
ENode *expr;
char buf[32];
AppendGListByte(&name_mangle_list, '<');
while (arg) {
if (arg->pid.type == TPT_NONTYPE) {
expr = arg->data.paramdecl.expr;
CError_ASSERT(409, expr);
if (expr->rtype->type != TYPETEMPLDEPEXPR) {
switch (expr->type) {
case EINTCONST:
CInt64_PrintDec(buf, expr->data.intval);
AppendGListName(&name_mangle_list, buf);
break;
case EOBJREF:
AppendGListByte(&name_mangle_list, '&');
AppendGListName(&name_mangle_list, CMangler_GetLinkName(expr->data.objref)->name);
break;
default:
CError_FATAL(452);
}
} else {
AppendGListByte(&name_mangle_list, 'T');
}
} else if (arg->pid.type == TPT_TYPE) {
CMangler_MangleTypeAppend(arg->data.typeparam.type, arg->data.typeparam.qual);
} else {
CError_ASSERT(467, arg->pid.type == TPT_TEMPLATE);
CMangler_MangleTypeAppend(arg->data.ttargtype, 0);
}
if (arg->next)
AppendGListByte(&name_mangle_list, ',');
arg = arg->next;
}
AppendGListByte(&name_mangle_list, '>');
}
HashNameNode *CMangler_TemplateInstanceName(HashNameNode *basename, TemplArg *args) {
HashNameNode *name;
CMangler_CheckTemplateArguments(args);
name_mangle_list.size = 0;
AppendGListName(&name_mangle_list, basename->name);
CMangler_AppendTemplateArgumentList(args);
AppendGListByte(&name_mangle_list, 0);
COS_LockHandle(name_mangle_list.data);
name = GetHashNameNodeExport(*name_mangle_list.data);
COS_UnlockHandle(name_mangle_list.data);
return name;
}
static void CMangler_MangleTypeName(char *str) {
char buf[16];
sprintf(buf, "%d", strlen(str));
AppendGListName(&name_mangle_list, buf);
AppendGListName(&name_mangle_list, str);
}
static void CMangler_MangleNameSpaceName(NameSpace *nspace, char *str) {
char *stack[10];
int stackp;
stack[0] = str;
stackp = 1;
while (nspace) {
if (nspace->name) {
stack[stackp++] = nspace->name->name;
if (stackp >= 9)
break;
}
nspace = nspace->parent;
}
if (stackp > 1) {
AppendGListByte(&name_mangle_list, 'Q');
AppendGListByte(&name_mangle_list, '0' + stackp);
}
while (--stackp >= 0)
CMangler_MangleTypeName(stack[stackp]);
}
static void CMangler_MangleClassName(TypeClass *tclass) {
if (!tclass->classname)
CMangler_MangleNameSpaceName(tclass->nspace->parent, "class");
else
CMangler_MangleNameSpaceName(tclass->nspace->parent, tclass->nspace->name->name);
}
static void CMangler_MangleQualifier(UInt32 qual) {
if (qual & Q_CONST)
AppendGListByte(&name_mangle_list, 'C');
if (qual & Q_VOLATILE)
AppendGListByte(&name_mangle_list, 'V');
}
static void CMangler_MangleTypeAppend(Type *type, UInt32 qual) {
char buf[16];
switch (type->type) {
case TYPEVOID:
CMangler_MangleQualifier(qual);
AppendGListByte(&name_mangle_list, 'v');
break;
case TYPEINT:
case TYPEFLOAT:
CMangler_MangleQualifier(qual);
switch (TYPE_INTEGRAL(type)->integral) {
case IT_BOOL:
AppendGListByte(&name_mangle_list, 'b');
return;
case IT_CHAR:
AppendGListByte(&name_mangle_list, 'c');
return;
case IT_WCHAR_T:
AppendGListByte(&name_mangle_list, 'w');
return;
case IT_UCHAR:
AppendGListName(&name_mangle_list, "Uc");
return;
case IT_SCHAR:
AppendGListName(&name_mangle_list, "Sc");
return;
case IT_SHORT:
AppendGListByte(&name_mangle_list, 's');
return;
case IT_USHORT:
AppendGListName(&name_mangle_list, "Us");
return;
case IT_INT:
AppendGListByte(&name_mangle_list, 'i');
return;
case IT_UINT:
AppendGListName(&name_mangle_list, "Ui");
return;
case IT_LONG:
AppendGListByte(&name_mangle_list, 'l');
return;
case IT_ULONG:
AppendGListName(&name_mangle_list, "Ul");
return;
case IT_LONGLONG:
AppendGListByte(&name_mangle_list, 'x');
return;
case IT_ULONGLONG:
AppendGListName(&name_mangle_list, "Ux");
return;
case IT_FLOAT:
AppendGListByte(&name_mangle_list, 'f');
return;
case IT_SHORTDOUBLE:
AppendGListByte(&name_mangle_list, 'D');
return;
case IT_DOUBLE:
AppendGListByte(&name_mangle_list, 'd');
return;
case IT_LONGDOUBLE:
AppendGListByte(&name_mangle_list, 'r');
return;
default:
CError_FATAL(619);
}
case TYPEENUM:
CMangler_MangleQualifier(qual);
if (!TYPE_ENUM(type)->enumname)
CMangler_MangleNameSpaceName(TYPE_ENUM(type)->nspace, "enum");
else
CMangler_MangleNameSpaceName(TYPE_ENUM(type)->nspace, TYPE_ENUM(type)->enumname->name);
break;
case TYPEPOINTER:
CMangler_MangleQualifier(TYPE_POINTER(type)->qual);
if (TYPE_POINTER(type)->qual & Q_REFERENCE)
AppendGListByte(&name_mangle_list, 'R');
else
AppendGListByte(&name_mangle_list, 'P');
CMangler_MangleTypeAppend(TYPE_POINTER(type)->target, qual);
break;
case TYPEMEMBERPOINTER:
if (TYPE_MEMBER_POINTER(type)->ty2->type != TYPECLASS) {
AppendGListName(&name_mangle_list, "3<T>");
} else {
CMangler_MangleQualifier(TYPE_MEMBER_POINTER(type)->qual);
AppendGListByte(&name_mangle_list, 'M');
CMangler_MangleClassName(TYPE_CLASS(TYPE_MEMBER_POINTER(type)->ty2));
CMangler_MangleTypeAppend(TYPE_MEMBER_POINTER(type)->ty1, qual);
}
break;
case TYPEARRAY:
AppendGListByte(&name_mangle_list, 'A');
if (TYPE_POINTER(type)->target->size) {
sprintf(buf, "%" PRId32 "", type->size / TYPE_POINTER(type)->target->size);
AppendGListName(&name_mangle_list, buf);
} else {
AppendGListByte(&name_mangle_list, '0');
}
AppendGListByte(&name_mangle_list, '_');
CMangler_MangleTypeAppend(TYPE_POINTER(type)->target, qual);
break;
case TYPEFUNC:
CMangler_MangleQualifier(qual);
AppendGListByte(&name_mangle_list, 'F');
CMangler_MangleArgs(TYPE_FUNC(type)->args);
AppendGListByte(&name_mangle_list, '_');
CMangler_MangleTypeAppend(TYPE_FUNC(type)->functype, TYPE_FUNC(type)->qual);
break;
case TYPESTRUCT:
CMangler_MangleQualifier(qual);
switch (TYPE_STRUCT(type)->stype) {
case STRUCT_VECTOR_UCHAR:
AppendGListName(&name_mangle_list, "XUc");
return;
case STRUCT_VECTOR_SCHAR:
AppendGListName(&name_mangle_list, "Xc");
return;
case STRUCT_VECTOR_BCHAR:
AppendGListName(&name_mangle_list, "XC");
return;
case STRUCT_VECTOR_USHORT:
AppendGListName(&name_mangle_list, "XUs");
return;
case STRUCT_VECTOR_SSHORT:
AppendGListName(&name_mangle_list, "Xs");
return;
case STRUCT_VECTOR_BSHORT:
AppendGListName(&name_mangle_list, "XS");
return;
case STRUCT_VECTOR_UINT:
AppendGListName(&name_mangle_list, "XUi");
return;
case STRUCT_VECTOR_SINT:
AppendGListName(&name_mangle_list, "Xi");
return;
case STRUCT_VECTOR_BINT:
AppendGListName(&name_mangle_list, "XI");
return;
case STRUCT_VECTOR_FLOAT:
AppendGListName(&name_mangle_list, "Xf");
return;
case STRUCT_VECTOR_PIXEL:
AppendGListName(&name_mangle_list, "Xp");
return;
}
if (TYPE_STRUCT(type)->name && !IsTempName(TYPE_STRUCT(type)->name)) {
CMangler_MangleTypeName(TYPE_STRUCT(type)->name->name);
return;
}
switch (TYPE_STRUCT(type)->stype) {
case STRUCT_TYPE_STRUCT:
AppendGListName(&name_mangle_list, "struct");
break;
case STRUCT_TYPE_UNION:
AppendGListName(&name_mangle_list, "union");
break;
case STRUCT_TYPE_CLASS:
AppendGListName(&name_mangle_list, "class");
break;
default:
CError_FATAL(701);
}
break;
case TYPECLASS:
CMangler_MangleQualifier(qual);
CMangler_MangleClassName(TYPE_CLASS(type));
break;
case TYPETEMPLATE:
AppendGListName(&name_mangle_list, "1T");
break;
default:
CError_FATAL(716);
}
}
void CMangler_MangleType(Type *type, UInt32 qual) {
name_mangle_list.size = 0;
CMangler_MangleTypeAppend(type, qual);
}
static void CMangler_MangleArgs(FuncArg *args) {
TypePointer ptr;
if (args) {
if (args->type) {
while (args) {
if (args != &elipsis && args != &oldstyle) {
if (args->type->type == TYPEPOINTER) {
ptr = *TYPE_POINTER(args->type);
ptr.qual &= ~(Q_CONST | Q_VOLATILE);
CMangler_MangleTypeAppend(TYPE(&ptr), args->qual);
} else {
CMangler_MangleTypeAppend(args->type, 0);
}
} else {
AppendGListByte(&name_mangle_list, 'e');
}
args = args->next;
}
} else {
AppendGListByte(&name_mangle_list, 'e');
}
} else {
AppendGListByte(&name_mangle_list, 'v');
}
}
static void CMangler_MangleFunction(Object *obj, NameSpace *nspace) {
TypeFunc *tfunc = TYPE_FUNC(obj->type);
FuncArg *arg = tfunc->args;
AppendGListName(&name_mangle_list, obj->name->name);
if (obj->u.func.inst) {
if (tfunc->flags & FUNC_CONVERSION)
CMangler_MangleTypeAppend(tfunc->functype, tfunc->qual);
CMangler_AppendTemplateArgumentList(obj->u.func.inst->args);
}
AppendGListName(&name_mangle_list, "__");
while (nspace && nspace->name == NULL)
nspace = nspace->parent;
if (nspace) {
CMangler_MangleNameSpaceName(nspace->parent, nspace->name->name);
if (nspace->theclass) {
if (obj->name == destructor_name_node) {
AppendGListName(&name_mangle_list, "Fv");
return;
}
if (arg) {
if (obj->name == constructor_name_node) {
arg = arg->next;
if (arg && (nspace->theclass->flags & CLASS_HAS_VBASES))
arg = arg->next;
} else {
if ((tfunc->flags & FUNC_METHOD) && !TYPE_METHOD(tfunc)->is_static) {
CMangler_MangleQualifier(arg->qual);
arg = arg->next;
}
}
}
}
}
AppendGListByte(&name_mangle_list, 'F');
CMangler_MangleArgs(arg);
if (obj->u.func.inst && copts.new_mangler) {
AppendGListByte(&name_mangle_list, '_');
CMangler_MangleTypeAppend(tfunc->functype, tfunc->qual);
}
}
HashNameNode *CMangler_ConversionFuncName(Type *type, UInt32 qual) {
HashNameNode *name;
if (CTemplTool_IsTemplateArgumentDependentType(type))
return GetHashNameNodeExport("__op");
name_mangle_list.size = 0;
AppendGListName(&name_mangle_list, "__op");
CMangler_MangleTypeAppend(type, qual);
AppendGListByte(&name_mangle_list, 0);
COS_LockHandle(name_mangle_list.data);
name = GetHashNameNodeExport(*name_mangle_list.data);
COS_UnlockHandle(name_mangle_list.data);
return name;
}
static HashNameNode *CMangler_MangleNameToUpper(char *str) {
HashNameNode *name;
name_mangle_list.size = 0;
while (*str) {
AppendGListByte(&name_mangle_list, toupper(*(str++)));
}
AppendGListByte(&name_mangle_list, 0);
COS_LockHandle(name_mangle_list.data);
name = GetHashNameNodeExport(*name_mangle_list.data);
COS_UnlockHandle(name_mangle_list.data);
return name;
}
static HashNameNode *CMangler_FunctionLinkName(Object *obj) {
HashNameNode *name;
NameSpace *nspace;
if (obj->u.func.inst)
CMangler_CheckTemplateArguments(obj->u.func.inst->args);
for (nspace = obj->nspace; nspace; nspace = nspace->parent) {
if (nspace->name)
break;
}
name_mangle_list.size = 0;
if (is_pascal_object(obj) && (!nspace || !nspace->theclass)) {
AppendGListData(&name_mangle_list, "_", 1);
AppendGListID(&name_mangle_list, obj->name->name);
} else if ((obj->qual & Q_MANGLE_NAME) && (strcmp("main", obj->name->name) || (obj->nspace != cscope_root))) {
AppendGListData(&name_mangle_list, "_", 1);
CMangler_MangleFunction(obj, nspace);
AppendGListByte(&name_mangle_list, 0);
} else {
AppendGListData(&name_mangle_list, "_", 1);
AppendGListID(&name_mangle_list, obj->name->name);
}
COS_LockHandle(name_mangle_list.data);
name = GetHashNameNodeExport(*name_mangle_list.data);
COS_UnlockHandle(name_mangle_list.data);
return name;
}
HashNameNode *CMangler_GetCovariantFunctionName(Object *dobj, TypeClass *theclass) {
HashNameNode *name;
name = CMangler_GetLinkName(dobj);
name_mangle_list.size = 0;
AppendGListName(&name_mangle_list, name->name);
AppendGListName(&name_mangle_list, "@@");
CMangler_MangleTypeAppend(TYPE(theclass), 0);
AppendGListByte(&name_mangle_list, 0);
COS_LockHandle(name_mangle_list.data);
name = GetHashNameNodeExport(*name_mangle_list.data);
COS_UnlockHandle(name_mangle_list.data);
return name;
}
static HashNameNode *CMangler_DataLinkName(Object *obj) {
NameSpace *nspace;
HashNameNode *name;
nspace = obj->nspace;
while (nspace && nspace->name == NULL)
nspace = nspace->parent;
name_mangle_list.size = 0;
AppendGListData(&name_mangle_list, "_", 1);
AppendGListName(&name_mangle_list, obj->name->name);
while (nspace && nspace->name == NULL)
nspace = nspace->parent;
if (nspace && (obj->qual & Q_MANGLE_NAME)) {
AppendGListName(&name_mangle_list, "__");
CMangler_MangleNameSpaceName(nspace->parent, nspace->name->name);
}
AppendGListByte(&name_mangle_list, 0);
COS_LockHandle(name_mangle_list.data);
name = GetHashNameNodeExport(*name_mangle_list.data);
COS_UnlockHandle(name_mangle_list.data);
return name;
}
HashNameNode *CMangler_GetLinkName(Object *obj) {
while (obj->datatype == DALIAS)
obj = obj->u.alias.object;
switch (obj->datatype) {
case DFUNC:
case DVFUNC:
if (!obj->u.func.linkname)
obj->u.func.linkname = CMangler_FunctionLinkName(obj);
return obj->u.func.linkname;
case DDATA:
if (!obj->u.data.linkname)
obj->u.data.linkname = CMangler_DataLinkName(obj);
return obj->u.data.linkname;
case DINLINEFUNC:
return CMangler_FunctionLinkName(obj);
case DLOCAL:
case DABSOLUTE:
case DLABEL:
return obj->name;
case DNONLAZYPTR:
if (!obj->u.toc.linkname)
obj->u.toc.linkname = CMangler_DataLinkName(obj);
return obj->u.toc.linkname;
default:
CError_FATAL(1110);
return NULL;
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -14,7 +14,7 @@
#include "compiler/CodeGen.h"
#include "compiler/CompilerTools.h"
#include "compiler/FuncLevelAsmPPC.h"
#include "compiler/IroPointerAnalysis.h"
#include "../Optimizer/IroPointerAnalysis.h"
#include "compiler/ObjGenMachO.h"
#include "compiler/objects.h"
#include "compiler/scopes.h"

View File

@@ -0,0 +1,676 @@
#include "compiler/CPreprocess.h"
#include "compiler/CError.h"
#include "compiler/CMachine.h"
#include "compiler/CParser.h"
#include "compiler/CPrep.h"
#include "compiler/CPrepTokenizer.h"
#include "compiler/CompilerTools.h"
#include "cos.h"
void CPrep_PreprocessDumpNewLine(void) {
if (copts.line_prepdump && pplist.data && filesp >= 0)
AppendGListData(&pplist, "\r", 1);
}
void CPrep_PreprocessDumpFileInfo(Boolean flag) {
char linebuf[512];
int size;
SInt16 tmp16;
SInt32 tmp32;
Str255 filename;
if (pplist.data && filesp >= 0) {
if (nlflag && flag && pplist.size > 0)
AppendGListName(&pplist, "\r");
if (copts.line_prepdump)
size = sprintf(linebuf, "#line % " PRId32 "\t\"", linenumber);
else
size = sprintf(linebuf, "/* #line % " PRId32 "\t\"", linenumber);
AppendGListData(&pplist, linebuf, size);
if (copts.fullpath_prepdump) {
if (prep_file->nameNode) {
AppendGListData(&pplist, prep_file->nameNode->name, strlen(prep_file->nameNode->name));
} else {
COS_FileGetPathName(linebuf, &prep_file->textfile, &tmp32);
AppendGListData(&pplist, linebuf, strlen(linebuf));
}
} else {
if (prep_file->nameNode) {
char *work = prep_file->nameNode->name + strlen(prep_file->nameNode->name);
while (work > prep_file->nameNode->name && !strchr("/\\:", work[-1]))
work--;
AppendGListData(&pplist, work, strlen(work));
} else {
COS_FileGetFSSpecInfo(&prep_file->textfile, &tmp16, &tmp32, filename);
AppendGListData(&pplist, &filename[1], filename[0]);
}
}
size = sprintf(linebuf, "\"\t/* stack depth % " PRId32 " */", filesp);
AppendGListData(&pplist, linebuf, size);
if (copts.line_prepdump && flag)
CPrep_PreprocessDumpNewLine();
nlflag = 1;
}
}
static void CPrep_DumpWString(UInt16 *str, short len) {
int divisor;
int i;
while (len--) {
if (*str < 32) {
AppendGListByte(&pplist, '\\');
switch (*str) {
case 7:
AppendGListByte(&pplist, 'a');
break;
case 8:
AppendGListByte(&pplist, 'b');
break;
case 27:
AppendGListByte(&pplist, 'e');
break;
case 12:
AppendGListByte(&pplist, 'f');
break;
case 10:
AppendGListByte(&pplist, 'n');
break;
case 13:
AppendGListByte(&pplist, 'r');
break;
case 9:
AppendGListByte(&pplist, 't');
break;
case 11:
AppendGListByte(&pplist, 'v');
break;
default:
if (*str >= 8)
AppendGListByte(&pplist, '0' + (*str / 8));
AppendGListByte(&pplist, '0' + (*str % 8));
}
} else if (*str > 255) {
AppendGListByte(&pplist, '\\');
AppendGListByte(&pplist, 'x');
divisor = 0x1000;
for (i = 0; i < 4; i++) {
AppendGListByte(&pplist, "0123456789ABCDEF"[(*str / divisor) % 16]);
divisor /= 16;
}
} else {
switch (*str) {
case '"':
case '\\':
AppendGListByte(&pplist, '\\');
default:
AppendGListByte(&pplist, *str);
}
}
str++;
}
}
static void CPrep_DumpString(UInt8 *str, short len) {
while (len--) {
if (*str < 32) {
AppendGListByte(&pplist, '\\');
switch (*str) {
case 7:
AppendGListByte(&pplist, 'a');
break;
case 8:
AppendGListByte(&pplist, 'b');
break;
case 12:
AppendGListByte(&pplist, 'f');
break;
case 10:
AppendGListByte(&pplist, 'n');
break;
case 13:
AppendGListByte(&pplist, 'r');
break;
case 9:
AppendGListByte(&pplist, 't');
break;
case 11:
AppendGListByte(&pplist, 'v');
break;
default:
if (*str >= 8)
AppendGListByte(&pplist, '0' + (*str / 8));
AppendGListByte(&pplist, '0' + (*str % 8));
}
} else {
switch (*str) {
case '"':
case '\\':
AppendGListByte(&pplist, '\\');
default:
AppendGListByte(&pplist, *str);
}
}
str++;
}
}
void CPrep_Preprocess(void) {
short innertoken;
short token;
char startToken;
char endToken;
int depth;
Boolean save_asmpoundcomment; // r16
Boolean save_cplusplus; // r15
char *p;
startToken = 0;
depth = 0;
if (InitGList(&pplist, 10000))
CError_NoMem();
nlflag = 0;
spaceskip = 0;
if ((token = lex())) {
do {
if (nlflag) {
if (!copts.line_prepdump)
AppendGListData(&pplist, "\r", 1);
} else {
if (spaceskip)
AppendGListByte(&pplist, ' ');
}
while (1) {
switch ((innertoken = token)) {
case '(':
case ')':
case '{':
case '}':
AppendGListByte(&pplist, token);
if (cprep_nostring) {
if (innertoken == startToken) {
depth++;
} else if (innertoken == endToken) {
if (--depth == 0) {
cprep_nostring = 0;
in_assembler = 0;
copts.cplusplus = save_cplusplus;
copts.asmpoundcomment = save_asmpoundcomment;
}
}
}
break;
case TK_INTCONST:
case TK_FLOATCONST:
if (tokenstacklevel > 0)
p = macropos;
else
p = prep_file_start + ts_current[-1].tokenoffset;
AppendGListData(&pplist, p, pos - p);
break;
case TK_IDENTIFIER:
AppendGListData(&pplist, tkidentifier->name, strlen(tkidentifier->name));
break;
case TK_AUTO:
AppendGListData(&pplist, "auto", 4);
break;
case TK_REGISTER:
AppendGListData(&pplist, "register", 8);
break;
case TK_STATIC:
AppendGListData(&pplist, "static", 6);
break;
case TK_EXTERN:
AppendGListData(&pplist, "extern", 6);
break;
case TK_TYPEDEF:
AppendGListData(&pplist, "typedef", 7);
break;
case TK_INLINE:
AppendGListData(&pplist, "inline", 6);
break;
case TK_VOID:
AppendGListData(&pplist, "void", 4);
break;
case TK_CHAR:
AppendGListData(&pplist, "char", 4);
break;
case TK_SHORT:
AppendGListData(&pplist, "short", 5);
break;
case TK_INT:
AppendGListData(&pplist, "int", 3);
break;
case TK_LONG:
AppendGListData(&pplist, "long", 4);
break;
case TK_FLOAT:
AppendGListData(&pplist, "float", 5);
break;
case TK_DOUBLE:
AppendGListData(&pplist, "double", 6);
break;
case TK_SIGNED:
AppendGListData(&pplist, "signed", 6);
break;
case TK_UNSIGNED:
AppendGListData(&pplist, "unsigned", 8);
break;
case TK_STRUCT:
AppendGListData(&pplist, "struct", 6);
break;
case TK_UNION:
AppendGListData(&pplist, "union", 5);
break;
case TK_ENUM:
AppendGListData(&pplist, "enum", 4);
break;
case TK_CLASS:
AppendGListData(&pplist, "class", 5);
break;
case TK_CONST:
AppendGListData(&pplist, "const", 5);
break;
case TK_VOLATILE:
AppendGListData(&pplist, "volatile", 8);
break;
case TK_PASCAL:
AppendGListData(&pplist, "pascal", 6);
break;
case TK_UU_FAR:
AppendGListData(&pplist, "__far", 5);
break;
case TK_ONEWAY:
AppendGListData(&pplist, "oneway", 6);
break;
case TK_IN:
AppendGListData(&pplist, "in", 2);
break;
case TK_OUT:
AppendGListData(&pplist, "out", 3);
break;
case TK_INOUT:
AppendGListData(&pplist, "inout", 5);
break;
case TK_BYCOPY:
AppendGListData(&pplist, "bycopy", 6);
break;
case TK_BYREF:
AppendGListData(&pplist, "byref", 5);
break;
case TK_ASM:
AppendGListData(&pplist, "asm", 3);
endToken = 0;
startToken = 0;
AppendGListByte(&pplist, ' ');
token = lex();
if (token == TK_VOLATILE || (token == TK_IDENTIFIER && !strcmp(tkidentifier->name, "__volatile__"))) {
AppendGListData(&pplist, "volatile", 8);
token = lex();
}
if (token) {
if (token < ' ' || token > 255)
continue;
AppendGListByte(&pplist, token);
if (token == '(') {
startToken = '(';
endToken = ')';
} else if (token == '{') {
startToken = '{';
endToken = '}';
} else {
continue;
}
cprep_nostring = 1;
in_assembler = 1;
depth = 1;
save_asmpoundcomment = copts.asmpoundcomment;
save_cplusplus = copts.cplusplus;
token = lex();
if (token == '"') {
AppendGListByte(&pplist, token);
copts.cplusplus = 0;
copts.asmpoundcomment = 1;
break;
} else if (token == 0) {
break;
}
continue;
}
break;
case TK_CASE:
AppendGListData(&pplist, "case", 4);
break;
case TK_DEFAULT:
AppendGListData(&pplist, "default", 7);
break;
case TK_IF:
AppendGListData(&pplist, "if", 2);
break;
case TK_ELSE:
AppendGListData(&pplist, "else", 4);
break;
case TK_SWITCH:
AppendGListData(&pplist, "switch", 6);
break;
case TK_WHILE:
AppendGListData(&pplist, "while", 5);
break;
case TK_DO:
AppendGListData(&pplist, "do", 2);
break;
case TK_FOR:
AppendGListData(&pplist, "for", 3);
break;
case TK_GOTO:
AppendGListData(&pplist, "goto", 4);
break;
case TK_CONTINUE:
AppendGListData(&pplist, "continue", 8);
break;
case TK_BREAK:
AppendGListData(&pplist, "break", 5);
break;
case TK_RETURN:
AppendGListData(&pplist, "return", 6);
break;
case TK_SIZEOF:
AppendGListData(&pplist, "sizeof", 6);
break;
case TK_CATCH:
AppendGListData(&pplist, "catch", 5);
break;
case TK_DELETE:
AppendGListData(&pplist, "delete", 6);
break;
case TK_FRIEND:
AppendGListData(&pplist, "friend", 6);
break;
case TK_NEW:
AppendGListData(&pplist, "new", 3);
break;
case TK_OPERATOR:
AppendGListData(&pplist, "operator", 8);
break;
case TK_PRIVATE:
AppendGListData(&pplist, "private", 7);
break;
case TK_PROTECTED:
AppendGListData(&pplist, "protected", 9);
break;
case TK_PUBLIC:
AppendGListData(&pplist, "public", 6);
break;
case TK_TEMPLATE:
AppendGListData(&pplist, "template", 8);
break;
case TK_THIS:
AppendGListData(&pplist, "this", 4);
break;
case TK_THROW:
AppendGListData(&pplist, "throw", 5);
break;
case TK_TRY:
AppendGListData(&pplist, "try", 3);
break;
case TK_VIRTUAL:
AppendGListData(&pplist, "virtual", 7);
break;
case TK_INHERITED:
AppendGListData(&pplist, "inherited", 9);
break;
case TK_CONST_CAST:
AppendGListData(&pplist, "const_cast", 10);
break;
case TK_DYNAMIC_CAST:
AppendGListData(&pplist, "dynamic_cast", 12);
break;
case TK_EXPLICIT:
AppendGListData(&pplist, "explicit", 8);
break;
case TK_MUTABLE:
AppendGListData(&pplist, "mutable", 7);
break;
case TK_NAMESPACE:
AppendGListData(&pplist, "namespace", 9);
break;
case TK_REINTERPRET_CAST:
AppendGListData(&pplist, "reinterpret_cast", 16);
break;
case TK_STATIC_CAST:
AppendGListData(&pplist, "static_cast", 11);
break;
case TK_USING:
AppendGListData(&pplist, "using", 5);
break;
case TK_WCHAR_T:
AppendGListData(&pplist, "wchar_t", 7);
break;
case TK_TYPENAME:
AppendGListData(&pplist, "typename", 8);
break;
case TK_TRUE:
AppendGListData(&pplist, "true", 4);
break;
case TK_FALSE:
AppendGListData(&pplist, "false", 5);
break;
case TK_TYPEID:
AppendGListData(&pplist, "typeid", 6);
break;
case TK_EXPORT:
AppendGListData(&pplist, "export", 6);
break;
case TK_UU_STDCALL:
AppendGListData(&pplist, "__stdcall", 9);
break;
case TK_UU_CDECL:
AppendGListData(&pplist, "__cdecl", 7);
break;
case TK_UU_FASTCALL:
AppendGListData(&pplist, "__fastcall", 10);
break;
case TK_UU_DECLSPEC:
AppendGListData(&pplist, "__declspec", 10);
break;
case TK_MULT_ASSIGN:
AppendGListData(&pplist, "*=", 2);
break;
case TK_DIV_ASSIGN:
AppendGListData(&pplist, "/=", 2);
break;
case TK_MOD_ASSIGN:
AppendGListData(&pplist, "%=", 2);
break;
case TK_ADD_ASSIGN:
AppendGListData(&pplist, "+=", 2);
break;
case TK_SUB_ASSIGN:
AppendGListData(&pplist, "-=", 2);
break;
case TK_SHL_ASSIGN:
AppendGListData(&pplist, "<<=", 3);
break;
case TK_SHR_ASSIGN:
AppendGListData(&pplist, ">>=", 3);
break;
case TK_AND_ASSIGN:
AppendGListData(&pplist, "&=", 2);
break;
case TK_XOR_ASSIGN:
AppendGListData(&pplist, "^=", 2);
break;
case TK_OR_ASSIGN:
AppendGListData(&pplist, "|=", 2);
break;
case TK_LOGICAL_OR:
AppendGListData(&pplist, "||", 2);
break;
case TK_LOGICAL_AND:
AppendGListData(&pplist, "&&", 2);
break;
case TK_LOGICAL_EQ:
AppendGListData(&pplist, "==", 2);
break;
case TK_LOGICAL_NE:
AppendGListData(&pplist, "!=", 2);
break;
case TK_LESS_EQUAL:
AppendGListData(&pplist, "<=", 2);
break;
case TK_GREATER_EQUAL:
AppendGListData(&pplist, ">=", 2);
break;
case TK_SHL:
AppendGListData(&pplist, "<<", 2);
break;
case TK_SHR:
AppendGListData(&pplist, ">>", 2);
break;
case TK_INCREMENT:
AppendGListData(&pplist, "++", 2);
break;
case TK_DECREMENT:
AppendGListData(&pplist, "--", 2);
break;
case TK_ARROW:
AppendGListData(&pplist, "->", 2);
break;
case TK_ELLIPSIS:
AppendGListData(&pplist, "...", 3);
break;
case TK_DOT_STAR:
AppendGListData(&pplist, ".*", 2);
break;
case TK_ARROW_STAR:
AppendGListData(&pplist, "->*", 3);
break;
case TK_COLON_COLON:
AppendGListData(&pplist, "::", 2);
break;
case TK_AT_INTERFACE:
AppendGListData(&pplist, "@interface", 10);
break;
case TK_AT_IMPLEMENTATION:
AppendGListData(&pplist, "@implementation", 15);
break;
case TK_AT_PROTOCOL:
AppendGListData(&pplist, "@protocol", 9);
break;
case TK_AT_END:
AppendGListData(&pplist, "@end", 4);
break;
case TK_AT_PRIVATE:
AppendGListData(&pplist, "@private", 8);
break;
case TK_AT_PROTECTED:
AppendGListData(&pplist, "@protected", 10);
break;
case TK_AT_PUBLIC:
AppendGListData(&pplist, "@public", 7);
break;
case TK_AT_CLASS:
AppendGListData(&pplist, "@class", 6);
break;
case TK_AT_SELECTOR:
AppendGListData(&pplist, "@selector", 9);
break;
case TK_AT_ENCODE:
AppendGListData(&pplist, "@encode", 7);
break;
case TK_AT_DEFS:
AppendGListData(&pplist, "@defs", 5);
break;
case TK_SELF:
AppendGListData(&pplist, "self", 4);
break;
case TK_SUPER:
AppendGListData(&pplist, "super", 5);
break;
case TK_BOOL:
if (!copts.cplusplus && copts.c9x)
AppendGListData(&pplist, "_Bool", 5);
else
AppendGListData(&pplist, "bool", 4);
break;
case TK_RESTRICT:
if (copts.c9x)
AppendGListData(&pplist, "restrict", 8);
else
AppendGListData(&pplist, "__restrict", 10);
break;
case TK_UU_VECTOR:
AppendGListData(&pplist, "__vector", 8);
break;
case TK_UU_TYPEOF_UU:
AppendGListData(&pplist, "__typeof__", 10);
break;
case TK_UU_ATTRIBUTE_UU:
AppendGListData(&pplist, "__attribute__", 13);
break;
case TK_UU_ALIGNOF_UU:
AppendGListData(&pplist, "__alignof__", 11);
break;
case TK_UU_UUIDOF:
AppendGListData(&pplist, "__uuidof", 8);
break;
case TK_U_COMPLEX:
AppendGListData(&pplist, "_Complex", 8);
break;
case TK_U_IMAGINARY:
AppendGListData(&pplist, "_Imaginary", 10);
break;
case TK_STRING:
if (ispascalstring) {
AppendGListData(&pplist, "\"\\p", 3);
CPrep_DumpString((UInt8 *) tkstring + 1, tksize - 1);
} else {
AppendGListByte(&pplist, '"');
CPrep_DumpString((UInt8 *) tkstring, tksize - 1);
}
AppendGListByte(&pplist, '"');
break;
case TK_STRING_WIDE:
AppendGListData(&pplist, "L\"", 2);
CPrep_DumpWString((UInt16 *) tkstring, (tksize / stwchar.size) - 1);
AppendGListByte(&pplist, '"');
break;
default:
if (token >= 32 && token <= 255)
AppendGListByte(&pplist, token);
else
CError_FATAL(563);
}
break;
}
CPrep_TokenStreamFlush();
nlflag = 0;
spaceskip = 0;
} while ((token = lex()));
}
AppendGListByte(&pplist, 0);
COS_ResizeHandle(pplist.data, pplist.size);
}

View File

@@ -0,0 +1,940 @@
#include "compiler/CRTTI.h"
#include "compiler/CClass.h"
#include "compiler/CDecl.h"
#include "compiler/CError.h"
#include "compiler/CExpr.h"
#include "compiler/CInit.h"
#include "compiler/CInt64.h"
#include "compiler/CMachine.h"
#include "compiler/CMangler.h"
#include "compiler/CParser.h"
#include "compiler/CScope.h"
#include "compiler/CompilerTools.h"
#include "compiler/objects.h"
#include "compiler/scopes.h"
#include "compiler/types.h"
#include "compiler/CPrepTokenizer.h"
#include "compiler/CPrep.h"
typedef struct Offset {
struct Offset *next;
SInt32 offset;
} Offset;
static Offset *crtti_offsets;
static OLinkList *crtti_olinks;
// forward decls
static Object *CRTTI_ConstructTypeInfoObject(Type *type, UInt32 qual);
typedef struct RTTISubClassList {
struct RTTISubClassList *next;
TypeClass *base;
SInt32 voffset;
} RTTISubClassList;
typedef struct RTTIBaseList {
struct RTTIBaseList *next;
TypeClass *base;
RTTISubClassList *subclasses;
SInt32 voffset;
short numsubclasses;
Boolean x12;
Boolean x13;
} RTTIBaseList;
static RTTIBaseList *CRTTI_CreateBaseList(TypeClass *tclass, TypeClass *tclassbase, RTTIBaseList *list, SInt32 voffset, Boolean flag) {
RTTIBaseList *scan;
ClassList *base;
Boolean flag27;
SInt32 newvoffset;
if (tclass != tclassbase) {
flag27 = 0;
for (scan = list; scan; scan = scan->next) {
if (scan->base == tclassbase) {
if (scan->voffset == voffset) {
if (!flag)
scan->x12 = 0;
flag27 = 0;
} else {
scan->x13 = 1;
flag27 = 1;
}
break;
}
}
if (!scan || flag27) {
scan = lalloc(sizeof(RTTIBaseList));
memclrw(scan, sizeof(RTTIBaseList));
scan->next = list;
list = scan;
scan->base = tclassbase;
scan->voffset = voffset;
scan->x12 = flag;
scan->x13 = flag27;
}
}
for (base = tclassbase->bases; base; base = base->next) {
if (base->is_virtual)
newvoffset = CClass_VirtualBaseOffset(tclass, base->base);
else
newvoffset = voffset + base->offset;
list = CRTTI_CreateBaseList(tclass, base->base, list, newvoffset, flag || base->access == ACCESSPRIVATE);
}
return list;
}
static void CRTTI_CreateSubClassList(TypeClass *tclass, RTTIBaseList *baselist, TypeClass *tclassbase, SInt32 voffset, Boolean flag) {
ClassList *base;
RTTISubClassList *scan;
SInt32 newvoffset;
if (baselist->base != tclassbase) {
for (scan = baselist->subclasses; scan; scan = scan->next) {
if (scan->base == tclassbase && scan->voffset == voffset)
break;
}
if (!scan) {
scan = lalloc(sizeof(RTTISubClassList));
scan->next = baselist->subclasses;
baselist->subclasses = scan;
scan->base = tclassbase;
scan->voffset = voffset;
baselist->numsubclasses++;
}
}
for (base = tclassbase->bases; base; base = base->next) {
if (base->access == ACCESSPUBLIC) {
if (base->is_virtual) {
if (!flag)
continue;
newvoffset = CClass_VirtualBaseOffset(tclass, base->base);
} else {
newvoffset = voffset + base->offset;
}
CRTTI_CreateSubClassList(tclass, baselist, base->base, newvoffset, flag);
}
}
}
static Object *CRTTI_CreateBaseListObject(TypeClass *tclass) {
RTTIBaseList *baselist;
OLinkList *refs;
Object *object;
SInt32 *buf;
SInt32 size;
short count1;
short count2;
short total;
OLinkList *ref;
RTTIBaseList *scan;
RTTISubClassList *subclass;
SInt32 *work;
SInt32 *work2;
baselist = CRTTI_CreateBaseList(tclass, tclass, NULL, 0, 0);
if (!baselist)
return NULL;
count1 = 0;
count2 = 0;
total = 0;
for (scan = baselist; scan; scan = scan->next) {
if (scan->x13 || scan->x12) {
CRTTI_CreateSubClassList(tclass, scan, scan->base, scan->voffset, scan->x13 == 0);
if (scan->numsubclasses) {
total += scan->numsubclasses;
count2++;
}
} else {
count1++;
}
}
if (!count1 && !count2)
return NULL;
size = (count1 + total) * 8 + count2 * 12 + 4;
buf = lalloc(size);
memclrw(buf, size);
object = CParser_NewCompilerDefDataObject();
object->name = CParser_GetUniqueName();
object->type = CDecl_NewStructType(size, 4);
object->qual = Q_CONST;
object->sclass = TK_STATIC;
refs = NULL;
work = buf;
if (count1) {
for (scan = baselist; scan; scan = scan->next) {
if (!scan->x12 && !scan->x13) {
ref = lalloc(sizeof(OLinkList));
ref->next = refs;
refs = ref;
ref->obj = CRTTI_ConstructTypeInfoObject(TYPE(scan->base), 0);
ref->offset = ((char *) work) - ((char *) buf);
ref->somevalue = 0;
work[1] = CTool_EndianConvertWord32(scan->voffset);
work += 2;
}
}
}
if (count2) {
for (scan = baselist; scan; scan = scan->next) {
if (scan->numsubclasses) {
ref = lalloc(sizeof(OLinkList));
ref->next = refs;
refs = ref;
ref->obj = CRTTI_ConstructTypeInfoObject(TYPE(scan->base), 0);
ref->offset = ((char *) work) - ((char *) buf);
ref->somevalue = 0;
work[1] = CTool_EndianConvertWord32(scan->voffset | 0x80000000);
work[2] = CTool_EndianConvertWord32(scan->numsubclasses);
work2 = work + 3;
for (subclass = scan->subclasses; subclass; subclass = subclass->next) {
ref = lalloc(sizeof(OLinkList));
ref->next = refs;
refs = ref;
ref->obj = CRTTI_ConstructTypeInfoObject(TYPE(subclass->base), 0);
ref->offset = ((char *) work2) - ((char *) buf);
ref->somevalue = 0;
work2[1] = CTool_EndianConvertWord32(subclass->voffset);
work2 += 2;
}
work = work2;
}
}
}
CInit_DeclareData(object, buf, refs, object->type->size);
return object;
}
static Object *CRTTI_ConstructTypeInfoObject(Type *type, UInt32 qual) {
Object *baselistobj;
Object *nameobj;
HashNameNode *rttiname;
OLinkList *refs;
char *namestr;
int namelen;
Object *object;
NameSpaceObjectList *list;
TypePointer tptr_copy;
TypeMemberPointer tmemptr_copy;
UInt32 data[2];
switch (type->type) {
case TYPEPOINTER:
if (TPTR_QUAL(type) & (Q_CONST | Q_VOLATILE)) {
tptr_copy = *TYPE_POINTER(type);
tptr_copy.qual &= ~(Q_CONST | Q_VOLATILE);
type = TYPE(&tptr_copy);
}
break;
case TYPEMEMBERPOINTER:
if (TYPE_MEMBER_POINTER(type)->qual & (Q_CONST | Q_VOLATILE)) {
tmemptr_copy = *TYPE_MEMBER_POINTER(type);
tmemptr_copy.qual &= ~(Q_CONST | Q_VOLATILE);
type = TYPE(&tmemptr_copy);
}
break;
default:
qual = 0;
}
if (IS_TYPE_CLASS(type) && type->size == 0) {
CDecl_CompleteType(type);
if (!(TYPE_CLASS(type)->flags & CLASS_COMPLETED))
CError_Error(CErrorStr136, type, 0);
}
rttiname = CMangler_RTTIObjectName(type, qual);
list = CScope_FindName(cscope_root, rttiname);
if (!list || (object = OBJECT(list->object))->otype != OT_OBJECT || object->datatype != DDATA) {
namestr = CError_GetTypeName(type, qual, 0);
namelen = strlen(namestr) + 1;
nameobj = CInit_DeclareString(namestr, namelen, 0, 0);
baselistobj = NULL;
if (IS_TYPE_CLASS(type))
baselistobj = CRTTI_CreateBaseListObject(TYPE_CLASS(type));
memclrw(data, sizeof(data));
object = CParser_NewCompilerDefDataObject();
object->name = rttiname;
object->type = CDecl_NewStructType(sizeof(data), 4);
object->qual = Q_CONST;
object->sclass = TK_STATIC;
refs = lalloc(sizeof(OLinkList));
refs->next = NULL;
refs->obj = nameobj;
refs->offset = 0;
refs->somevalue = 0;
if (baselistobj) {
refs->next = lalloc(sizeof(OLinkList));
refs->next->next = NULL;
refs->next->obj = baselistobj;
refs->next->offset = 4;
refs->next->somevalue = 0;
}
CScope_AddGlobalObject(object);
CInit_DeclareData(object, data, refs, object->type->size);
}
return object;
}
static void CRTTI_ConstructVTableHeader(TypeClass *tclass1, TypeClass *tclass2, Object *typeinfoObj, char *data, SInt32 offset, SInt32 voffset) {
ClassList *base;
Offset *o;
OLinkList *olink;
SInt32 tmp;
SInt32 newoffset;
SInt32 newvoffset;
if (tclass2->vtable->owner == tclass2) {
for (o = crtti_offsets; o; o = o->next) {
if (o->offset == voffset)
break;
}
if (!o) {
o = lalloc(sizeof(Offset));
o->next = crtti_offsets;
o->offset = voffset;
crtti_offsets = o;
olink = lalloc(sizeof(OLinkList));
olink->next = crtti_olinks;
olink->obj = typeinfoObj;
olink->offset = voffset;
olink->somevalue = 0;
crtti_olinks = olink;
*((SInt32 *) (data + voffset + 4)) = CTool_EndianConvertWord32(-offset);
} else {
tmp = *((SInt32 *) (data + voffset + 4));
CError_ASSERT(404, tmp == CTool_EndianConvertWord32(-offset));
}
}
for (base = tclass2->bases; base; base = base->next) {
if (base->base->vtable) {
if (base->is_virtual) {
newoffset = CClass_VirtualBaseOffset(tclass1, base->base);
newvoffset = CClass_VirtualBaseVTableOffset(tclass1, base->base);
} else {
newoffset = offset + base->offset;
newvoffset = voffset + base->voffset;
}
CRTTI_ConstructVTableHeader(tclass1, base->base, typeinfoObj, data, newoffset, newvoffset);
}
}
}
OLinkList *CRTTI_ConstructVTableHeaders(TypeClass *tclass, void *data, OLinkList *links) {
crtti_offsets = NULL;
crtti_olinks = links;
CRTTI_ConstructVTableHeader(
tclass, tclass,
CRTTI_ConstructTypeInfoObject(TYPE(tclass), 0),
data, 0, 0);
return crtti_olinks;
}
static Type *CRTTI_FindTypeInfoType(void) {
NameSpace *nspace;
NameSpaceObjectList *list;
Type *type;
if ((list = CScope_FindName(cscope_root, GetHashNameNodeExport("std"))) && list->object->otype == OT_NAMESPACE)
nspace = OBJ_NAMESPACE(list->object)->nspace;
else
nspace = cscope_root;
type = CScope_GetLocalTagType(nspace, GetHashNameNodeExport("type_info"));
if (type && IS_TYPE_CLASS(type) && type->size)
return type;
CError_Error(CErrorStr140, "::std::type_info");
return TYPE(&stchar);
}
ENode *CRTTI_ParseTypeID(void) {
ENode *expr;
Type *type;
Type *typeinfoType;
UInt32 qual;
if (!copts.RTTI)
CError_Warning(CErrorStr257);
typeinfoType = CRTTI_FindTypeInfoType();
if (lex() != '(') {
CError_Error(CErrorStr114);
return nullnode();
}
tk = lex();
if ((type = CParser_ParseTypeID(&qual, NULL))) {
if (tk != ')')
CError_ErrorSkip(CErrorStr115);
else
tk = lex();
if (IS_TYPE_REFERENCE(type))
type = TPTR_TARGET(type);
} else {
expr = s_expression();
if (tk != ')')
CError_ErrorSkip(CErrorStr115);
else
tk = lex();
type = expr->rtype;
qual = ENODE_QUALS(expr);
if (IS_TYPE_REFERENCE(type))
type = TPTR_TARGET(type);
if (IS_TYPE_CLASS(type) && TYPE_CLASS(type)->vtable) {
expr = funccallexpr(
Rgtid_func,
getnodeaddress(expr, 0),
intconstnode(TYPE(&stsignedlong), TYPE_CLASS(type)->vtable->offset),
NULL,
NULL);
expr->rtype = CDecl_NewPointerType(typeinfoType);
expr = makemonadicnode(expr, EINDIRECT);
expr->rtype = typeinfoType;
expr->flags = ENODE_FLAG_CONST;
return expr;
}
}
expr = create_objectrefnode(CRTTI_ConstructTypeInfoObject(type, qual));
expr = makemonadicnode(expr, EINDIRECT);
expr->rtype = typeinfoType;
expr->flags = ENODE_FLAG_CONST;
return expr;
}
static void CRTTI_ConstCastQualCheck(UInt32 qual1, UInt32 qual2) {
if (
((qual1 & Q_CONST) && !(qual2 & Q_CONST)) ||
((qual1 & Q_VOLATILE) && !(qual2 & Q_VOLATILE))
)
CError_Error(CErrorStr258);
}
static void CRTTI_ConstCastCheck(Type *type1, UInt32 qual1, Type *type2, UInt32 qual2) {
Boolean flag = 1;
if (IS_TYPE_REFERENCE(type2)) {
type2 = TPTR_TARGET(type2);
flag = 0;
}
while (1) {
if (type1->type != type2->type)
break;
switch (type1->type) {
case TYPEPOINTER:
if (!flag)
CRTTI_ConstCastQualCheck(TPTR_QUAL(type1), TPTR_QUAL(type2));
type1 = TPTR_TARGET(type1);
type2 = TPTR_TARGET(type2);
flag = 0;
continue;
case TYPEMEMBERPOINTER:
if (!flag)
CRTTI_ConstCastQualCheck(TYPE_MEMBER_POINTER(type1)->qual, TYPE_MEMBER_POINTER(type2)->qual);
type1 = TYPE_MEMBER_POINTER(type1)->ty1;
type2 = TYPE_MEMBER_POINTER(type2)->ty1;
flag = 0;
continue;
}
break;
}
if (!flag && !IS_TYPE_FUNC(type1) && !IS_TYPE_FUNC(type2))
CRTTI_ConstCastQualCheck(CParser_GetCVTypeQualifiers(type1, qual1), CParser_GetCVTypeQualifiers(type2, qual2));
}
static ENode *CRTTI_ParseCast(DeclInfo *di) {
ENode *expr;
if (lex() != '<') {
CError_Error(CErrorStr230);
return NULL;
}
tk = lex();
memclrw(di, sizeof(DeclInfo));
CParser_GetDeclSpecs(di, 0);
scandeclarator(di);
if (di->name)
CError_Error(CErrorStr164);
if (tk != '>') {
CError_Error(CErrorStr231);
return NULL;
}
if (lex() != '(') {
CError_Error(CErrorStr114);
return NULL;
}
tk = lex();
expr = s_expression();
if (!IS_TYPE_REFERENCE(di->thetype))
expr = pointer_generation(expr);
if (tk != ')') {
CError_Error(CErrorStr115);
return NULL;
}
tk = lex();
return expr;
}
static void CRTTI_IncompleteCheck(Type *type) {
if (IS_TYPE_POINTER_ONLY(type))
type = TPTR_TARGET(type);
if (IS_TYPE_CLASS(type) && type->size == 0) {
CDecl_CompleteType(type);
if (!(TYPE_CLASS(type)->flags & CLASS_COMPLETED))
CError_Error(CErrorStr136, type, 0);
}
}
static Boolean CRTTI_IsSameType(Type *a, Type *b) {
while (1) {
if (a->type != b->type)
return 0;
switch (a->type) {
case TYPEVOID:
return 1;
case TYPEINT:
case TYPEFLOAT:
case TYPEENUM:
case TYPESTRUCT:
return a == b;
case TYPEPOINTER:
a = TPTR_TARGET(a);
b = TPTR_TARGET(b);
continue;
default:
return is_typesame(a, b);
}
}
}
static ENode *CRTTI_UniversalCast(ENode *expr, Type *type, UInt32 qual, UInt8 mode) {
// type/qual are the target type
Boolean isSimpleCast;
Boolean needsTypcon;
Boolean failed;
if (ENODE_IS(expr, EOBJLIST))
return CExpr_AssignmentPromotion(expr, type, qual & (Q_CONST | Q_VOLATILE), 1);
isSimpleCast = needsTypcon = failed = 0;
switch (type->type) {
case TYPEINT:
case TYPEENUM:
if (mode == 2 && IS_TYPE_POINTER_ONLY(expr->rtype) && type != TYPE(&stbool))
failed = 1;
break;
case TYPEPOINTER:
if (TPTR_QUAL(type) & Q_REFERENCE) {
if (
!CRTTI_IsSameType(TPTR_TARGET(type), expr->rtype) &&
mode == 2 &&
!(
IS_TYPE_CLASS(TPTR_TARGET(type)) &&
IS_TYPE_CLASS(expr->rtype) &&
(
CClass_IsBaseClass(TYPE_CLASS(TPTR_TARGET(type)), TYPE_CLASS(expr->rtype), NULL, 0, 1) ||
CClass_IsBaseClass(TYPE_CLASS(expr->rtype), TYPE_CLASS(TPTR_TARGET(type)), NULL, 0, 1)
)
)
)
{
failed = 1;
}
} else if (IS_TYPE_POINTER_ONLY(expr->rtype)) {
if (
mode == 3 ||
CRTTI_IsSameType(type, expr->rtype) ||
IS_TYPE_VOID(TPTR_TARGET(type)) ||
IS_TYPE_VOID(TPTR_TARGET(expr->rtype))
)
{
isSimpleCast = needsTypcon = 1;
}
else if (
mode == 2 &&
!(
IS_TYPE_CLASS(TPTR_TARGET(type)) &&
IS_TYPE_CLASS(TPTR_TARGET(expr->rtype)) &&
(
CClass_IsBaseClass(TYPE_CLASS(TPTR_TARGET(type)), TYPE_CLASS(TPTR_TARGET(expr->rtype)), NULL, 0, 1) ||
CClass_IsBaseClass(TYPE_CLASS(TPTR_TARGET(expr->rtype)), TYPE_CLASS(TPTR_TARGET(type)), NULL, 0, 1)
)
)
)
{
failed = 1;
}
} else {
if (IS_TYPE_ENUM(expr->rtype))
expr->rtype = TYPE_ENUM(expr->rtype)->enumtype;
if (IS_TYPE_INT(expr->rtype)) {
if (ENODE_IS(expr, EINTCONST) && CInt64_IsZero(&expr->data.intval)) {
isSimpleCast = 1;
break;
}
if (mode != 2)
break;
}
if (IS_TYPE_CLASS(expr->rtype)) {
if (mode == 2)
break;
}
failed = 1;
}
break;
}
if (failed) {
CError_Error(CErrorStr247, expr->rtype, ENODE_QUALS(expr), type, qual);
return expr;
}
if (isSimpleCast) {
if (needsTypcon && ENODE_IS(expr, EINDIRECT) && (copts.pointercast_lvalue || !copts.ANSIstrict))
expr = makemonadicnode(expr, ETYPCON);
expr->rtype = type;
expr->flags = qual & ENODE_FLAG_QUALS;
return expr;
}
if (copts.old_argmatch)
return do_typecast(expr, type, qual);
return CExpr_Convert(expr, type, qual, 1, 1);
}
ENode *CRTTI_Parse_dynamic_cast(void) {
Boolean isRef;
ENode *expr;
TypeClass *srcclass;
TypeClass *destclass;
ENode *typeinfo;
DeclInfo di;
expr = CRTTI_ParseCast(&di);
if (!expr)
return nullnode();
if (!copts.RTTI)
CError_Warning(CErrorStr257);
CRTTI_ConstCastCheck(expr->rtype, expr->flags, di.thetype, di.qual);
if (!IS_TYPE_POINTER_ONLY(di.thetype)) {
CError_Error(CErrorStr164);
return expr;
}
isRef = (TPTR_QUAL(di.thetype) & Q_REFERENCE) != 0;
if (IS_TYPE_CLASS(TPTR_TARGET(di.thetype))) {
destclass = TYPE_CLASS(TPTR_TARGET(di.thetype));
CDecl_CompleteType(TYPE(destclass));
if (!(destclass->flags & CLASS_COMPLETED)) {
CError_Error(CErrorStr136, destclass, 0);
return expr;
}
} else if (!IS_TYPE_VOID(TPTR_TARGET(di.thetype))) {
CError_Error(CErrorStr164);
return expr;
} else {
destclass = NULL;
}
if (isRef) {
if (!IS_TYPE_CLASS(expr->rtype)) {
CError_Error(CErrorStr164);
return expr;
}
srcclass = TYPE_CLASS(expr->rtype);
if (destclass) {
if (srcclass == destclass || CClass_IsBaseClass(srcclass, destclass, NULL, 0, 1))
return do_typecast(expr, di.thetype, di.qual);
}
expr = getnodeaddress(expr, 1);
} else {
if (!IS_TYPE_POINTER_ONLY(expr->rtype) || !IS_TYPE_CLASS(TPTR_TARGET(expr->rtype))) {
CError_Error(CErrorStr164);
return expr;
}
srcclass = TYPE_CLASS(TPTR_TARGET(expr->rtype));
if (destclass) {
if (srcclass == destclass || CClass_IsBaseClass(srcclass, destclass, NULL, 0, 1))
return do_typecast(expr, di.thetype, di.qual);
}
}
if (!(srcclass->flags & CLASS_COMPLETED)) {
CError_Error(CErrorStr136, srcclass, 0);
return expr;
}
if (!srcclass->vtable) {
CError_Error(CErrorStr164);
return expr;
}
if (srcclass->sominfo) {
CError_Error(CErrorStr164);
return expr;
}
if (destclass) {
typeinfo = create_objectrefnode(CRTTI_ConstructTypeInfoObject(TYPE(destclass), 0));
if (destclass->sominfo) {
CError_Error(CErrorStr164);
return expr;
}
} else {
typeinfo = nullnode();
}
expr = CExpr_FuncCallSix(
Rdync_func,
expr,
intconstnode(TYPE(&stsignedlong), srcclass->vtable->offset),
typeinfo,
create_objectrefnode(CRTTI_ConstructTypeInfoObject(TYPE(srcclass), 0)),
intconstnode(TYPE(&stsignedshort), isRef),
NULL
);
if (isRef) {
expr->rtype = CDecl_NewPointerType(TYPE(destclass));
expr = makemonadicnode(expr, EINDIRECT);
expr->rtype = TYPE(destclass);
} else {
expr->rtype = di.thetype;
}
expr->flags = di.qual & ENODE_FLAG_QUALS;
return expr;
}
ENode *CRTTI_Parse_static_cast(void) {
ENode *expr;
DeclInfo di;
expr = CRTTI_ParseCast(&di);
if (!expr)
return nullnode();
CRTTI_ConstCastCheck(expr->rtype, expr->flags, di.thetype, di.qual);
if (IS_TYPE_REFERENCE(di.thetype)) {
if (IS_TYPE_CLASS(expr->rtype) && CExpr_CanImplicitlyConvert(expr, di.thetype, di.qual)) {
expr = CExpr_Convert(expr, di.thetype, di.qual, 0, 1);
CError_ASSERT(959, IS_TYPE_POINTER_ONLY(expr->rtype));
expr = makemonadicnode(expr, EINDIRECT);
expr->rtype = TPTR_TARGET(di.thetype);
expr->flags = di.qual & ENODE_FLAG_QUALS;
return expr;
}
} else {
if (CExpr_CanImplicitlyConvert(expr, di.thetype, di.qual))
return CExpr_Convert(expr, di.thetype, di.qual, 1, 1);
}
if (!IS_TYPE_VOID(di.thetype) && !(IS_TYPE_POINTER_ONLY(expr->rtype) && IS_TYPE_VOID(TPTR_TARGET(expr->rtype)))) {
CRTTI_IncompleteCheck(di.thetype);
CRTTI_IncompleteCheck(expr->rtype);
}
return CRTTI_UniversalCast(expr, di.thetype, di.qual, 2);
}
ENode *CRTTI_Parse_reinterpret_cast(void) {
ENode *expr;
Type *origtype;
ENode *lvalue;
DeclInfo di;
expr = CRTTI_ParseCast(&di);
if (!expr)
return nullnode();
CRTTI_ConstCastCheck(expr->rtype, expr->flags, di.thetype, di.qual);
if (IS_TYPE_REFERENCE(di.thetype)) {
lvalue = CExpr_LValue(expr, 0, 1);
if (!ENODE_IS(lvalue, EINDIRECT))
return lvalue;
lvalue->data.monadic->rtype = CDecl_NewPointerType(lvalue->rtype);
expr = lvalue->data.monadic;
origtype = di.thetype;
di.thetype = CDecl_NewPointerType(TPTR_TARGET(di.thetype));
} else {
origtype = NULL;
}
switch (di.thetype->type) {
case TYPEINT:
switch (expr->rtype->type) {
case TYPEMEMBERPOINTER:
case TYPEPOINTER:
expr = do_typecast(expr, di.thetype, di.qual);
break;
default:
CError_Error(CErrorStr164);
}
break;
case TYPEPOINTER:
switch (expr->rtype->type) {
case TYPEINT:
case TYPEENUM:
if (origtype)
di.thetype = origtype;
expr = do_typecast(expr, di.thetype, di.qual);
break;
case TYPEPOINTER:
expr = makemonadicnode(expr, ETYPCON);
expr->rtype = di.thetype;
expr->flags = di.qual & ENODE_FLAG_QUALS;
break;
default:
CError_Error(CErrorStr164);
}
break;
case TYPEMEMBERPOINTER:
if (IS_TYPE_MEMBERPOINTER(expr->rtype)) {
if (IS_TYPE_FUNC(TYPE_MEMBER_POINTER(di.thetype)->ty1)) {
if (IS_TYPE_FUNC(TYPE_MEMBER_POINTER(expr->rtype)->ty1)) {
expr->rtype = di.thetype;
expr->flags = di.qual & ENODE_FLAG_QUALS;
break;
}
} else {
if (!IS_TYPE_FUNC(TYPE_MEMBER_POINTER(expr->rtype)->ty1)) {
expr->rtype = di.thetype;
expr->flags = di.qual & ENODE_FLAG_QUALS;
break;
}
}
}
expr = do_typecast(expr, di.thetype, di.qual);
break;
default:
CError_Error(CErrorStr164);
}
if (origtype && IS_TYPE_POINTER_ONLY(expr->rtype)) {
expr = makemonadicnode(expr, EINDIRECT);
expr->rtype = TPTR_TARGET(di.thetype);
}
return expr;
}
ENode *CRTTI_Parse_const_cast(void) {
DeclInfo di;
ENode *expr;
if (!(expr = CRTTI_ParseCast(&di)))
return nullnode();
if (IS_TYPE_POINTER_ONLY(di.thetype)) {
if (TPTR_QUAL(di.thetype) & Q_REFERENCE) {
if (!iscpp_typeequal(TPTR_TARGET(di.thetype), expr->rtype))
CError_Error(CErrorStr164);
if (ENODE_IS(expr, EINDIRECT)) {
expr->rtype = TPTR_TARGET(di.thetype);
expr->flags = di.qual & ENODE_FLAG_QUALS;
} else {
CError_Error(CErrorStr142);
}
} else {
if (!iscpp_typeequal(di.thetype, expr->rtype))
CError_Error(CErrorStr164);
expr = do_typecast(expr, di.thetype, di.qual);
}
} else if (IS_TYPE_MEMBERPOINTER(di.thetype)) {
if (!iscpp_typeequal(di.thetype, expr->rtype))
CError_Error(CErrorStr164);
expr = do_typecast(expr, di.thetype, di.qual);
} else {
if (!is_typesame(di.thetype, expr->rtype))
CError_Error(CErrorStr164);
else
expr = do_typecast(expr, di.thetype, di.qual);
}
return expr;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff