diff --git a/CError.c b/CError.c deleted file mode 100644 index 5179463..0000000 --- a/CError.c +++ /dev/null @@ -1,319 +0,0 @@ -#include "CError.h" -#include "CompilerTools.h" - -// TODO MOVE ME -extern char *CMangler_GetOperator(StringNode *str); -extern jmp_buf errorreturn; -extern unsigned char cprep_nomem_exit; -extern unsigned char anyerrors; -extern unsigned char fatalerrors; -extern char string[256]; -// TODO MOVE ME - -Token *cerror_locktoken; -static Token *cerror_token; -static short cerror_errorcount; -static int cerror_lasterrorline; -// cerror_synchdata -// cerror_synchoffset -int CError_BreakPointcount; - -void CError_Init() { - cerror_errorcount = 0; - cerror_lasterrorline = -1; - cerror_token = 0; - cerror_locktoken = 0; -} - -void CError_SetErrorToken(Token *token) { - if (token && token->x4) - cerror_token = token; -} - -void CError_SetNullErrorToken() { - cerror_token = (Token *) -1; -} - -void CError_LockErrorPos(Token *token, Token **saved) { - *saved = cerror_locktoken; - if (token && token->x4) - cerror_locktoken = token; -} - -void CError_UnlockErrorPos(Token **saved) { - cerror_locktoken = *saved; -} - -void CError_ResetErrorSkip() { - cerror_lasterrorline = -1; -} - -void CError_GetErrorString(char *buf, short code) { - // This feels dirty, surely this can't have been the solution... - int code_ = code; -#line 142 - CError_ASSERT(code_ >= 100 && code_ < 393); - COS_GetString(buf, 10000, (short) (code_ - 99)); -} - -void CError_BufferInit(CErrorBuffer *eb, char *buf, long bufSize) { - eb->start = eb->end = buf; - eb->size = eb->remaining = bufSize - 1; -} - -void CError_BufferGrow(CErrorBuffer *eb, long amount) { - char *newBuf; - - newBuf = lalloc(eb->size + amount); - memcpy(newBuf, eb->start, eb->size); - eb->start = newBuf; - eb->end = newBuf + eb->size - eb->remaining; - eb->size += amount; - eb->remaining += amount; -} - -void CError_BufferAppendChar(CErrorBuffer *eb, char ch) { - if (eb) { - if (!eb->remaining) - CError_BufferGrow(eb, 256); - *(eb->end++) = ch; - eb->remaining--; - } -} - -void CError_BufferAppendString(CErrorBuffer *eb, const char *str) { - size_t len; - - if (eb) { - len = strlen(str); - if (eb->remaining < len) - CError_BufferGrow(eb, len); - memcpy(eb->end, str, len); - eb->end += len; - eb->remaining -= len; - } -} - -void CError_BufferTerminate(CErrorBuffer *eb) { - if (eb->remaining == 0) - CError_BufferGrow(eb, 1); - *eb->end = 0; - eb->remaining = 0; -} - -void CError_BufferAppendQualifier(CErrorBuffer *eb, int quals) { - -} - -void CError_BufferAppendTemplArgExpr(CErrorBuffer *eb, void *targExpr) { - -} - -void CError_BufferAppendTemplArg(CErrorBuffer *eb, void *targ) { - -} - -void CError_BufferAppendTemplArgs(CErrorBuffer *eb, void *targs) { - -} - -void CError_BufferAppendNameSpace(CErrorBuffer *eb, void *ns) { - -} - -void CError_BufferAppendPType(CErrorBuffer *eb, void *ty) { - -} - -void CError_BufferAppendTemplDepType(CErrorBuffer *eb, void *ty) { - -} - -void CError_BufferAppendFuncArgs(CErrorBuffer *eb, void *args, unsigned char flag) { - -} - -void CError_BufferAppendType(CErrorBuffer *eb, void *ty, int quals) { - -} - -char *CError_GetTypeName(void *ty, int quals, unsigned char useGlobalHeap) { - CErrorBuffer eb; - char buf[256]; - char *ptr; - - CError_BufferInit(&eb, buf, sizeof(buf)); - CError_BufferAppendType(&eb, ty, quals); - CError_BufferTerminate(&eb); - - if (useGlobalHeap) - ptr = galloc(eb.size + 1); - else - ptr = lalloc(eb.size + 1); - - return strcpy(ptr, eb.start); -} - -void CError_AppendUnqualFunctionName(CErrorBuffer *eb, void *unk1, void *unk2, void *unk3) { - -} - -void CError_AppendFunctionName(CErrorBuffer *eb, void *unk1, void *unk2, void *unk3, void *unk4) { - -} - -void CError_AppendObjectName(CErrorBuffer *eb, void *obj) { - -} - -void CError_AppendMethodName(CErrorBuffer *eb, void *obj) { - -} - -char *CError_GetQualifiedName(void *ns, StringNode *name) { - CErrorBuffer eb; - char buf[256]; - char *ptr; - - CError_BufferInit(&eb, buf, sizeof(buf)); - CError_BufferAppendNameSpace(&eb, ns); - CError_BufferAppendString(&eb, name->data); - CError_BufferTerminate(&eb); - - ptr = lalloc(eb.size + 1); - return strcpy(ptr, eb.start); -} - -char *CError_GetFunctionName(void *a, void *b, void *c) { - CErrorBuffer eb; - char buf[256]; - char *ptr; - - CError_BufferInit(&eb, buf, sizeof(buf)); - CError_AppendFunctionName(&eb, a, b, 0, c); - CError_BufferTerminate(&eb); - - ptr = lalloc(eb.size + 1); - return strcpy(ptr, eb.start); -} - -char *CError_GetObjectName(void *obj) { - CErrorBuffer eb; - char buf[256]; - char *ptr; - - CError_BufferInit(&eb, buf, sizeof(buf)); - CError_AppendObjectName(&eb, obj); - CError_BufferTerminate(&eb); - - ptr = lalloc(eb.size + 1); - return strcpy(ptr, eb.start); -} - -char *CError_GetNameString(void *obj, StringNode *operatorName) { - CErrorBuffer eb; - char buf[256]; - char *ptr; - char *opStr; - - CError_ASSERT(operatorName); - - // TODO lolol - CError_BufferInit(&eb, buf, sizeof(buf)); - CError_AppendObjectName(&eb, obj); - CError_BufferTerminate(&eb); - - ptr = lalloc(eb.size + 1); - return strcpy(ptr, eb.start); -} - -void CError_ErrorMessage(int errTable, char *buf, unsigned char flag1, unsigned char flag2) { - -} - -void CError_BufferAppendTemplateStack(CErrorBuffer *eb) { - -} - -void CError_ErrorMessageVA(short code, char *buf, va_list list, unsigned char flag1, unsigned char flag2) { - -} - -void CError_VAErrorMessage(short code, va_list list, unsigned char flag1, unsigned char flag2) { - char buf[256]; - - CError_GetErrorString(buf, code); - CError_ErrorMessageVA(code + 10000, buf, list, flag1, flag2); -} - -void CError_Error(short code, ...) { - -} - -void CError_ErrorTerm(short code) { - CError_GetErrorString(string, code); - CError_ErrorMessage(code + 10000, string, 0, 0); - longjmp(errorreturn, 1); -} - -void CError_ErrorSkip(short code, ...) { - // TODO trychain, tk -} - -void CError_ErrorFuncCall(short code, void *aa, void *bb) { - -} - -void CError_OverloadedFunctionError2(void *aa, void *bb, void *cc) { - -} - -void CError_OverloadedFunctionError(void *aa, void *bb) { - -} - -void CError_AbstractClassError() { - // TODO CClass -} - -void CError_Warning(short code, ...) { - // TODO lol -} - -void CError_BreakPoint(const char *a, const char *b) { - if (!a || !strcmp(a, b)) - CError_BreakPointcount++; -} - -void CError_Internal(char *filename, int line) { - char tmp[128]; - CompilerGetCString(5, tmp); - sprintf(string, tmp, filename, line); - CError_ErrorMessage(10001, string, 1, 0); - longjmp(errorreturn, 1); - CError_BreakPoint(0, 0); -} - -void CError_ExpressionTooComplex() { - CompilerGetCString(6, string); - CError_ErrorMessage(10002, string, 1, 0); - longjmp(errorreturn, 1); -} - -void CError_NoMem() { - cprep_nomem_exit = 1; - longjmp(errorreturn, 1); -} - -void CError_UserBreak() { - CompilerGetCString(8, string); - longjmp(errorreturn, 1); -} - -void CError_CannotOpen() { - // TODO -} - -void CError_QualifierCheck(int quals) { - -} diff --git a/CError.h b/CError.h deleted file mode 100644 index 6137d23..0000000 --- a/CError.h +++ /dev/null @@ -1,63 +0,0 @@ -#include "CompilerTools.h" -#pragma once - -#define CError_ASSERT(cond) if (!(cond)) { CError_Internal(__FILE__, __LINE__); } -#define CError_FAIL(cond) if (cond) { CError_Internal(__FILE__, __LINE__); } - -typedef struct _CErrorBuffer { - char *start; - char *end; - unsigned long size; - unsigned long remaining; -} CErrorBuffer; - -extern void CError_Init(); -extern void CError_SetErrorToken(Token *token); -extern void CError_SetNullErrorToken(); -extern void CError_LockErrorPos(Token *token, Token **saved); -extern void CError_UnlockErrorPos(Token **saved); -extern void CError_ResetErrorSkip(); -extern void CError_GetErrorString(char *buf, short code); -extern void CError_BufferInit(CErrorBuffer *eb, char *buf, long bufSize); -extern void CError_BufferGrow(CErrorBuffer *eb, long amount); -extern void CError_BufferAppendChar(CErrorBuffer *eb, char ch); -extern void CError_BufferAppendString(CErrorBuffer *eb, const char *str); -extern void CError_BufferTerminate(CErrorBuffer *eb); -// FIX LOTS OF THESE -extern void CError_BufferAppendQualifier(CErrorBuffer *eb, int quals); -extern void CError_BufferAppendTemplArgExpr(CErrorBuffer *eb, void *targExpr); -extern void CError_BufferAppendTemplArg(CErrorBuffer *eb, void *targ); -extern void CError_BufferAppendTemplArgs(CErrorBuffer *eb, void *targs); -extern void CError_BufferAppendNameSpace(CErrorBuffer *eb, void *ns); -extern void CError_BufferAppendPType(CErrorBuffer *eb, void *ty); -extern void CError_BufferAppendTemplDepType(CErrorBuffer *eb, void *ty); -extern void CError_BufferAppendFuncArgs(CErrorBuffer *eb, void *args, unsigned char flag); -extern void CError_BufferAppendType(CErrorBuffer *eb, void *ty, int quals); -extern char *CError_GetTypeName(void *ty, int quals, unsigned char useGlobalHeap); -extern void CError_AppendUnqualFunctionName(CErrorBuffer *eb, void *unk1, void *unk2, void *unk3); -extern void CError_AppendFunctionName(CErrorBuffer *eb, void *unk1, void *unk2, void *unk3, void *unk4); -extern void CError_AppendObjectName(CErrorBuffer *eb, void *obj); -extern void CError_AppendMethodName(CErrorBuffer *eb, void *obj); -extern char *CError_GetQualifiedName(void *ns, StringNode *name); -extern char *CError_GetFunctionName(void *a, void *b, void *c); -extern char *CError_GetObjectName(void *obj); -extern char *CError_GetNameString(void *obj, StringNode *operatorName); -extern void CError_ErrorMessage(int errTable, char *buf, unsigned char flag1, unsigned char flag2); -extern void CError_BufferAppendTemplateStack(CErrorBuffer *eb); -extern void CError_ErrorMessageVA(short code, char *buf, va_list list, unsigned char flag1, unsigned char flag2); -extern void CError_VAErrorMessage(short code, va_list list, unsigned char flag1, unsigned char flag2); -extern void CError_Error(short code, ...); -extern void CError_ErrorTerm(short code); -extern void CError_ErrorSkip(short code, ...); -extern void CError_ErrorFuncCall(short code, void *aa, void *bb); -extern void CError_OverloadedFunctionError2(void *aa, void *bb, void *cc); -extern void CError_OverloadedFunctionError(void *aa, void *bb); -extern void CError_AbstractClassError(); -extern void CError_Warning(short code, ...); -extern void CError_BreakPoint(const char *a, const char *b); -extern void CError_Internal(); -extern void CError_ExpressionTooComplex(); -extern void CError_NoMem(); -extern void CError_UserBreak(); -extern void CError_CannotOpen(); -extern void CError_QualifierCheck(int quals); diff --git a/CMakeLists.txt b/CMakeLists.txt index 33718d6..3351eef 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -74,4 +74,14 @@ add_executable(mwcc unsorted/Arguments.c unsorted/Help.c unsorted/Option.c - unsorted/Parameter.c unsorted/TargetOptimizer-ppc-mach.c unsorted/OptimizerHelpers.c compiler_and_linker/CmdLine_Tools/MacOS_PPC/Tools_PPC/Src/Options/Glue/TargetWarningHelpers-ppc-cc.c) + unsorted/Parameter.c + unsorted/TargetOptimizer-ppc-mach.c + unsorted/OptimizerHelpers.c + compiler_and_linker/CmdLine_Tools/MacOS_PPC/Tools_PPC/Src/Options/Glue/TargetWarningHelpers-ppc-cc.c + compiler_and_linker/unsorted/CCompiler.c + unsorted/CmdLineBuildDate.c + compiler_and_linker/FrontEnd/C/CScope.c + compiler_and_linker/unsorted/CPrec.c + compiler_and_linker/unsorted/CError.c + compiler_and_linker/unsorted/CInt64.c + compiler_and_linker/unsorted/CMachine.c compiler_and_linker/FrontEnd/C/CPrepTokenizer.c compiler_and_linker/FrontEnd/C/CPrep.c) diff --git a/CompilerTools.c b/CompilerTools.c deleted file mode 100644 index d2ff19d..0000000 --- a/CompilerTools.c +++ /dev/null @@ -1,1244 +0,0 @@ -#include "CompilerTools.h" - -static short lheaplockcount; -static void (*heaperror)(); -static Allocator bheap; -static Allocator oheap; -static Allocator aheap; -static Allocator lheap; -static Allocator gheap; -long hash_name_id; -StringNode **name_hash_nodes; -void (*GListErrorProc)(); - -void CompilerGetPString(short index, unsigned char *str) { - COS_GetPString(str, 10100, index); -} - -void CompilerGetCString(short index, char *str) { - COS_GetString(str, 10100, index); -} - -unsigned char *CTool_CtoPstr(char *input) { - char *work = input; - int length = 0; - int i; - - while (*work) { - ++length; - ++work; - } - - for (i = length; i > 0; i--) { - work[0] = work[-1]; - --work; - } - - input[0] = length; - return (unsigned char *) input; -} - -static void GListError() { - if (GListErrorProc) - GListErrorProc(); -} - -int InitGList(GList *list, long capacity) { - if ((list->data = COS_NewOSHandle(capacity)) == 0) - if ((list->data = COS_NewHandle(capacity)) == 0) - return -1; - list->size = 0; - list->expansion = capacity >> 1; - list->capacity = capacity; - return 0; -} - -void FreeGList(GList *list) { - if (list->data != 0) { - COS_FreeHandle(list->data); - list->data = 0; - } - list->capacity = 0; - list->size = 0; -} - -void LockGList(GList *list) { - COS_LockHandleHi(list->data); -} - -void UnlockGList(GList *list) { - COS_UnlockHandle(list->data); -} - -void ShrinkGList(GList *list) { - COS_ResizeHandle(list->data, list->capacity = list->size); -} - -void AppendGListData(GList *list, const void *data, long size) { - if ((list->size + size) > list->capacity) { - if (!COS_ResizeHandle(list->data, list->capacity += size + list->expansion)) - GListError(); - } - - memcpy(*list->data + list->size, data, size); - list->size += size; -} - -void AppendGListNoData(GList *list, long size) { - if ((list->size + size) > list->capacity) { - if (!COS_ResizeHandle(list->data, list->capacity += size + list->expansion)) - GListError(); - } - - list->size += size; -} - -void AppendGListByte(GList *list, char v) { - if ((list->size + 1) > list->capacity) { - if (!COS_ResizeHandle(list->data, list->capacity += 1 + list->expansion)) - GListError(); - } - - (*list->data)[list->size++] = v; -} - -void AppendGListWord(GList *list, short v) { - char *p; - - if ((list->size + 2) > list->capacity) { - if (!COS_ResizeHandle(list->data, list->capacity += 2 + list->expansion)) - GListError(); - } - - p = *list->data + list->size; - list->size += 2; - *(p++) = ((unsigned char *) &v)[0]; - *(p++) = ((unsigned char *) &v)[1]; -} - -void AppendGListTargetEndianWord(GList *list, short v) { - char *p; - - if ((list->size + 2) > list->capacity) { - if (!COS_ResizeHandle(list->data, list->capacity += 2 + list->expansion)) - GListError(); - } - - p = *list->data + list->size; - list->size += 2; - *(p++) = ((unsigned char *) &v)[0]; - *(p++) = ((unsigned char *) &v)[1]; -} - -void AppendGListLong(GList *list, long v) { - char *p; - - if ((list->size + 4) > list->capacity) { - if (!COS_ResizeHandle(list->data, list->capacity += 4 + list->expansion)) - GListError(); - } - - p = *list->data + list->size; - list->size += 4; - *(p++) = ((unsigned char *) &v)[0]; - *(p++) = ((unsigned char *) &v)[1]; - *(p++) = ((unsigned char *) &v)[2]; - *(p++) = ((unsigned char *) &v)[3]; -} - -void AppendGListTargetEndianLong(GList *list, long v) { - char *p; - - if ((list->size + 4) > list->capacity) { - if (!COS_ResizeHandle(list->data, list->capacity += 4 + list->expansion)) - GListError(); - } - - p = *list->data + list->size; - list->size += 4; - *(p++) = ((unsigned char *) &v)[0]; - *(p++) = ((unsigned char *) &v)[1]; - *(p++) = ((unsigned char *) &v)[2]; - *(p++) = ((unsigned char *) &v)[3]; -} - -void AppendGListID(GList *list, const char *str) { - unsigned long size = strlen(str) + 1; - if ((list->size + size) > list->capacity) { - if (!COS_ResizeHandle(list->data, list->capacity += size + list->expansion)) - GListError(); - } - - memcpy(*list->data + list->size, str, size); - list->size += size; -} - -void AppendGListName(GList *list, const char *str) { - unsigned long size = strlen(str); - if ((list->size + size) > list->capacity) { - if (!COS_ResizeHandle(list->data, list->capacity += size + list->expansion)) - GListError(); - } - - memcpy(*list->data + list->size, str, size); - list->size += size; -} - -void RemoveGListData(GList *list, long size) { - list->size -= size; - if (list->capacity > (list->size + list->expansion * 2)) - COS_ResizeHandle(list->data, list->capacity = list->size + list->expansion); -} - -char GetGListByte(GList *list) { - unsigned char *p; - char r; - - p = (unsigned char *) (*list->data + list->size); - list->size++; - r = p[0]; - return r; -} - -short GetGListWord(GList *list) { - unsigned char *p; - union { unsigned char bytes[2]; short s; } data; - - p = (unsigned char *) (*list->data + list->size); - list->size += 2; - data.bytes[0] = p[0]; - data.bytes[1] = p[1]; - return data.s; -} - -long GetGListLong(GList *list) { - unsigned char *p; - union { unsigned char bytes[4]; long l; } data; - - p = (unsigned char *) (*list->data + list->size); - list->size += 4; - data.bytes[0] = p[0]; - data.bytes[1] = p[1]; - data.bytes[2] = p[2]; - data.bytes[3] = p[3]; - return data.l; -} - -short GetGListID(GList *list, char *buf) { - short len; - char *p; - - len = 1; - p = *list->data + list->size; - while (*p) { - *(buf++) = *(p++); - len++; - } - - *buf = *p; - list->size += len; - return len; -} - -void GetGListData(GList *list, char *buf, long size) { - memcpy(buf, *list->data + list->size, size); - list->size += size; -} - -static long hashpjw(const char *str) { - unsigned long work = 0; - unsigned long tmp; - - while (*str) { - work = (work << 4) + *str; - tmp = work & 0xF0000000; - if (tmp) { - work ^= (tmp >> 24); - work ^= tmp; - } - str++; - } - - return work % 0xFFFFFD; -} - -static short PHash(const unsigned char *str) { - short result; - short counter; - unsigned char work; - const unsigned char *p; - - result = str[0] & 0xFF; - p = &str[1]; - if (str[0] & 0xFF) { - counter = result; - work = 0; - while (counter > 0) { - work = (work >> 3) | (work << 5); - work += *p; - --counter; - ++p; - } - - result = (result << 8) | work; - } - - return result & 0x7FF; -} - -short CHash(const char *str) { - /* not matching :( */ - unsigned char len; - short result; // orig r4 - unsigned char work; // orig r5 - short counter; // orig r3 - - // counter,result,work -> r3=work, r4=counter, r5=result - // result,counter,work -> r3=work, r4=result, r5=counter - // work,result,counter -> r3=work, r4=result, r5=counter - // work,counter,result -> r3=work, r4=counter, r5=result - // counter,work,result -> r3=work, r4=counter, r5=result - // result,work,counter -> r3=work, r4=result, r5=counter - - // i am: r4 = result, r5 = counter, r3 = work - - len = strlen(str); - result = len; - if (len) { - counter = len; - work = 0; - while (counter > 0) { - work = (work >> 3) | (work << 5); - work = work + *str; - //work = *(str++) + (unsigned char) ((work >> 3) | (work << 5)); - counter--; - str++; - } - result = result << 8; - result = result | work; - } - - return result & 0x7FF; -} - -StringNode *GetHashNameNode(const char *str) { - StringNode *node; - short hash; - - hash = CHash(str); - node = name_hash_nodes[hash]; - if (node == 0) { - node = (StringNode *) galloc(strlen(str) + sizeof(StringNode)); - name_hash_nodes[hash] = node; - node->next = 0; - node->index = hash_name_id++; - node->hash = hash; - strcpy(node->data, str); - return node; - } else { - for (;;) { - if (strcmp(str, node->data) == 0) { - if (node->index < 0) - node->index = hash_name_id++; - return node; - } - - if (node->next == 0) { - node->next = (StringNode *) galloc(strlen(str) + sizeof(StringNode)); - node = node->next; - node->next = 0; - node->index = hash_name_id++; - node->hash = hash; - strcpy(node->data, str); - return node; - } else { - node = node->next; - } - } - } -} - -StringNode *GetHashNameNodeHash(const char *str, short hash) { - StringNode *node; - - node = name_hash_nodes[hash]; - if (node == 0) { - node = (StringNode *) galloc(strlen(str) + sizeof(StringNode)); - name_hash_nodes[hash] = node; - node->next = 0; - node->index = hash_name_id++; - node->hash = hash; - strcpy(node->data, str); - return node; - } else { - for (;;) { - if (strcmp(str, node->data) == 0) - return node; - - if (node->next == 0) { - node->next = (StringNode *) galloc(strlen(str) + sizeof(StringNode)); - node = node->next; - node->next = 0; - node->index = hash_name_id++; - node->hash = hash; - strcpy(node->data, str); - return node; - } else { - node = node->next; - } - } - } -} - -StringNode *GetHashNameNodeHash2(const char *str, short hash) { - StringNode *node; - - node = name_hash_nodes[hash]; - if (node == 0) { - node = (StringNode *) galloc(strlen(str) + sizeof(StringNode)); - name_hash_nodes[hash] = node; - node->next = 0; - node->index = -1; - node->hash = hash; - strcpy(node->data, str); - return node; - } else { - for (;;) { - if (strcmp(str, node->data) == 0) - return node; - - if (node->next == 0) { - node->next = (StringNode *) galloc(strlen(str) + sizeof(StringNode)); - node = node->next; - node->next = 0; - node->index = -1; - node->hash = hash; - strcpy(node->data, str); - return node; - } else { - node = node->next; - } - } - } -} - -StringNode *GetHashNameNodeExport(const char *str) { - // not matching - StringNode *node; - short hash; - - hash = CHash(str); - if ((node = name_hash_nodes[hash]) == 0) { - node = (StringNode *) galloc(strlen(str) + sizeof(StringNode)); - name_hash_nodes[hash] = node; - node->next = 0; - node->index = -1; - node->hash = hash; - strcpy(node->data, str); - return node; - } else { - for (;;) { - if (strcmp(str, node->data) == 0) - return node; - - if (node->next == 0) { - node->next = (StringNode *) galloc(strlen(str) + sizeof(StringNode)); - node = node->next; - node->next = 0; - node->index = -1; - node->hash = hash; - strcpy(node->data, str); - return node; - } else { - node = node->next; - } - } - } -} - -long GetHashNameNodeExportID(StringNode *node) { - if (node->index < 0) - node->index = hash_name_id++; - return node->index; -} - -StringNode *GetHashNameNodeByID(long id) { - StringNode *node; - short i; - - for (i = 0; i < 2048; i++) { - for (node = name_hash_nodes[i]; node; node = node->next) { - if (id == node->index) - return node; - } - } - - return 0; -} - -void NameHashExportReset() { - short i; - StringNode *node; - - for (i = 0; i < 0x800; i++) { - node = name_hash_nodes[i]; - while (node) { - node->index = -1; - node = node->next; - } - } - - hash_name_id = 1; -} - -void NameHashWriteNameTable(GList *list) { - StringNode *node; - StringNode **nodes; - short grp; - int i; - - nodes = (StringNode **) galloc(sizeof(StringNode *) * hash_name_id); - - for (grp = 0; grp < 0x800; grp++) { - node = name_hash_nodes[grp]; - while (node) { - if (node->index > 0) - nodes[node->index] = node; - node = node->next; - } - } - - for (i = 1; i < hash_name_id; i++) { - node = nodes[i]; - AppendGListWord(list, node->hash); - AppendGListID(list, node->data); - } - - if (list->size & 1) - AppendGListByte(list, 0); -} - -void NameHashWriteTargetEndianNameTable(GList *list) { - StringNode *node; - StringNode **nodes; - short grp; - int i; - - nodes = (StringNode **) galloc(sizeof(StringNode *) * hash_name_id); - memclrw(nodes, sizeof(StringNode *) * hash_name_id); - - for (grp = 0; grp < 0x800; grp++) { - node = name_hash_nodes[grp]; - while (node) { - if (node->index > 0) - nodes[node->index] = node; - node = node->next; - } - } - - for (i = 1; i < hash_name_id; i++) { - node = nodes[i]; - if (node == 0) { - AppendGListTargetEndianWord(list, 0); - AppendGListID(list, ""); - } else { - AppendGListTargetEndianWord(list, node->hash); - AppendGListID(list, node->data); - } - } - - if (list->size & 1) - AppendGListByte(list, 0); -} - -void InitNameHash() { - name_hash_nodes = (StringNode **) galloc(0x800 * sizeof(StringNode *)); - memclrw(name_hash_nodes, 0x800 * sizeof(StringNode *)); - hash_name_id = 1; -} - -long CTool_TotalHeapSize() { - long total = 0; - AllocatorBlock *block; - - for (block = gheap.blockList; block; block = block->nextBlock) { - total += block->size; - } - for (block = lheap.blockList; block; block = block->nextBlock) { - total += block->size; - } - for (block = aheap.blockList; block; block = block->nextBlock) { - total += block->size; - } - for (block = oheap.blockList; block; block = block->nextBlock) { - total += block->size; - } - for (block = bheap.blockList; block; block = block->nextBlock) { - total += block->size; - } - - return total; -} - -static void getheapinfo(HeapInfo *result, Allocator *heap) { - AllocatorBlock *block; - - result->_4 = heap->paddingSize; - for (block = heap->blockList; block; block = block->nextBlock) { - result->_8 += block->size - sizeof(AllocatorBlock); - result->xx_C += block->remaining; - result->_0++; - if (block->remaining > result->_18) - result->_18 = block->remaining; - } - - result->_10 = result->_8 / result->_0; - result->_14 = result->xx_C / result->_0; -} - -void CTool_GetHeapInfo(HeapInfo *result, unsigned char heapID) { - memclrw(result, sizeof(HeapInfo)); - - switch (heapID) { - case 0: - getheapinfo(result, &gheap); - break; - case 1: - getheapinfo(result, &lheap); - break; - case 2: - getheapinfo(result, &aheap); - break; - case 3: - getheapinfo(result, &oheap); - break; - case 4: - getheapinfo(result, &bheap); - break; - case 5: - getheapinfo(result, &gheap); - getheapinfo(result, &lheap); - getheapinfo(result, &aheap); - getheapinfo(result, &oheap); - getheapinfo(result, &bheap); - break; - } -} - -static void MoreHeapSpace(Allocator *alloc, long size) { - Handle blockHandle; - long blockSize; - AllocatorBlock *block; - - block = alloc->blockList; - if (block) { - alloc->lastBlockUsed->remaining = alloc->remaining; - while (block) { - if (block->remaining >= size) - goto gotBlock; - block = block->nextBlock; - } - } - - /* create new block */ - blockSize = size + alloc->paddingSize; - if (systemHandles) { - blockHandle = COS_NewOSHandle(blockSize << 1); - if (blockHandle != 0) - goto createdTempDoubleBlock; - blockHandle = COS_NewOSHandle(blockSize); - if (blockHandle != 0) - goto createdBlock; - } - blockHandle = COS_NewHandle(blockSize); - if (blockHandle != 0) - goto createdBlock; - - if (heaperror) - heaperror(); - return; - - createdTempDoubleBlock: - blockSize <<= 1; - goto createdBlock; - createdBlock: - COS_LockHandleHi(blockHandle); - block = (AllocatorBlock *) *blockHandle; - block->nextBlock = alloc->blockList; - alloc->blockList = block; - block->handle = blockHandle; - block->size = blockSize; - block->remaining = blockSize - sizeof(AllocatorBlock); - gotBlock: - alloc->lastBlockUsed = block; - alloc->remaining = block->remaining; - alloc->ptrToFreeArea = ((char *) block) + block->size - block->remaining; -} - -int initheaps(heaperror_t failureCallback) { - heaperror = 0; - lheaplockcount = 0; - - memclrw(&gheap, sizeof(Allocator)); - memclrw(&lheap, sizeof(Allocator)); - memclrw(&aheap, sizeof(Allocator)); - memclrw(&oheap, sizeof(Allocator)); - memclrw(&bheap, sizeof(Allocator)); - - gheap.paddingSize = 0x38000; - lheap.paddingSize = 0x10000; - aheap.paddingSize = 0x4000; - oheap.paddingSize = 0x40000; - bheap.paddingSize = 0x4000; - - MoreHeapSpace(&gheap, 0); - MoreHeapSpace(&lheap, 0); - MoreHeapSpace(&aheap, 0); - MoreHeapSpace(&oheap, 0); - MoreHeapSpace(&bheap, 0); - - gheap.paddingSize = 0x8000; - lheap.paddingSize = 0x8000; - - heaperror = failureCallback; - - if (!gheap.lastBlockUsed || !lheap.lastBlockUsed || !aheap.lastBlockUsed || !oheap.lastBlockUsed || !bheap.lastBlockUsed) - return -1; - else - return 0; -} - -int initgheap(heaperror_t failureCallback) { - heaperror = 0; - lheaplockcount = 0; - - memclrw(&gheap, sizeof(Allocator)); - memclrw(&lheap, sizeof(Allocator)); - memclrw(&aheap, sizeof(Allocator)); - memclrw(&oheap, sizeof(Allocator)); - memclrw(&bheap, sizeof(Allocator)); - - gheap.paddingSize = 0x38000; - MoreHeapSpace(&gheap, 0); - gheap.paddingSize = 0x8000; - - heaperror = failureCallback; - - if (!gheap.lastBlockUsed) - return -1; - else - return 0; -} - -heaperror_t getheaperror() { - return heaperror; -} - -void setheaperror(heaperror_t failureCallback) { - heaperror = failureCallback; -} - -static void relheap(Allocator *alloc) { - AllocatorBlock *block; - Handle handle; - - block = alloc->blockList; - while (block) { - handle = block->handle; - block = block->nextBlock; - COS_FreeHandle(handle); - } - - memclrw(alloc, sizeof(Allocator)); -} - -void releaseheaps() { - relheap(&gheap); - relheap(&lheap); - relheap(&aheap); - relheap(&oheap); - relheap(&bheap); -} - -void releasegheap() { - relheap(&gheap); -} - -void releaseoheap() { - relheap(&gheap); - oheap.paddingSize = 0x40000; - MoreHeapSpace(&oheap, 0); -} - -char *galloc(long size) { - long alignedSize; - char *ptr; - - alignedSize = (size & ~7) + 8; - if (gheap.remaining < alignedSize) - MoreHeapSpace(&gheap, alignedSize); - - gheap.remaining -= alignedSize; - ptr = (char *) gheap.ptrToFreeArea; - gheap.ptrToFreeArea = ptr + alignedSize; - return ptr; -} - -char *lalloc(long size) { - long alignedSize; - char *ptr; - - alignedSize = (size & ~7) + 8; - if (lheap.remaining < alignedSize) - MoreHeapSpace(&lheap, alignedSize); - - lheap.remaining -= alignedSize; - ptr = (char *) lheap.ptrToFreeArea; - lheap.ptrToFreeArea = ptr + alignedSize; - return ptr; -} - -char *aalloc(long size) { - long alignedSize; - char *ptr; - - alignedSize = (size & ~7) + 8; - if (aheap.remaining < alignedSize) - MoreHeapSpace(&aheap, alignedSize); - - aheap.remaining -= alignedSize; - ptr = (char *) aheap.ptrToFreeArea; - aheap.ptrToFreeArea = ptr + alignedSize; - return ptr; -} - -char *oalloc(long size) { - long alignedSize; - char *ptr; - - alignedSize = (size & ~7) + 8; - if (oheap.remaining < alignedSize) - MoreHeapSpace(&oheap, alignedSize); - - oheap.remaining -= alignedSize; - ptr = (char *) oheap.ptrToFreeArea; - oheap.ptrToFreeArea = ptr + alignedSize; - return ptr; -} - -char *balloc(long size) { - long alignedSize; - char *ptr; - - alignedSize = (size & ~7) + 8; - if (bheap.remaining < alignedSize) - MoreHeapSpace(&bheap, alignedSize); - - bheap.remaining -= alignedSize; - ptr = (char *) bheap.ptrToFreeArea; - bheap.ptrToFreeArea = ptr + alignedSize; - return ptr; -} - -void locklheap() { - lheaplockcount++; -} - -void unlocklheap() { - if (lheaplockcount > 0) - --lheaplockcount; -} - -void freelheap() { - AllocatorBlock *block; - - if (lheaplockcount == 0) { - block = lheap.blockList; - lheap.lastBlockUsed = block; - lheap.ptrToFreeArea = ((char *) block) + sizeof(AllocatorBlock); - lheap.remaining = block->size - sizeof(AllocatorBlock); - - while (block) { - block->remaining = block->size - sizeof(AllocatorBlock); - block = block->nextBlock; - } - } -} - -void freeaheap() { - AllocatorBlock *block; - - block = aheap.blockList; - aheap.lastBlockUsed = block; - aheap.ptrToFreeArea = ((char *) block) + sizeof(AllocatorBlock); - aheap.remaining = block->size - sizeof(AllocatorBlock); - - while (block) { - block->remaining = block->size - sizeof(AllocatorBlock); - block = block->nextBlock; - } -} - -void freeoheap() { - AllocatorBlock *block; - - block = oheap.blockList; - oheap.lastBlockUsed = block; - oheap.ptrToFreeArea = ((char *) block) + sizeof(AllocatorBlock); - oheap.remaining = block->size - sizeof(AllocatorBlock); - - while (block) { - block->remaining = block->size - sizeof(AllocatorBlock); - block = block->nextBlock; - } -} - -void freebheap() { - AllocatorBlock *block; - - block = bheap.blockList; - bheap.lastBlockUsed = block; - bheap.ptrToFreeArea = ((char *) block) + sizeof(AllocatorBlock); - bheap.remaining = block->size - sizeof(AllocatorBlock); - - while (block) { - block->remaining = block->size - sizeof(AllocatorBlock); - block = block->nextBlock; - } -} - -char *ScanHex(char *str, long *output, Boolean *overflow) { - long work; - int ch; - - work = 0; - *overflow = 0; - - for (;;) { - ch = *str; - if (ch >= '0' && ch <= '9') { - ch = ch - '0'; - } else if (ch >= 'A' && ch <= 'F') { - ch = ch - 'A' + 10; - } else if (ch >= 'a' && ch <= 'f') { - ch = ch - 'a' + 10; - } else { - break; - } - - if (work & 0xF0000000) - *overflow = 1; - work = (work << 4) | (short) ch; - ++str; - } - - *output = work; - return str; -} - -char *ScanOct(char *str, long *output, Boolean *overflow) { - short digit; - long work; - - work = 0; - *overflow = 0; - - for (;;) { - digit = *str - '0'; - if (digit >= 0 && digit <= 9) { - if (digit >= 8) { - *overflow = 1; - ++str; - break; - } - } else { - break; - } - - if (work & 0xE0000000) - *overflow = 1; - work = (work << 3) | digit; - ++str; - } - - *output = work; - return str; -} - -char *ScanDec(char *str, long *output, Boolean *overflow) { - short digit; - unsigned long work; - - work = 0; - *overflow = 0; - - for (;;) { - digit = *str - '0'; - if (digit >= 0 && digit <= 9) { - if (work >= 0x19999999 && (work > 0x19999999 || digit > 5)) - *overflow = 1; - } else { - break; - } - - work = (work << 3) + (work << 1) + digit; - ++str; - } - - *output = work; - return str; -} - -static char *UnmangleClassname(char *work, char **pNameStart, short *pNameLength, char **a4, short *a5, Boolean a6) { - char ch; - short len; - char *p2; - short len2; - short i; - short wtf; - - *pNameLength = 0; - if (*(work++) != '_') - return work; - if (*(work++) != '_') { - return work; - } else { - len = 0; - while (work[0] >= '0' && work[0] <= '9') { - len = (len * 10) + work[0] - '0'; - ++work; - } - - if (len > 0) { - *pNameStart = work; - *pNameLength = len; - - if (a6) { - p2 = *a4; - len2 = *a5; - i = 0; - wtf = len; - while (i < wtf && len2 < 255) { - *(p2++) = work[i]; - ++i; - ++len2; - } - if (len2 < 255) { - *(p2++) = ':'; - len2++; - } - if (len2 < 255) { - *(p2++) = ':'; - len2++; - } - *a4 = p2; - *a5 = len2; - } - } - - return work + len; - } -} - -static char *UnmangleAppend(char *src, char srcLen, char **pOutput, short *pOutputLen) { - char *output; - short i; - short outputLen; - - output = *pOutput; - outputLen = *pOutputLen; - - for (i = 0; i < srcLen && outputLen < 255; i++, outputLen++) { - *(output++) = src[i]; - } - - *pOutput = output; - *pOutputLen = outputLen; -} - -void OldUnmangle(char *input, char *output, Boolean flag) { - short var26; - char *nameStart; - short nameLength; - char *saved; - int i; - - if (*input == '.') - ++input; - - var26 = 0; - saved = input; - if (input[0] == '_' && input[1] == '_') { - if (input[2] == 'c' && input[3] == 't') { - saved = UnmangleClassname(&input[4], &nameStart, &nameLength, &output, &var26, flag); - if (nameLength == 0) - goto invalid; - UnmangleAppend(nameStart, nameLength, &output, &var26); - } else if (input[2] == 'd' && input[3] == 't') { - saved = UnmangleClassname(&input[4], &nameStart, &nameLength, &output, &var26, flag); - if (nameLength == 0) - goto invalid; - if (var26 <= 255) { - *(output++) = '~'; - var26++; - } - UnmangleAppend(nameStart, nameLength, &output, &var26); - } else if (input[2] == 'n' && input[3] == 'w') { - saved = UnmangleClassname(&input[4], &nameStart, &nameLength, &output, &var26, flag); - UnmangleAppend("operator new", 15, &output, &var26); - } else if (input[2] == 'd' && input[3] == 'l') { - saved = UnmangleClassname(&input[4], &nameStart, &nameLength, &output, &var26, flag); - UnmangleAppend("operator delete", 15, &output, &var26); - } else { - invalid: - strncpy(output, input, 256); - return; - } - } else { - i = 0; - while (*saved) { - ++saved; - ++i; - if (saved[0] == '_' && saved[1] == '_') { - saved = UnmangleClassname(saved, &nameStart, &nameLength, &output, &var26, flag); - break; - } - } - UnmangleAppend(input, i, &output, &var26); - } - - if (flag && saved[0] == 'F') { - if (saved[1] == 'v') { - UnmangleAppend("(void)", 6, &output, &var26); - } else { - UnmangleAppend("(...)", 5, &output, &var26); - } - } - - *output = 0; -} - -short hash(char *str) { - char hash = 0; - - while (*str) { - hash = hash << 1; - hash ^= *(str++); - } - - return hash & 0x7F; -} - -void memclr(void *buffer, long size) { - memset(buffer, 0, size); -} - -void memclrw(void *buffer, long size) { - memset(buffer, 0, size); -} - -void CToLowercase(char *src, char *dst) { - char ch; - - do { - ch = tolower(*(src++)); - *(dst++) = ch; - } while (ch); -} - -int getbit(long v) { - switch (v) { - case 0: return -1; - case 1: return 0; - case 2: return 1; - case 4: return 2; - case 8: return 3; - case 0x10: return 4; - case 0x20: return 5; - case 0x40: return 6; - case 0x80: return 7; - case 0x100: return 8; - case 0x200: return 9; - case 0x400: return 10; - case 0x800: return 11; - case 0x1000: return 12; - case 0x2000: return 13; - case 0x4000: return 14; - case 0x8000: return 15; - case 0x10000: return 16; - case 0x20000: return 17; - case 0x40000: return 18; - case 0x80000: return 19; - case 0x100000: return 20; - case 0x200000: return 21; - case 0x400000: return 22; - case 0x800000: return 23; - case 0x1000000: return 24; - case 0x2000000: return 25; - case 0x4000000: return 26; - case 0x8000000: return 27; - case 0x10000000: return 28; - case 0x20000000: return 29; - case 0x40000000: return 30; - case 0x80000000: return 31; - default: return -2; - } -} - -void CTool_EndianConvertWord64(WtfWord64 value, unsigned long long *p) { - union { unsigned char bytes[8]; WtfWord64 w; } data; - data.w.a = value.a; - data.w.b = value.b; - memcpy(p, data.bytes, 8); -} - -unsigned short CTool_EndianConvertInPlaceWord16Ptr(unsigned short *p) { - unsigned short v; - v = *p; - // this probably has a conversion on non-ppc - *p = v; - return v; -} - -unsigned long CTool_EndianConvertInPlaceWord32Ptr(unsigned long *p) { - unsigned long v; - v = *p; - // this probably has a conversion on non-ppc - *p = v; - return v; -} - -void CTool_EndianConvertVector128() { - // not correct but idc -} - -StringNode *CTool_GetPathName(const FSSpec *spec, long *mdDat) { - char buffer[256]; - COS_FileGetPathName(buffer, spec, mdDat); - return GetHashNameNodeExport(buffer); -} - -Boolean strcat_safe(char *dst, const char *src, int maxLen) { - int len; - char ch; - - len = strlen(dst); - dst += len; - maxLen -= len; - if (maxLen < 0) - return 1; - - while (maxLen != 0) { - ch = *(dst++) = *(src++); - if (ch == 0) - break; - --maxLen; - } - - if (maxLen == 0 && dst[-1]) { - dst[-1] = 0; - return 1; - } else { - return 0; - } -} diff --git a/CompilerTools.h b/CompilerTools.h deleted file mode 100644 index 6f8ceac..0000000 --- a/CompilerTools.h +++ /dev/null @@ -1,134 +0,0 @@ -#include "includes/mwcc_decomp.h" -#pragma once - -extern void CompilerGetPString(short index, unsigned char *str); -extern void CompilerGetCString(short index, char *str); -extern unsigned char *CTool_CtoPstr(char *input); - -typedef struct _AllocatorBlock { - struct _AllocatorBlock *nextBlock; - char **handle; - long size; - long remaining; -} AllocatorBlock; - -typedef struct _Allocator { - AllocatorBlock *blockList; - long paddingSize; - AllocatorBlock *lastBlockUsed; - void *ptrToFreeArea; - long remaining; -} Allocator; - -typedef struct _HeapInfo { - long _0; - long _4; - long _8; - long xx_C; - long _10; - long _14; - long _18; -} HeapInfo; - -typedef struct _StringNode { - struct _StringNode *next; - long index; - short hash; - char data[1]; -} StringNode; - -typedef struct _GList { - char **data; - long size; - long capacity; - long expansion; -} GList; - -extern long hash_name_id; -extern StringNode **name_hash_nodes; -extern void (*GListErrorProc)(); - -// extern void GListError(); -extern int InitGList(GList *list, long capacity); -extern void FreeGList(GList *list); -extern void LockGList(GList *list); -extern void UnlockGList(GList *list); -extern void ShrinkGList(GList *list); -extern void AppendGListData(GList *list, const void *data, long size); -extern void AppendGListNoData(GList *list, long size); -extern void AppendGListByte(GList *list, char v); -extern void AppendGListWord(GList *list, short v); -extern void AppendGListTargetEndianWord(GList *list, short v); -extern void AppendGListLong(GList *list, long v); -extern void AppendGListTargetEndianLong(GList *list, long v); -extern void AppendGListID(GList *list, const char *str); -extern void AppendGListName(GList *list, const char *str); -extern void RemoveGListData(GList *list, long size); -extern char GetGListByte(GList *list); -extern short GetGListWord(GList *list); -extern long GetGListLong(GList *list); -extern short GetGListID(GList *list, char *buf); -extern void GetGListData(GList *list, char *buf, long size); -// extern long hashpjw(const char *str); -// extern short PHash(const unsigned char *str); -extern short CHash(const char *str); -extern StringNode *GetHashNameNode(const char *str); -extern StringNode *GetHashNameNodeHash(const char *str, short hash); -extern StringNode *GetHashNameNodeHash2(const char *str, short hash); -extern StringNode *GetHashNameNodeExport(const char *str); -extern long GetHashNameNodeExportID(StringNode *node); -extern StringNode *GetHashNameNodeByID(long id); -extern void NameHashExportReset(); -extern void NameHashWriteNameTable(GList *list); -extern void NameHashWriteTargetEndianNameTable(GList *list); -extern void InitNameHash(); - -typedef void (*heaperror_t)(); - -extern long CTool_TotalHeapSize(); -// extern void getheapinfo(HeapInfo *result, Allocator *heap); -extern void CTool_GetHeapInfo(HeapInfo *result, unsigned char heapID); -// extern void MoreHeapSpace(Allocator *alloc, long size); -extern int initheaps(heaperror_t failureCallback); -extern int initgheap(heaperror_t failureCallback); -extern heaperror_t getheaperror(); -extern void setheaperror(heaperror_t failureCallback); -// extern void relheap(Allocator *alloc); -extern void releaseheaps(); -extern void releasegheap(); -extern void releaseoheap(); -extern char *galloc(long size); -extern char *lalloc(long size); -extern char *aalloc(long size); -extern char *oalloc(long size); -extern char *balloc(long size); - -extern void locklheap(); -extern void unlocklheap(); -extern void freelheap(); -extern void freeaheap(); -extern void freeoheap(); -extern void freebheap(); - -extern char *ScanHex(char *str, long *output, Boolean *overflow); -extern char *ScanOct(char *str, long *output, Boolean *overflow); -extern char *ScanDec(char *str, long *output, Boolean *overflow); - -// extern char *UnmangleClassname(char *work, char **pNameStart, short *pNameLength, char **a4, short *a5, Boolean a6); -// extern char *UnmangleAppend(char *src, char srcLen, char **pOutput, short *pOutputLen); -extern void OldUnmangle(char *input, char *output, Boolean flag); - -extern short hash(char *str); -extern void memclr(void *buffer, long size); -extern void memclrw(void *buffer, long size); -extern void CToLowercase(char *src, char *dst); -extern int getbit(long v); -typedef struct { - unsigned long a, b; -} WtfWord64; // this has to make sense, somehow... but how? -extern void CTool_EndianConvertWord64(WtfWord64 value, unsigned long long *p); -extern unsigned short CTool_EndianConvertInPlaceWord16Ptr(unsigned short *p); -extern unsigned long CTool_EndianConvertInPlaceWord32Ptr(unsigned long *p); -extern void CTool_EndianConvertVector128(); // not correct but idc -extern StringNode *CTool_GetPathName(const FSSpec *spec, long *mdDat); -extern Boolean strcat_safe(char *dst, const char *src, int maxLen); diff --git a/compiler_and_linker/FrontEnd/C/CPrep.c b/compiler_and_linker/FrontEnd/C/CPrep.c new file mode 100644 index 0000000..e69bcfb --- /dev/null +++ b/compiler_and_linker/FrontEnd/C/CPrep.c @@ -0,0 +1,921 @@ +#include "compiler.h" +#include "compiler/CError.h" +#include "compiler/tokens.h" +#include "cos.h" + +extern SInt16 *CLT_filesp; +extern CPrepFileInfo **CLT_filestack; + +//#define OPT_OFFSET(optname) ((short) (((char *) (&copts.optname)) - ((char *) &copts))) +#define OPT_OFFSET(optname) ((short) ( &((COpts *)0)->optname )) +enum { + OPT_FLAG_2000 = 0x2000, + OPT_FLAG_4000 = 0x4000 +}; + +struct { + char *name; + short bits; +} compileroptions[138] = { + "little_endian", OPT_FLAG_4000 | OPT_OFFSET(little_endian), + "longlong", OPT_OFFSET(longlong), + "traceback", OPT_OFFSET(traceback), + "disable_registers", OPT_OFFSET(disable_registers), + "fp_contract", OPT_OFFSET(fp_contract), + "no_common", OPT_OFFSET(no_common), + "no_implicit_templates", OPT_OFFSET(no_implicit_templates), + "absolutepath", OPT_OFFSET(absolutepath), + "debug_listing", OPT_OFFSET(debuglisting), + "profile", OPT_OFFSET(profile), + "optimizewithasm", OPT_OFFSET(optimizewithasm), + "use_lmw_stmw", OPT_OFFSET(use_lmw_stmw), + "no_register_save_helpers", OPT_OFFSET(no_register_save_helpers), + "ppc_opt_bclr_bcctr", OPT_OFFSET(ppc_opt_bclr_bcctr), + "misaligned_mem_access", OPT_OFFSET(misaligned_mem_access), + "switch_tables", OPT_OFFSET(switch_tables), + "prepare_compress", OPT_OFFSET(prepare_compress), + "asmsemicolcomment", OPT_OFFSET(asmsemicolcomment), + "asmpoundcomment", OPT_OFFSET(asmpoundcomment), + "cplusplus", OPT_OFFSET(cplusplus), + "ecplusplus", OPT_OFFSET(ecplusplus), + "objective_c", OPT_OFFSET(objective_c), + "objc_strict", OPT_OFFSET(objc_strict), + "ARM_conform", OPT_OFFSET(ARM_conform), + "ARM_scoping", OPT_OFFSET(ARM_scoping), + "require_prototypes", OPT_OFFSET(require_prototypes), + "trigraphs", OPT_OFFSET(trigraphs), + "only_std_keywords", OPT_OFFSET(only_std_keywords), + "enumsalwaysint", OPT_OFFSET(enumsalwaysint), + "ANSI_strict", OPT_OFFSET(ANSI_strict), + "mpwc_relax", OPT_OFFSET(mpwc_relax), + "mpwc_newline", OPT_OFFSET(mpwc_newline), + "ignore_oldstyle", OPT_OFFSET(ignore_oldstyle), + "cpp_extensions", OPT_OFFSET(cpp_extensions), + "pointercast_lvalue", OPT_OFFSET(pointercast_lvalue), + "RTTI", OPT_OFFSET(useRTTI), + "delete_exception", OPT_OFFSET(delete_exception), + "oldalignment", OPT_OFFSET(oldalignment), + "multibyteaware", OPT_OFFSET(multibyteaware), + "unsigned_char", OPT_OFFSET(unsignedchars), + "auto_inline", OPT_OFFSET(autoinline), + "inline_bottom_up", OPT_OFFSET(inline_bottom_up), + "defer_codegen", OPT_OFFSET(defer_codegen), + "direct_to_som", OPT_OFFSET(direct_to_som), + "SOMCheckEnvironment", OPT_OFFSET(som_env_check), + "SOMCallOptimization", OPT_OFFSET(som_call_opt), + "bool", OPT_OFFSET(booltruefalse), + "old_enum_mangler", OPT_OFFSET(old_enum_mangler), + "longlong_enums", OPT_OFFSET(longlong_enums), + "no_tfuncinline", OPT_OFFSET(no_tfuncinline), + "flat_include", OPT_OFFSET(flat_include), + "syspath_once", OPT_OFFSET(syspath_once), + "always_import", OPT_OFFSET(always_import), + "simple_class_byval", OPT_OFFSET(simple_class_byval), + "wchar_type", OPT_OFFSET(wchar_type), + "vbase_ctor_offset", OPT_OFFSET(vbase_ctor_offset), + "vbase_abi_v2", OPT_OFFSET(vbase_abi_v2), + "def_inherited", OPT_OFFSET(def_inherited), + "template_patch", OPT_OFFSET(template_patch), + "template_friends", OPT_OFFSET(template_friends), + "faster_pch_gen", OPT_OFFSET(faster_pch_gen), + "array_new_delete", OPT_OFFSET(array_new_delete), + "dollar_identifiers", OPT_OFFSET(dollar_identifiers), + "def_inline_tfuncs", OPT_OFFSET(def_inline_tfuncs), + "arg_dep_lookup", OPT_OFFSET(arg_dep_lookup), + "simple_prepdump", OPT_OFFSET(simple_prepdump), + "line_prepdump", OPT_OFFSET(line_prepdump), + "fullpath_prepdump", OPT_OFFSET(fullpath_prepdump), + "old_mtemplparser", OPT_OFFSET(old_mtemplparser), + "suppress_init_code", OPT_OFFSET(suppress_init_code), + "reverse_bitfields", OPT_OFFSET(reverse_bitfields), + "c9x", OPT_OFFSET(c9x), + "float_constants", OPT_OFFSET(float_constants), + "no_static_dtors", OPT_OFFSET(no_static_dtors), + "longlong_prepeval", OPT_OFFSET(longlong_prepeval), + "const_strings", OPT_OFFSET(const_strings), + "dumpir", OPT_OFFSET(dumpir), + "experimental", OPT_OFFSET(experimental), + "gcc_extensions", OPT_OFFSET(gcc_extensions), + "stdc_fp_contract", OPT_OFFSET(stdc_fp_contract), + "stdc_fenv_access", OPT_OFFSET(stdc_fenv_access), + "stdc_cx_limitedr", OPT_OFFSET(stdc_cx_limitedr), + "old_argmatch", OPT_OFFSET(old_argmatch), + "optEH", OPT_OFFSET(optEH), + "optEH2", OPT_OFFSET(optEH2), + "new_mangler", OPT_OFFSET(new_mangler), + "microsoft_exceptions", OPT_OFFSET(microsoft), + "microsoft_RTTI", OPT_OFFSET(microsoft), + "warning_errors", OPT_OFFSET(warningerrors), + "extended_errorcheck", OPT_OFFSET(pedantic), + "check_header_flags", OPT_OFFSET(check_header_flags), + "supress_warnings", OPT_OFFSET(supress_warnings), + "warn_illpragma", OPT_OFFSET(warn_illpragma), + "warn_emptydecl", OPT_OFFSET(warn_emptydecl), + "warn_possunwant", OPT_OFFSET(warn_possunwant), + "warn_unusedvar", OPT_OFFSET(warn_unusedvar), + "warn_unusedarg", OPT_OFFSET(warn_unusedarg), + "warn_extracomma", OPT_OFFSET(warn_extracomma), + "warn_hidevirtual", OPT_OFFSET(warn_hidevirtual), + "warn_largeargs", OPT_OFFSET(warn_largeargs), + "warn_implicitconv", OPT_OFFSET(warn_implicitconv), + "warn_notinlined", OPT_OFFSET(warn_notinlined), + "warn_structclass", OPT_OFFSET(warn_structclass), + "warn_padding", OPT_OFFSET(warn_padding), + "warn_no_side_effect", OPT_OFFSET(warn_no_side_effect), + "warn_resultnotused", OPT_OFFSET(warn_resultnotused), + "warn_ptr_int_conv", OPT_OFFSET(warn_ptr_int_conv), + "align_array_members", OPT_OFFSET(align_array_members), + "dont_reuse_strings", OPT_OFFSET(dont_reuse_strings), + "pool_strings", OPT_OFFSET(pool_strings), + "explicit_zero_data", OPT_OFFSET(explicit_zero_data), + "readonly_strings", OPT_OFFSET(readonly_strings), + "opt_common_subs", OPT_OFFSET(opt_common_subs), + "opt_loop_invariants", OPT_OFFSET(opt_loop_invariants), + "opt_propagation", OPT_OFFSET(opt_propagation), + "opt_unroll_loops", OPT_OFFSET(opt_unroll_loops), + "opt_lifetimes", OPT_OFFSET(opt_lifetimes), + "opt_strength_reduction", OPT_OFFSET(opt_strength_reduction), + "opt_strength_reduction_strict", OPT_OFFSET(opt_strength_reduction_strict), + "opt_dead_code", OPT_OFFSET(opt_dead_code), + "opt_dead_assignments", OPT_OFFSET(opt_dead_assignments), + "opt_vectorize_loops", OPT_OFFSET(opt_vectorize_loops), + "opt_pointer_analysis", OPT_OFFSET(opt_pointer_analysis), + "exceptions", OPT_OFFSET(exceptions), + "dont_inline", OPT_OFFSET(dont_inline), + "always_inline", OPT_OFFSET(always_inline), + "optimize_for_size", OPT_OFFSET(optimize_for_size), + "peephole", OPT_OFFSET(peephole), + "global_optimizer", OPT_OFFSET(global_optimizer), + "side_effects", OPT_OFFSET(side_effects), + "internal", OPT_FLAG_2000 | OPT_OFFSET(internal), + "import", OPT_FLAG_2000 | OPT_OFFSET(import), + "export", OPT_FLAG_2000 | OPT_OFFSET(export), + "lib_export", OPT_FLAG_2000 | OPT_OFFSET(lib_export), + "nosyminline", OPT_OFFSET(nosyminline), + "force_active", OPT_OFFSET(force_active), + "sym", OPT_OFFSET(isGeneratingDebugInfo), + NULL, 0 +}; + +CParams *cparamblkptr; +short tk; +CInt64 tkintconst; +Float tkfloatconst; +char *tkstring; +HashNameNode *tkidentifier; +SInt32 tksize; +short ispascalstring; +short nlflag; +SInt32 lines; +Boolean spaceskip; +Macro **macrohashtable; +Boolean cprep_nomem_exit; +Boolean cprep_nostring; +Boolean cprep_eoltokens; +static void *ifstack[100]; // TODO type+size +static short iflevel; +TokenStack tokenstack[128]; +short tokenstacklevel; +SInt32 cprep_cursymfile; // might be a ptr? +char *pos; +char *macropos; +char *nextcharpos; +char CPrep_SkipNewCommentChar; +Boolean preprocessing_only; +Handle stringmem; +SInt32 maxstringsize; +char cprep_idarray[256]; +Boolean was_escchar; +Boolean macrocheck; +Boolean widestring; +Boolean at_linestart; +char *prep_file_start; +char *prep_file_end; +char *macrostart; +Boolean cprep_strconcat; +CPrepFileInfo *prep_file; +short filesp; +SInt32 linenumber; +static CPrepFileInfo *filestack[32]; +static void *cprep_files; // TODO type +static SInt32 linetick; +static Boolean waslockedmacro; +static Boolean include_once; +static time_t now_time; +static SInt32 lineoffset; +static Boolean was_prep_error; +static Boolean cprep_hasprepline; +static Boolean cprep_incondexpr; +static void *cprep_packstack[100]; // TODO type+size +static short cprep_packstackp; +static Macro lineM; +static Macro fileM; +static Macro dateM; +static Macro timeM; +static Macro stdcM; +static Macro stcvM; +static Macro stchM; +static Macro casmM; +static Macro cpplM; +static Macro MWRSM; +static Macro dtsomM; +static Macro ecppM; +static Macro optiM; +static Macro trgtM; +GList pplist; +struct COptsPush { + struct COptsPush *next; + COpts opts; +}; +static struct COptsPush *coptpushs; +static void *coptpush; // TODO type +static void *coptssave; // TODO type +static Boolean dofreeaheap; +static GList mlist; +static Handle ts_buffer; +static TStreamElement *ts_first; +static TStreamElement *ts_last; +TStreamElement *ts_current; +static SInt32 ts_elements; +SInt32 ts_preread_elements; +static SInt32 gDirectiveStart; +static SInt32 high_mem_mark; +// static TStreamElement dummyelement; // in CPrep_CurStreamElement +static short exprtk; + +static void cannotopenerror(StringPtr filename, Boolean err) { + static char fname[64]; + + short len = filename[0]; + if (len > 63) + len = 63; + memcpy(fname, filename + 1, len); + fname[len] = 0; + + CError_ResetErrorSkip(); + + if (prep_file) { + was_prep_error = 1; + CError_Error(151, fname); + if (err) + longjmp(errorreturn, 1); + } else { + CError_CannotOpen(); + } +} + +static void insertmacro(Macro *macro) { + macro->next = macrohashtable[macro->name->hashval]; + macrohashtable[macro->name->hashval] = macro; + macro->xF = 0; +} + +void CPrep_InsertSpecialMacro(Macro *macro, char *name) { + macro->name = GetHashNameNodeExport(name); + macro->is_special = 1; + insertmacro(macro); +} + +void CPrep_InsertSpecialMacros() { + CPrep_InsertSpecialMacro(&lineM, "__LINE__"); + CPrep_InsertSpecialMacro(&fileM, "__FILE__"); + CPrep_InsertSpecialMacro(&dateM, "__DATE__"); + CPrep_InsertSpecialMacro(&timeM, "__TIME__"); + CPrep_InsertSpecialMacro(&stdcM, "__STDC__"); + CPrep_InsertSpecialMacro(&stcvM, "__STDC_VERSION__"); + CPrep_InsertSpecialMacro(&stchM, "__STDC_HOSTED__"); + CPrep_InsertSpecialMacro(&casmM, "__CASM__"); + CPrep_InsertSpecialMacro(&cpplM, "__cplusplus"); + CPrep_InsertSpecialMacro(&MWRSM, "__MWERKS__"); + CPrep_InsertSpecialMacro(&dtsomM, "__SOM_ENABLED__"); + CPrep_InsertSpecialMacro(&ecppM, "__embedded_cplusplus"); + CPrep_InsertSpecialMacro(&optiM, "__option"); + CPrep_InsertSpecialMacro(&trgtM, "__ide_target"); + CodeGen_InsertSpecialMacros(); +} + +void CPrep_RemoveSpecialMacros() { + Macro **scan; + int x; + + for (x = 0; x < 2048; x++) { + scan = ¯ohashtable[x]; + while (*scan) { + if ((*scan)->is_special) { + *scan = (*scan)->next; + } else { + scan = &(*scan)->next; + } + } + } +} + +static void CPrep_Reconfig() { + cprep_idarray['$'] = copts.dollar_identifiers != 0; +} + +Boolean setupprep() { + int x; + + now_time = time(NULL); + lineoffset = 0; + include_once = 0; + cprep_eoltokens = 0; + cprep_nostring = 0; + cprep_incondexpr = 0; + filesp = -1; + linetick = 0; + lines = 0; + dofreeaheap = 1; + macrocheck = 1; + maxstringsize = 256; + iflevel = 0; + tokenstacklevel = 0; + cprep_cursymfile = 0; + cprep_files = 0; + CLT_filesp = &filesp; + CLT_filestack = filestack; + anyerrors = 0; + fatalerrors = 0; + was_prep_error = 0; + cprep_strconcat = 0; + + GListErrorProc = CError_NoMem; + mlist.data = NULL; + pplist.data = NULL; + if (InitGList(&mlist, 10000)) + CError_NoMem(); + + stringmem = COS_NewHandle(256); + if (!stringmem) + CError_NoMem(); + ts_buffer = COS_NewHandle(1024 * sizeof(TStreamElement)); + if (!ts_buffer) + CError_NoMem(); + COS_LockHandleHi(ts_buffer); + ts_first = (TStreamElement *) *ts_buffer; + ts_last = ts_first + 1023; + ts_current = ts_first; + ts_elements = 1024; + ts_preread_elements = 0; + + macrohashtable = galloc(sizeof(Macro *) * 2048); + memclrw(macrohashtable, sizeof(Macro *) * 2048); + CPrep_InsertSpecialMacros(); + + for (x = 0; x < 256; x++) + cprep_idarray[x] = 0; + + for (x = 'a'; ; x++) { + cprep_idarray[x] = 1; + if (x == 'z') break; + } + + for (x = 'A'; ; x++) { + cprep_idarray[x] = 1; + if (x == 'Z') break; + } + + for (x = '0'; ; x++) { + cprep_idarray[x] = 2; + if (x == '9') break; + } + + cprep_idarray['_'] = 1; + + CPrep_Reconfig(); + return 0; +} + +void cleanupprep() { + while (filesp >= 0) + popfile(); + + high_mem_mark = CTool_TotalHeapSize(); + releaseheaps(); + GListErrorProc = NULL; + FreeGList(&mlist); + FreeGList(&pplist); + + if (stringmem) { + COS_FreeHandle(stringmem); + stringmem = NULL; + } + + if (ts_buffer) { + COS_FreeHandle(ts_buffer); + ts_buffer = NULL; + } + ts_current = NULL; + ts_first = ts_last = NULL; +} + +static char *getfiledata(FSSpec *spec) { + const char *text; + SInt32 textlength; + short filedatatype; + + if (CWGetFileText(cparamblkptr->context, spec, &text, &textlength, &filedatatype) != cwNoErr) { + Str255 filename; + COS_FileGetFSSpecInfo(spec, NULL, NULL, filename); + cannotopenerror(filename, 1); + return NULL; + } else { + return (char *) text; + } +} + +static Boolean setupfile(StringPtr filename, Boolean flag1, Boolean flag2) { + CPrepFileInfo prepinfo; + CWFileInfo fileinfo; + Str255 file_filename; + char myfilename[256]; + OSType file_type; + SInt32 file_size; + SInt32 file_dirid; + CWMemHandle cache_hnd; + void *cache; + SInt16 refnum; + SInt16 file_vrefnum; + char *extpos; + + if (filesp >= 31) { + was_prep_error = 1; + CError_ErrorTerm(243); + return 0; + } + + memclrw(&prepinfo, sizeof(CPrepFileInfo)); + prepinfo.unkfield126 = !flag1; // may be wrong field! + if (filename) { + memclrw(&fileinfo, sizeof(CWFileInfo)); + fileinfo.fullsearch = flag2; + fileinfo.dependencyType = cwNormalDependency; + fileinfo.isdependentoffile = -1; + memcpy(myfilename, &filename[1], filename[0]); + myfilename[filename[0]] = 0; + + if (CWFindAndLoadFile(cparamblkptr->context, myfilename, &fileinfo) != cwNoErr) { + if (filename[0] + strlen(".framework/Headers") < 255) { + if ((extpos = strchr(myfilename, '/'))) { + // Do Me! 37D8C + } else { + cannotopenerror(filename, 0); + return 0; + } + } else { + cannotopenerror(filename, 0); + return 0; + } + } + + if ((flag2 || include_once) && fileinfo.alreadyincluded) + return 1; + + prepinfo.textfile = fileinfo.filespec; + prepinfo.nameNode = CTool_GetPathName(&fileinfo.filespec, &prepinfo.fileModDate); + if (fileinfo.filedata) { + if (fileinfo.filedatatype == cwFileTypeText) { + prepinfo.textbuffer = (char *) fileinfo.filedata; + prepinfo.textlength = fileinfo.filedatalength; + prepinfo.fileID = fileinfo.fileID; + prepinfo.recordbrowseinfo = fileinfo.recordbrowseinfo; + } else if (fileinfo.filedatatype == cwFileTypePrecompiledHeader) { + PrecompilerRead(0, (void *) fileinfo.filedata); + return 1; + } else { + cannotopenerror(filename, 0); + return 0; + } + } else { + COS_FileGetFSSpecInfo(&prepinfo.textfile, &file_vrefnum, &file_dirid, file_filename); + if (COS_FileOpen(&prepinfo.textfile, &refnum)) { + cannotopenerror(filename, 0); + return 0; + } + if (COS_FileGetType(&prepinfo.textfile, &file_type) || COS_FileGetSize(refnum, &file_size)) { + COS_FileClose(refnum); + cannotopenerror(filename, 0); + return 0; + } + if (file_type == copts.pchType) { + if (cparamblkptr->isCachingPrecompiledHeaders) { + if (CWAllocMemHandle(cparamblkptr->context, file_size, 1, &cache_hnd) != cwNoErr) { + if (CWAllocMemHandle(cparamblkptr->context, file_size, 0, &cache_hnd) != cwNoErr) { + COS_FileClose(refnum); + CError_NoMem(); + } + } + + CWLockMemHandle(cparamblkptr->context, cache_hnd, 0, &cache); + if (COS_FileRead(refnum, cache, file_size)) { + COS_FileClose(refnum); + CWFreeMemHandle(cparamblkptr->context, cache_hnd); + cannotopenerror(filename, 0); + return 0; + } + COS_FileClose(refnum); + CWCachePrecompiledHeader(cparamblkptr->context, &prepinfo.textfile, cache_hnd); + PrecompilerRead(0, cache); + CWUnlockMemHandle(cparamblkptr->context, cache_hnd); + return 1; + } else { + PrecompilerRead(refnum, 0); + COS_FileClose(refnum); + return 1; + } + } else { + COS_FileClose(refnum); + cannotopenerror(filename, 0); + return 0; + } + } + } else { + if (!cparamblkptr->mainFileText) { + COS_FileGetFSSpecInfo(&cparamblkptr->mainFileSpec, &file_vrefnum, &file_dirid, file_filename); + cannotopenerror(file_filename, 1); + return 0; + } + + prepinfo.textfile = cparamblkptr->mainFileSpec; + prepinfo.textbuffer = (char *) cparamblkptr->mainFileText; + prepinfo.textlength = cparamblkptr->mainFileTextLength; + prepinfo.fileID = cparamblkptr->mainFileID; + prepinfo.recordbrowseinfo = cparamblkptr->field276; + } + + if (filesp >= 0) { + filestack[filesp]->linenumber = linenumber; + filestack[filesp]->hasprepline = cprep_hasprepline; + filestack[filesp]->pos = pos - filestack[filesp]->textbuffer; + } + + pos = prepinfo.textbuffer; + linenumber = 1; + at_linestart = 1; + filestack[++filesp] = galloc(sizeof(CPrepFileInfo)); + *filestack[filesp] = prepinfo; + prep_file = filestack[filesp]; + prep_file_start = prep_file->textbuffer; + prep_file_end = prep_file->textbuffer + prep_file->textlength; + if (preprocessing_only && !copts.simple_prepdump) + CPrep_PreprocessDumpFileInfo(1); + + return 1; +} + +void CPrep_TSBufferGrow(int amount) { + int current_offset = ts_current - ts_first; + COS_UnlockHandle(ts_buffer); + if (!COS_ResizeHandle(ts_buffer, sizeof(TStreamElement) * (ts_elements + amount))) + CError_NoMem(); + COS_LockHandleHi(ts_buffer); + ts_elements += amount; + ts_first = (TStreamElement *) *ts_buffer; + ts_last = ts_first + (ts_elements - 1); + ts_current = ts_first + current_offset; +} + +void CPrep_TokenStreamGetState(SInt32 *state) { + *state = ts_current - ts_first; +} + +void CPrep_TokenStreamSetState(SInt32 *state) { + ts_preread_elements += ts_current - ts_first - *state; + ts_current = ts_first + *state; +} + +void CPrep_UnLex() { + ++ts_preread_elements; + --ts_current; +#line 900 + CError_ASSERT(ts_current >= ts_first); +} + +void CPrep_TokenStreamSetCurState(SInt32 *state) { + ts_preread_elements += ts_current - ts_first - (*state - 1); + ts_current = ts_first + (*state - 1); + tk = lex(); +} + +static void CPrep_StreamSkipToBrace() {} +static void CPrep_StreamSkipBlock() {} +void CPrep_StreamGetBlock() {} +void CPrep_StreamGetSemicolon() {} +void CPrep_StreamGetTemplate() {} +void CPrep_StreamInsert() {} +void CPrep_StreamRemove() {} +void CPrep_RemoveTokens() {} +void CPrep_TokenStreamFlush() {} +static void CPrep_TokenSize() {} +void CPrep_CurStreamElement() {} + +void CPrep_GetTokenContext(TStreamElement *token, CPrepFileInfo **tokenfile, SInt32 *selectionoffset, short *tokensize, SInt32 *linenumber, char *buf1, short *tokenoffset, short *tokenlength, char *buf2, short *lastarg) { +} + +void CPrep_Error(short code) { + Boolean save = in_assembler; + in_assembler = 0; + if (code == 102 && (tokenstacklevel > 0 || pos < prep_file_end)) + code = 105; + was_prep_error = 1; + CError_Error(code); + in_assembler = save; +} + +void CPrep_ErrorName(short code, const char *name) { + Boolean save = in_assembler; + in_assembler = 0; + was_prep_error = 1; + if (code == 102 && (tokenstacklevel > 0 || pos < prep_file_end)) + CError_Error(105, name); + else + CError_Error(code, name); + in_assembler = save; +} + +void CPrep_Warning(short code) { + Boolean save = in_assembler; + in_assembler = 0; + was_prep_error = 1; + CError_Warning(code); + in_assembler = save; +} + +void CPrep_WarningName(short code, const char *name) { + Boolean save = in_assembler; + in_assembler = 0; + was_prep_error = 1; + CError_Warning(code, name); + in_assembler = save; +} + +void CPrep_ErrorMessage(int errTable, char *str, Boolean flag1, Boolean flag2) { + Boolean save = in_assembler; + in_assembler = 0; + was_prep_error = 1; + CError_ErrorMessage(errTable, str, flag1, flag2); + in_assembler = save; +} + +void CPrep_ErrorMessageVA(int code, const char *format, va_list list, Boolean flag1, Boolean flag2) { + Boolean save = in_assembler; + in_assembler = 0; + was_prep_error = 1; + CError_ErrorMessageVA(code, format, list, flag1, flag2); + in_assembler = save; +} + +void popfile() { + // r5 and r6 are swapped, not sure why + if (filesp >= 0) { + CWReleaseFileText(cparamblkptr->context, prep_file->textbuffer); + prep_file->textbuffer = NULL; + if (--filesp >= 0) { + prep_file = filestack[filesp]; + prep_file_start = prep_file->textbuffer; + prep_file_end = prep_file->textbuffer + prep_file->textlength; + pos = prep_file_start + prep_file->pos; + linenumber = prep_file->linenumber; + cprep_hasprepline = prep_file->hasprepline; + at_linestart = 1; + } + if (preprocessing_only && !copts.simple_prepdump) + CPrep_PreprocessDumpFileInfo(1); + } +} + +static void prepoffset() {} +static void prepoffset2() {} +void CPrep_SetSourceFile() {} +void CPrep_GetSourceFilePath() {} +void CPrep_NewFileOffsetInfo() {} +void CPrep_GetFileOffsetInfo() {} +void CPrep_GetFileOffsetInfo2() {} +void CPrep_ResetFileInfo() {} +void CPrep_GetPrepPos() {} +Boolean C_Compiler(CParams *param) {} + +static void pushtokenseq(Macro *macro) { + if (tokenstacklevel >= 128) { + was_prep_error = 1; + CError_ErrorTerm(111); + } else { + tokenstack[tokenstacklevel].pos = pos; + tokenstack[tokenstacklevel].macrostart = macrostart; + tokenstack[tokenstacklevel].macro = macro; + if (macro) + macro->xF = 1; + tokenstack[tokenstacklevel].macrocheck = macrocheck; + tokenstacklevel++; + } +} + +void poptokenseq() { + if (!--tokenstacklevel && dofreeaheap) + freeaheap(); + + pos = tokenstack[tokenstacklevel].pos; + macrostart = tokenstack[tokenstacklevel].macrostart; + if (tokenstack[tokenstacklevel].macro) + tokenstack[tokenstacklevel].macro->xF = 0; + macrocheck = tokenstack[tokenstacklevel].macrocheck; + spaceskip = 1; +} + +static void is_nextchar() {} +static void ismacroname() {} +static void ismacroname2() {} +static void ismacroname5() {} +static void ismacroname3() {} +static void ismacroname4() {} +void foundnl() {} +void newline() {} +static void gotonexttoken() {} +short notendofline() {} +static void CPrep_MacroRedefError() {} +static void goendofline() {} +static void CPrep_Define() {} +static void prepundefine() {} +static Boolean CPrep_CheckTarget() {} +static Boolean CPrep_CheckOption() {} +static void CPrep_XpandDefinedCheck() {} +static void XpandString() {} +char *CPrep_GetFileName(char *buffer, Boolean flag1, Boolean flag2) { +} + +static char *XpandSpecialMacro(Macro *macro) { + char buf[512]; + char smallbuf[32]; + char *strptr; + struct tm *tm; + + if (macro == &optiM) { + return CPrep_CheckOption() ? "1" : "0"; + } else if (macro == &trgtM) { + return CPrep_CheckTarget() ? "1" : "0"; + } else if (macro == &lineM) { + sprintf(buf, "%ld", linenumber); + do_string: + strptr = aalloc(strlen(buf) + 1); + strcpy(strptr, buf); + return strptr; + } else if (macro == &fileM) { + CPrep_GetFileName(buf, 0, 1); + goto do_string; + } else if (macro == &dateM) { + tm = localtime(&now_time); + strftime(buf, 64, "\"%b ", tm); + strftime(smallbuf, 32, "%d", tm); + if (smallbuf[0] == '0') + smallbuf[0] = ' '; + strcat(buf, smallbuf); + strftime(smallbuf, 32, " %Y\"", tm); + strcat(buf, smallbuf); + goto do_string; + } else if (macro == &timeM) { + strftime(buf, 64, "\"%H:%M:%S\"", localtime(&now_time)); + goto do_string; + } else if (macro == &stdcM) { + return "1"; + } else if (macro == &casmM || macro == &MWRSM) { + return "0x2405"; + } else if (macro == &cpplM) { + return "199711L"; + } else if (macro == &dtsomM) { + return copts.direct_to_som ? "1" : "0"; + } else if (macro == &ecppM) { + return copts.ecplusplus ? "1" : "0"; + } else if (macro == &stcvM) { + return copts.c9x ? "199901L" : "199409L"; + } else if (macro == &stchM) { + return "0"; + } else { + return CodeGen_ExpandSpecialMacro(macro); + } +} + +static void XpandMacro() {} +static void prepmacro() {} +void macrotest() {} +void CPrep_PragmaLex() {} +void CPrep_PushOption() {} +void CPrep_PopOption() {} +static void CPrep_PragmaImExport() {} +static void pragma_on_off_reset() {} +static void CPrep_PragmaOnceName() {} +static void pragma_precompile_target() {} +static void CPrep_DefinePragmaOnceMacro() {} +static void CPrep_PragmaOnce() {} +static void CPrep_PragmaUnused() {} +static void CPrep_PragmaInlineDepth() {} +static void CPrep_PragmaInlineMaxSize() {} +static void CPrep_PragmaInlineMaxTotalSize() {} + +static void pragma_segment() { + short i; + short t; + char name[256]; + + if (notendofline()) { + for (i = 0; i < 255; i++) { + spaceskip = 0; + t = prepskipnextchar(); + if (spaceskip) + break; + if (t <= ' ') + break; + name[i] = t; + pos = nextcharpos; + } + name[i] = 0; + + if (!i || i >= 255) + CPrep_Warning(186); + + copts.forcedSegment = GetHashNameNodeExport(name); + ObjGen_SegmentName(); + } else { + if (copts.warn_illpragma) + CPrep_Warning(186); + } +} + +static void pragma_options() {} + +static void pragma_push() { + struct COptsPush *push; + + push = galloc(sizeof(struct COptsPush)); + push->next = coptpushs; + coptpushs = push; + + push->opts = copts; +} + +static void pragma_pop() { + if (coptpushs) { + copts = coptpushs->opts; + coptpushs = coptpushs->next; + CMach_Configure(); + } else { + CPrep_Error(237); + } +} + +static void pragma_overload() {} +static void pragma_optimization_level() {} +static void pragma_opt_unroll_count() {} +static void pragma_opt_unroll_instr_count() {} +static void pragma_pack() {} +static void pragma_comment() {} +static void pragma_message() {} +static void preppragma() {} +static void prepinclude() {} +static void prepline() {} +static void CPrep_GetPrepType() {} +static void CPrep_ParseUnary() {} +static void CPrep_ParseBinary() {} +static void CPrep_ParseCond() {} +static void doevalconstexpr() {} +static void pushifstate() {} +static void popifstate() {} +static void positiveif() {} +static void negativeif() {} +static void prepif() {} +static void prepifdef() {} +static void prepifndef() {} +static void prepelif() {} +static void prepelse() {} +static void prependif() {} +static void prepifskip() {} +void preprocessor() {} +void CPrep_BrowserTokenOffset() {} +void CPrep_BrowserFileOffset() {} + +void CPrep_BrowserFilePosition(CPrepFileInfo **fileinfo, SInt32 *offset) { + CPrepFileInfo *file; + + if (ts_first < ts_current) { + file = ts_current[-1].tokenfile; + *offset = ts_current[-1].tokenoffset + 1; + } else { + file = filestack[filesp]; + if (tokenstacklevel) { + *offset = tokenstack[0].pos - filestack[filesp]->textbuffer; + } else { + *offset = pos - filestack[filesp]->textbuffer; + } + } + + if (file && file->fileID > 0 && (file->recordbrowseinfo || gForceSourceLoc)) { + *fileinfo = file; + } else { + *fileinfo = NULL; + *offset = 0; + } +} + +CPrepFileInfo *CPrep_BrowserCurrentFile() { + return prep_file; +} diff --git a/compiler_and_linker/FrontEnd/C/CPrepTokenizer.c b/compiler_and_linker/FrontEnd/C/CPrepTokenizer.c new file mode 100644 index 0000000..5b77268 --- /dev/null +++ b/compiler_and_linker/FrontEnd/C/CPrepTokenizer.c @@ -0,0 +1,166 @@ +#include "compiler.h" +#include "compiler/tokens.h" + +static Boolean prepnextstringchar_foundnl; + +short prepskipnextchar() { + +} + +short prepnextchar() { + +} + +short prepnextstringchar(char *str, Boolean flag) { + +} + +void CPrep_MatchChar(char ch, Boolean flag) { + +} + +char *CPrep_MatchChar2(char *str, char ch, Boolean flag) { + +} + +short prepcurchar() { + +} + +static short prepcurstringchar(char *str) { +} + +static void prepcurstringchar_skip() { +} + +char *ReadIdentifier(char *str) { +} + +static short intsuffix(short token, Boolean flag) { +} + +static short floatsuffix(short token) { +} + +static short tohex(short token) { +} + +static short nextchar(char *str) { +} + +char *CPrep_SkipNewComment(char *str) { + +} + +Boolean skipendoflinematch(char *str, Boolean flag) { +} + +void skipendofline() { +} + +void CPrep_SkipAsmComment() { +} + +static short tille() {} +static short tcret() {} +static short tapos() {} +static short tquot() {} +static short thash() {} +static short tmult() {} +static short tcolo() {} +static short tless() {} +static short tequa() {} +static short tgrea() {} +static short tatsg() {} +static short tperc() {} +static short texcl() {} +static short tplus() {} +static short tminu() {} +static short torrr() {} +static short tampe() {} +static short tpowe() {} +static short tdivi() {} +static short tzero() {} +static short tpoin() {} +static short tnumb() {} +static short tiden() {} +static short tchrL() {} +static short tchra() {} +static short tchrb() {} +static short tchrc() {} +static short tchrd() {} +static short tchre() {} +static short tchrf() {} +static short tchrg() {} +static short tchri() {} +static short tchrl() {} +static short tchrm() {} +static short tchrn() {} +static short tchro() {} +static short tchrp() {} +static short tchrr() {} +static short tchrs() {} +static short tchrt() {} +static short tchru() {} +static short tchrv() {} +static short tchrw() {} +static short tchrx() {} +static short tchr_() {} +static short token() {} +static short tdoll() {} +static short tisid() {} +static short tnull() {} +static short t0x1a() {} + +static short (*cprep_tokenize[256])() = { + &tnull, &tille, &tille, &tille, &tisid, &tisid, &tille, &tille, + &tille, &tille, &tille, &tille, &tille, &tcret, &tille, &tille, + &tille, &tille, &tille, &tille, &tille, &tille, &tille, &tille, + &tille, &tille, &t0x1a, &tille, &tille, &tille, &tille, &tille, + &tille, &texcl, &tquot, &thash, &tdoll, &tperc, &tampe, &tapos, + &token, &token, &tmult, &tplus, &token, &tminu, &tpoin, &tdivi, + &tzero, &tnumb, &tnumb, &tnumb, &tnumb, &tnumb, &tnumb, &tnumb, + &tnumb, &tnumb, &tcolo, &token, &tless, &tequa, &tgrea, &token, + &tatsg, &tiden, &tiden, &tiden, &tiden, &tiden, &tiden, &tiden, + &tiden, &tiden, &tiden, &tiden, &tchrL, &tiden, &tchrn, &tiden, + &tchrp, &tiden, &tiden, &tiden, &tiden, &tiden, &tiden, &tiden, + &tchrx, &tiden, &tiden, &token, &token, &token, &tpowe, &tchr_, + &token, &tchra, &tchrb, &tchrc, &tchrd, &tchre, &tchrf, &tchrg, + &tiden, &tchri, &tiden, &tiden, &tchrl, &tchrm, &tchrn, &tchro, + &tchrp, &tiden, &tchrr, &tchrs, &tchrt, &tchru, &tchrv, &tchrw, + &tchrx, &tiden, &tiden, &token, &torrr, &token, &token, &tille, + &tille, &tille, &tille, &tille, &tille, &tille, &tille, &tille, + &tille, &tille, &tille, &tille, &tille, &tille, &tille, &tille, + &tille, &tille, &tille, &tille, &tille, &tille, &tille, &tille, + &tille, &tille, &tille, &tille, &tille, &tille, &tille, &tille, + &tille, &tille, &tille, &tille, &tille, &tille, &tille, &tille, + &tille, &tille, &tille, &tille, &tille, &tille, &tille, &tille, + &tille, &tille, &tille, &tille, &tille, &tille, &tille, &tille, + &tille, &tille, &tille, &tille, &tille, &tille, &tille, &tille, + &tille, &tille, &tille, &tille, &tille, &tille, &tille, &tille, + &tille, &tille, &tille, &tille, &tille, &tille, &tille, &tille, + &tille, &tille, &tille, &tille, &tille, &tille, &tille, &tille, + &tille, &tille, &tille, &tille, &tille, &tille, &tille, &tille, + &tille, &tille, &tille, &tille, &tille, &tille, &tille, &tille, + &tille, &tille, &tille, &tille, &tille, &tille, &tille, &tille, + &tille, &tille, &tille, &tille, &tille, &tille, &tille, &tille, + &tille, &tille, &tille, &tille, &tille, &tille, &tille, &tille +}; + +short lookahead() { +} + +short lookahead_noeol() { +} + +static void CPrep_StringConCat(Boolean flag) { +} + +short lex() { +} + +short plex() { +} + +short lexidentifier() { +} diff --git a/compiler_and_linker/FrontEnd/C/CScope.c b/compiler_and_linker/FrontEnd/C/CScope.c new file mode 100644 index 0000000..7423c07 --- /dev/null +++ b/compiler_and_linker/FrontEnd/C/CScope.c @@ -0,0 +1,2690 @@ +#include "compiler.h" +#include "compiler/CError.h" +#include "compiler/enode.h" +#include "compiler/objects.h" +#include "compiler/scopes.h" +#include "compiler/templates.h" +#include "compiler/types.h" + +static Boolean cscope_isambig; +static UInt8 cscope_lookuptype; +static SInt32 cscope_foundclassoffset; +static TemplClass *cscope_foundtemplate; +static TypeClass *cscope_foundclass; +static HashNameNode *cscope_name; +static TypeClass *cscope_mostderived; +Boolean cscope_is_member_func; +Object *cscope_currentfunc; +TypeClass *cscope_currentclass; +NameSpace *cscope_current; +NameSpace *cscope_root; + +void CScope_Setup() { + cscope_current = cscope_root = CScope_NewHashNameSpace(0); + cscope_currentclass = NULL; + cscope_currentfunc = NULL; + cscope_is_member_func = 0; +} + +void CScope_Cleanup() { +} + +void CScope_GetScope(CScopeSave *save) { + save->current = cscope_current; + save->currentclass = cscope_currentclass; + save->currentfunc = cscope_currentfunc; + save->is_member_func = cscope_is_member_func; +} + +void CScope_SetNameSpaceScope(NameSpace *nspace, CScopeSave *save) { + save->current = cscope_current; + save->currentclass = cscope_currentclass; + save->currentfunc = cscope_currentfunc; + save->is_member_func = cscope_is_member_func; + + cscope_current = nspace; + cscope_currentclass = nspace->theclass; + cscope_currentfunc = NULL; + cscope_is_member_func = 0; +} + +void CScope_SetClassScope(TypeClass *cls, CScopeSave *save) { + save->current = cscope_current; + save->currentclass = cscope_currentclass; + save->currentfunc = cscope_currentfunc; + save->is_member_func = cscope_is_member_func; + + cscope_current = cls->nspace; + cscope_currentclass = cls; + cscope_currentfunc = NULL; + cscope_is_member_func = 0; +} + +void CScope_SetClassDefScope(TypeClass *cls, CScopeSave *save) { + save->current = cscope_current; + save->currentclass = cscope_currentclass; + save->currentfunc = cscope_currentfunc; + save->is_member_func = cscope_is_member_func; + + cscope_current = cls->nspace; + cscope_currentclass = cls; +} + +void CScope_SetFunctionScope(Object *function, CScopeSave *save) { + save->current = cscope_current; + save->currentclass = cscope_currentclass; + save->currentfunc = cscope_currentfunc; + save->is_member_func = cscope_is_member_func; + + cscope_currentfunc = function; + cscope_currentclass = NULL; + cscope_is_member_func = 0; + + if (TYPE_FUNC(function->type)->flags & FUNC_FLAGS_METHOD) { + cscope_currentclass = TYPE_METHOD(function->type)->theclass; + cscope_current = cscope_currentclass->nspace; + cscope_is_member_func = TYPE_METHOD(function->type)->x26 == 0; + } else { + cscope_current = function->nspace; + } +} + +void CScope_SetMethodScope(Object *function, TypeClass *cls, Boolean unknownFlag, CScopeSave *save) { + save->current = cscope_current; + save->currentclass = cscope_currentclass; + save->currentfunc = cscope_currentfunc; + save->is_member_func = cscope_is_member_func; + + cscope_currentfunc = function; + cscope_currentclass = cls; + cscope_current = cls->nspace; + cscope_is_member_func = !unknownFlag; +} + +void CScope_RestoreScope(CScopeSave *saved) { + cscope_current = saved->current; + cscope_currentclass = saved->currentclass; + cscope_currentfunc = saved->currentfunc; + cscope_is_member_func = saved->is_member_func; +} + +static Boolean CScope_ObjectIsFunction(Object *obj) { + return obj->otype == OT_OBJECT && obj->type->type == TYPEFUNC; +} + +Boolean CScope_IsEmptySymTable() { + NameSpaceObjectList *scan; + NameSpaceName *nsname; + int i; + +#line 232 + CError_ASSERT(cscope_root->is_hash); + + i = 0; + do { + for (nsname = cscope_root->data.hash[i]; nsname; nsname = nsname->next) { + for (scan = &nsname->first; scan; scan = scan->next) { + if (scan->object->otype != OT_OBJECT || !CParser_IsPublicRuntimeObject(OBJECT(scan->object))) + return 0; + } + } + } while (++i < 1024); + + return 1; +} + +Boolean CScope_IsInLocalNameSpace(NameSpace *nspace) { + while (nspace) { + if (!nspace->is_global && !nspace->is_templ) + return 1; + nspace = nspace->parent; + } + return 0; +} + +static void CScope_AppendNameSpaceName(NameSpaceName *nsn) { + if (nsn->next) + CScope_AppendNameSpaceName(nsn->next); + if (nsn->name) { + AppendGListName(&name_mangle_list, nsn->name->name); + AppendGListName(&name_mangle_list, "::"); + } +} + +static void CScope_AmbigNameError(NameSpace *nspace1, NameSpace *nspace2, HashNameNode *name) { + if (name && nspace1 != nspace2) { + CError_Error(319, CError_GetNameString(nspace1, name), CError_GetNameString(nspace2, name)); + } else { + CError_Error(188, nspace2); + } +} + +NameSpaceObjectList *CScope_FindName(NameSpace *nspace, HashNameNode *name) { + NameSpaceName *scan; + + for (scan = nspace->tparams; scan; scan = scan->next) { + if (scan->name == name) + return &scan->first; + } + + if (!nspace->is_hash) + scan = nspace->data.list; + else + scan = nspace->data.hash[name->hashval & 1023]; + + for (; scan; scan = scan->next) { + if (scan->name == name) + return &scan->first; + } + + return NULL; +} + +static NameSpaceObjectList *CScope_FindQualName(NameSpace *nspace, HashNameNode *name) { + NameSpaceName *scan; + + if (!nspace->is_hash) + scan = nspace->data.list; + else + scan = nspace->data.hash[name->hashval & 1023]; + + for (; scan; scan = scan->next) { + if (scan->name == name) + return &scan->first; + } + + return NULL; +} + +NameSpaceName *CScope_FindNameSpaceName(NameSpace *nspace, HashNameNode *name) { + NameSpaceName *scan; + + for (scan = nspace->tparams; scan; scan = scan->next) { + if (scan->name == name) + return scan; + } + + if (!nspace->is_hash) + scan = nspace->data.list; + else + scan = nspace->data.hash[name->hashval & 1023]; + + for (; scan; scan = scan->next) { + if (scan->name == name) + return scan; + } + + return NULL; +} + +NameSpaceObjectList *CScope_InsertName(NameSpace *nspace, HashNameNode *name) { + NameSpaceName **nsnptr; + NameSpaceName *nsname; + if (nspace->is_global) + nsname = galloc(sizeof(NameSpaceName)); + else + nsname = lalloc(sizeof(NameSpaceName)); + + nsname->name = name; + nsname->first.next = NULL; + nsname->first.object = NULL; + if (nspace->is_hash) { + nsnptr = &nspace->data.hash[name->hashval & 0x3FF]; + nsname->next = *nsnptr; + *nsnptr = nsname; + } else { + nsname->next = nspace->data.list; + nspace->data.list = nsname; + } + nspace->names++; + + return &nsname->first; +} + +static NameSpaceObjectList *CScope_AppendName(NameSpace *nspace, HashNameNode *name) { + NameSpaceName *nsname; + NameSpaceName *scan; +#line 387 + CError_ASSERT(!nspace->is_hash); + + if (nspace->is_global) + nsname = galloc(sizeof(NameSpaceName)); + else + nsname = lalloc(sizeof(NameSpaceName)); + + nsname->next = NULL; + nsname->name = name; + nsname->first.next = NULL; + nsname->first.object = NULL; + if (nspace->data.list) { + scan = nspace->data.list; + while (scan->next) + scan = scan->next; + scan->next = nsname; + } else { + nspace->data.list = nsname; + } + nspace->names++; + + return &nsname->first; +} + +static NameSpaceList *CScope_AddNameSpaceToList(NameSpaceList *list, NameSpace *nspace) { + NameSpaceList *scan; + NameSpaceList *newlist; + ClassList *clslist; + + for (scan = list; scan; scan = scan->next) { + if (scan->nspace == nspace) + return list; + } + + newlist = lalloc(sizeof(NameSpaceList)); + newlist->next = list; + newlist->nspace = nspace; + list = newlist; + + if (nspace->theclass) { + list = CScope_AddNameSpaceToList(list, nspace->parent); + for (clslist = nspace->theclass->bases; clslist; clslist = clslist->next) + list = CScope_AddNameSpaceToList(list, clslist->base->nspace); + } + + return list; +} + +static NameSpaceList *CScope_BuildTypeAssociatedNameSpaceList(NameSpaceList *list, Type *type) { + FuncArg *arg; + +restart: + switch (type->type) { + case TYPEVOID: + case TYPEINT: + case TYPEFLOAT: + case TYPESTRUCT: + case TYPEBITFIELD: + case TYPETEMPLATE: + case TYPETEMPLDEPEXPR: + break; + case TYPEPOINTER: + case TYPEARRAY: + type = TYPE_POINTER(type)->target; + goto restart; + case TYPEENUM: + list = CScope_AddNameSpaceToList(list, TYPE_ENUM(type)->nspace); + break; + case TYPEFUNC: + for (arg = TYPE_FUNC(type)->args; arg; arg = arg->next) { + if (arg->type) + list = CScope_BuildTypeAssociatedNameSpaceList(list, arg->type); + } + type = TYPE_FUNC(type)->functype; + goto restart; + case TYPEMEMBERPOINTER: + list = CScope_BuildTypeAssociatedNameSpaceList(list, TYPE_MEMBER_POINTER(type)->ty1); + type = TYPE_MEMBER_POINTER(type)->ty2; + if (type->type != TYPECLASS) + break; + case TYPECLASS: + list = CScope_AddNameSpaceToList(list, TYPE_CLASS(type)->nspace); + break; + default: +#line 494 + CError_FATAL(); + } + + return list; +} + +static NameSpaceList *CScope_BuildAssociatedNameSpaceList(ENodeList *enodeList) { + // not 100% sure about the type for this but i think it's right?? + NameSpaceList *nslist = NULL; + while (enodeList) { + nslist = CScope_BuildTypeAssociatedNameSpaceList(nslist, enodeList->node->rtype); + enodeList = enodeList->next; + } + return nslist; +} + +static Boolean CScope_IsSameObject(Object *a, Object *b) { + if (a == b) + return 1; + return (a->nspace == b->nspace) && (a->name == b->name) && is_typesame(a->type, b->type); +} + +NameSpaceObjectList *CScope_ArgumentDependentNameLookup(NameSpaceObjectList *list, HashNameNode *name, ENodeList *argNodes, Boolean flag) { + NameSpaceList *scan; + NameSpaceObjectList *iscan; + NameSpaceObjectList *iiscan; + NameSpaceObjectList *newlist; + + for (scan = CScope_BuildAssociatedNameSpaceList(argNodes); scan; scan = scan->next) { + for (iscan = CScope_FindQualName(scan->nspace, name); iscan; iscan = iscan->next) { + if (iscan->object->otype != OT_OBJECT) + continue; + if (OBJECT(iscan->object)->type->type != TYPEFUNC) + continue; + if (flag && (TYPE_FUNC(OBJECT(iscan->object)->type)->flags & FUNC_FLAGS_METHOD)) + continue; + + for (iiscan = list; iiscan; iiscan = iiscan->next) { + if (iiscan->object->otype == OT_OBJECT && CScope_IsSameObject(OBJECT(iiscan->object), OBJECT(iscan->object))) + break; + } + + if (!iiscan) { + newlist = lalloc(sizeof(NameSpaceObjectList)); + newlist->object = iscan->object; + newlist->next = list; + list = newlist; + } + } + } + + return list; +} + +NameSpace *CScope_NewHashNameSpace(HashNameNode *name) { + NameSpace *nspace; + void *buffer; + + buffer = galloc(0x400 * sizeof(void *)); + memclrw(buffer, 0x400 * sizeof(void *)); + nspace = galloc(sizeof(NameSpace)); + memclrw(nspace, sizeof(NameSpace)); + nspace->name = name; + nspace->data.hash = buffer; + nspace->is_hash = 1; + nspace->is_global = 1; + return nspace; +} + +NameSpace *CScope_NewListNameSpace(HashNameNode *name, Boolean is_global) { + NameSpace *nspace; + if (is_global) { + nspace = galloc(sizeof(NameSpace)); + memclrw(nspace, sizeof(NameSpace)); + } else { + nspace = lalloc(sizeof(NameSpace)); + memclrw(nspace, sizeof(NameSpace)); + } + nspace->name = name; + nspace->is_hash = 0; + nspace->is_global = is_global; + return nspace; +} + +NameSpace *CScope_FindNonClassNonFunctionNS(NameSpace *nspace) { + while (nspace) { + if (!nspace->theclass && !nspace->is_templ) + return nspace; + nspace = nspace->parent; + } + return cscope_root; +} + +NameSpace *CScope_FindGlobalNS(NameSpace *nspace) { + while (nspace) { + if (nspace->name && !nspace->theclass && nspace->is_global) + return nspace; + nspace = nspace->parent; + } + return cscope_root; +} + +Boolean CScope_IsStdNameSpace(NameSpace *nspace) { + return nspace && !nspace->theclass && (nspace->parent == cscope_root) && nspace->name && !strcmp(nspace->name->name, "std"); +} + +Boolean CScope_IsEmptyNameSpace(NameSpace *nspace) { +#line 664 + CError_ASSERT(!nspace->is_hash); + return !nspace->data.list; +} + +void CScope_MergeNameSpace(NameSpace *dst, NameSpace *src) { + NameSpaceName *nsname; + +#line 678 + CError_ASSERT(!dst->is_hash && !src->is_hash); + + if ((nsname = dst->data.list)) { + while (nsname->next) + nsname = nsname->next; + nsname->next = src->data.list; + } else { + dst->data.list = src->data.list; + } +} + +void CScope_AddObject(NameSpace *nspace, HashNameNode *name, ObjBase *obj) { + NameSpaceObjectList *objlist; + NameSpaceObjectList *newlist; + + objlist = CScope_FindQualName(nspace, name); + if (objlist) { + if (nspace->is_global) + newlist = galloc(sizeof(NameSpaceObjectList)); + else + newlist = lalloc(sizeof(NameSpaceObjectList)); + + if (obj->otype == OT_NAMESPACE || objlist->object->otype == OT_NAMESPACE) { + CError_Error(322/*, objlist->object*/); + return; + } + + if (obj->otype == OT_TYPETAG) { + do { + if (objlist->object->otype == OT_TYPETAG) { + CError_Error(322/*, objlist->object*/); + return; + } + + if (copts.cplusplus && objlist->object->otype == OT_TYPE && !is_typesame(OBJ_TYPE_TAG(obj)->type, OBJ_TYPE(objlist->object)->type)) { + CError_Error(332); + return; + } + + if (!objlist->next) { + objlist->next = newlist; + newlist->next = NULL; + newlist->object = obj; + return; + } + objlist = objlist->next; + } while (1); + } + + if (objlist->object->otype == OT_TYPETAG) { + if (copts.cplusplus && obj->otype == OT_TYPE && !is_typesame(OBJ_TYPE(obj)->type, OBJ_TYPE_TAG(objlist->object)->type)) { + CError_Error(332); + return; + } + +#line 739 + CError_ASSERT(!objlist->next); + + newlist->object = objlist->object; + newlist->next = NULL; + objlist->object = obj; + objlist->next = newlist; + return; + } + + if (!copts.cplusplus || !CScope_ObjectIsFunction(OBJECT(obj))) { + CError_Error(322); + return; + } + + do { + if (objlist->object->otype == OT_TYPETAG) { + objlist->next = galloc(sizeof(NameSpaceObjectList)); + objlist->next->next = NULL; + objlist->next->object = objlist->object; + objlist->object = obj; + return; + } + + if (!CScope_ObjectIsFunction(OBJECT(objlist->object))) { + CError_Error(322); + return; + } + + if (!objlist->next) { + objlist->next = galloc(sizeof(NameSpaceObjectList)); + objlist->next->next = NULL; + objlist->next->object = obj; + return; + } + + objlist = objlist->next; + } while (1); + } else if (nspace->theclass && TYPE_CLASS(nspace->theclass)->flags & CLASS_FLAGS_900) { + CScope_AppendName(nspace, name)->object = obj; + } else { + CScope_InsertName(nspace, name)->object = obj; + } +} + +void CScope_AddGlobalObject(Object *obj) { + obj->nspace = cscope_root; + CScope_AddObject(cscope_root, obj->name, OBJ_BASE(obj)); +} + +NameSpaceLookupList *CScope_BuildNameSpaceLookupList(NameSpace *nspace) { + NameSpaceLookupList *lookup; + NameSpaceList list; + NameSpaceList *current; + NameSpaceList *current2; + NameSpaceList *current3; + NameSpaceList *newlist; + NameSpaceLookupList *currentL; + NameSpace *currentNS; + + lookup = lalloc(sizeof(NameSpaceLookupList)); + memclrw(lookup, sizeof(NameSpaceLookupList)); + lookup->nspace = nspace; + + if (nspace->parent) + lookup->next = CScope_BuildNameSpaceLookupList(nspace->parent); + + if (nspace->usings) { + list.nspace = nspace; + list.next = NULL; + for (current2 = &list; current2; current2 = current2->next) { + for (current = current2->nspace->usings; current; current = current->next) { + for (current3 = &list; current3; current3 = current3->next) { + if (current3->nspace == current->nspace) + break; + } + if (!current3) { + newlist = lalloc(sizeof(NameSpaceList)); + newlist->nspace = current->nspace; + newlist->next = current2->next; + current2->next = newlist; + } + } + } + + for (current = list.next; current; current = current->next) { + for (currentL = lookup; currentL; currentL = currentL->next) { + for (currentNS = current->nspace; currentNS; currentNS = currentNS->parent) { + if (currentL->nspace == currentNS) + goto foundIt; + } + } +#line 853 + CError_FATAL(); + foundIt: + for (current2 = currentL->namespaces; current2; current2 = current2->next) { + if (current2->nspace == current->nspace) + break; + } + if (!current2) { + newlist = lalloc(sizeof(NameSpaceList)); + newlist->nspace = current->nspace; + newlist->next = currentL->namespaces; + currentL->namespaces = newlist; + } + } + } + + return lookup; +} + +static Boolean CScope_IsInLookup(NameSpaceLookupList *list, NameSpace *nspace) { + NameSpaceLookupList *scan; + NameSpaceList *iscan; + + for (scan = list; scan; scan = scan->next) { + if (scan->nspace == nspace) + return 1; + for (iscan = scan->namespaces; iscan; iscan = iscan->next) { + if (iscan->nspace == nspace) + return 1; + } + } + + return 0; +} + +static NameSpaceLookupList *CScope_BuildNameSpaceMemberLookupList(NameSpace *nspace) { + NameSpaceLookupList list; + NameSpaceLookupList *current; + NameSpaceList *scan; + NameSpaceList *oscan; + NameSpaceList *newlist; + + list.nspace = nspace; + list.namespaces = NULL; + list.next = NULL; + + for (current = &list; current; current = current->next) { + if (current->nspace) { + for (scan = current->nspace->usings; scan; scan = scan->next) { + if (!CScope_IsInLookup(&list, scan->nspace)) { + if (!current->next) { + current->next = lalloc(sizeof(NameSpaceLookupList)); + current->next->nspace = NULL; + current->next->namespaces = NULL; + current->next->next = NULL; + } + newlist = lalloc(sizeof(NameSpaceList)); + newlist->nspace = scan->nspace; + newlist->next = current->next->namespaces; + current->next->namespaces = newlist; + } + } + } + + for (oscan = current->namespaces; oscan; oscan = oscan->next) { + for (scan = oscan->nspace->usings; scan; scan = scan->next) { + if (!CScope_IsInLookup(&list, scan->nspace)) { + if (!current->next) { + current->next = lalloc(sizeof(NameSpaceLookupList)); + current->next->nspace = NULL; + current->next->namespaces = NULL; + current->next->next = NULL; + } + newlist = lalloc(sizeof(NameSpaceList)); + newlist->nspace = scan->nspace; + newlist->next = current->next->namespaces; + current->next->namespaces = newlist; + } + } + } + } + + return list.next; +} + +static NameSpaceObjectList *CScope_CopyNameSpaceObjectList(NameSpaceObjectList *list) { + NameSpaceObjectList *first, *current; + + first = current = lalloc(sizeof(NameSpaceObjectList)); + do { + current->object = list->object; + list = list->next; + if (!list) { + current->next = NULL; + break; + } else { + current->next = lalloc(sizeof(NameSpaceObjectList)); + current = current->next; + } + } while (1); + + return first; +} + +static NameSpace *CScope_ExtractNameSpace(NameSpaceObjectList *list, Boolean *fail) { + Type *type; + +restart: + if (!list) + return NULL; + + switch (list->object->otype) { + case OT_TYPE: + type = OBJ_TYPE(list->object)->type; + break; + case OT_TYPETAG: + type = OBJ_TYPE_TAG(list->object)->type; + break; + case OT_NAMESPACE: + return OBJ_NAMESPACE(list->object)->nspace; + default: +#line 1052 + CError_FATAL(); + break; + case OT_ENUMCONST: + case OT_MEMBERVAR: + case OT_OBJECT: + list = list->next; + goto restart; + } + + if (type->type != TYPECLASS) { + if (type->type == TYPETEMPLATE) + return NULL; + CError_Error(320); + if (fail) + *fail = 1; + return NULL; + } else { + return TYPE_CLASS(type)->nspace; + } +} + +static BClassList *CScope_RecFindClassMember(CScopeParseResult *result, TypeClass *tclass, SInt32 offset) { + // does not match, r24 and r23 are swapped at the end x.x + Boolean fail; + NameSpace *nspace; + NameSpaceObjectList *list; + ClassList *base; + TypeClass *bestClass; + BClassList *bestBase, *n; + BClassList *candidate; + SInt32 thisoffset; + BClassList *newlist; + + if ((list = CScope_FindName(tclass->nspace, cscope_name))) { + if (cscope_foundclass) { + if (CClass_ClassDominates(cscope_foundclass, tclass)) + return NULL; + if (CClass_ClassDominates(tclass, cscope_foundclass)) + cscope_foundclass = NULL; + } + + switch (cscope_lookuptype) { + case 2: + fail = 0; + if ((nspace = CScope_ExtractNameSpace(list, &fail))) { + if (cscope_foundclass) { + if (cscope_foundclass != tclass) { + CScope_AmbigNameError(cscope_foundclass->nspace, tclass->nspace, cscope_name); + return NULL; + } + if (cscope_foundclassoffset != offset) + cscope_isambig = 1; + return NULL; + } + + cscope_foundclass = tclass; + cscope_foundclassoffset = offset; + result->nspace_0 = nspace; + + newlist = lalloc(sizeof(BClassList)); + newlist->next = NULL; + newlist->type = (Type *) tclass; + return newlist; + } + + if (fail) + return NULL; + break; + case 0: + if (cscope_foundclass) { + if ( + list->object->otype == OT_TYPETAG + && result->nsol_14->object->otype == OT_TYPETAG + && OBJ_TYPE_TAG(list->object)->type->type == TYPECLASS + && OBJ_TYPE_TAG(result->nsol_14->object)->type->type == TYPECLASS + && (TYPE_CLASS(OBJ_TYPE_TAG(list->object)->type)->flags & CLASS_FLAGS_800) + && (TYPE_CLASS(OBJ_TYPE_TAG(result->nsol_14->object)->type)->flags & CLASS_FLAGS_800) + && TEMPL_CLASS_INST(OBJ_TYPE_TAG(list->object)->type)->templ == TEMPL_CLASS_INST(OBJ_TYPE_TAG(result->nsol_14->object)->type)->templ + ) { + cscope_foundtemplate = TEMPL_CLASS_INST(OBJ_TYPE_TAG(result->nsol_14->object)->type)->templ; + } else { + if (cscope_foundclass != tclass) { + CScope_AmbigNameError(cscope_foundclass->nspace, tclass->nspace, cscope_name); + return NULL; + } + if (cscope_foundclassoffset != offset) { + cscope_isambig = 1; + return NULL; + } + } + } + + cscope_foundclass = tclass; + cscope_foundclassoffset = offset; + result->nsol_14 = list; + newlist = lalloc(sizeof(BClassList)); + newlist->next = NULL; + newlist->type = (Type *) tclass; + return newlist; + case 1: + for (; list; list = list->next) { + if (list->object->otype == OT_TYPETAG) { + if (cscope_foundclass) { + if (cscope_foundclass != tclass) { + CScope_AmbigNameError(cscope_foundclass->nspace, tclass->nspace, cscope_name); + return NULL; + } + if (cscope_foundclassoffset != offset) + cscope_isambig = 1; + return NULL; + } + + cscope_foundclass = tclass; + cscope_foundclassoffset = offset; + result->x8 = OBJ_TYPE_TAG(list->object)->type; + newlist = lalloc(sizeof(BClassList)); + newlist->next = NULL; + newlist->type = (Type *) tclass; + return newlist; + } + } + break; + default: +#line 1202 + CError_FATAL(); + } + } + + for (base = tclass->bases, bestBase = NULL; base; base = base->next) { + thisoffset = base->is_virtual ? CClass_VirtualBaseOffset(cscope_mostderived, base->base) : offset + base->offset; + if ((candidate = CScope_RecFindClassMember(result, base->base, thisoffset))) { + n = lalloc(sizeof(BClassList)); + n->next = candidate; + n->type = (Type *) tclass; + if (bestBase && bestClass == cscope_foundclass) { + if (CClass_IsMoreAccessiblePath(n, bestBase)) + bestBase = n; + } else { + bestClass = cscope_foundclass; + bestBase = n; + } + } + } + + return bestBase; +} + +static Boolean CScope_FindClassMember(CScopeParseResult *result, NameSpace *nspace, HashNameNode *name, UInt8 lookupType) { + BClassList *bcl; + BClassList *scan; + + cscope_mostderived = nspace->theclass; + cscope_foundclass = NULL; + cscope_foundtemplate = NULL; + cscope_name = name; + cscope_lookuptype = lookupType; + cscope_isambig = 0; + + if ((bcl = CScope_RecFindClassMember(result, cscope_mostderived, 0))) { + if (cscope_foundtemplate) + return 1; + + if ((scan = result->bcl_18)) { + while (scan->next) + scan = scan->next; + if (TYPE_CLASS(scan->type) != cscope_mostderived) + scan->next = bcl; + else + scan->next = bcl->next; + } else { + result->bcl_18 = bcl; + } + + if (cscope_isambig) + result->isambig = 1; + return 1; + } else { + return 0; + } +} + +static BClassList *CScope_GetAccessPathRec(TypeClass *src, TypeClass *dest, SInt32 offset) { + BClassList *list; + BClassList *best; + ClassList *base; + + if (src == dest) { + if (cscope_foundclass && cscope_foundclassoffset != offset) + CError_Error(188); + + list = lalloc(sizeof(BClassList)); + list->next = NULL; + list->type = (Type *) src; + cscope_foundclass = src; + cscope_foundclassoffset = offset; + return list; + } + + for (base = src->bases, best = NULL; base; base = base->next) { + if ((list = CScope_GetAccessPathRec(base->base, dest, base->is_virtual ? CClass_VirtualBaseOffset(cscope_mostderived, base->base) : (offset + base->offset)))) + best = list; + } + + if (best) { + list = lalloc(sizeof(BClassList)); + list->next = best; + list->type = (Type *) src; + return list; + } + + return NULL; +} + +static BClassList *CScope_GetAccessPath(TypeClass *src, TypeClass *dest) { + cscope_mostderived = src; + cscope_foundclass = NULL; + return CScope_GetAccessPathRec(src, dest, 0); +} + +static NameSpace *CScope_FindLookupNameSpace(CScopeNSIterator *iterator, NameSpaceLookupList *lookup, HashNameNode *name) { + NameSpaceObjectList *list; + NameSpaceList *scan; + NameSpace *retnspace = NULL; + NameSpace *candidate; + Boolean fail = 0; + + if (lookup->nspace->theclass) { + if (CScope_FindClassMember(iterator->result, lookup->nspace, name, 2)) { + retnspace = iterator->result->nspace_0; + iterator->result->nspace_0 = NULL; + return retnspace; + } else { + return NULL; + } + } + + if ((list = CScope_FindName(lookup->nspace, name))) { + fail = 0; + retnspace = CScope_ExtractNameSpace(list, &fail); + if (fail) + return NULL; + } + + for (scan = lookup->namespaces; scan; scan = scan->next) { + fail = 0; + if ((list = CScope_FindName(scan->nspace, name)) && (candidate = CScope_ExtractNameSpace(list, &fail))) { + if (retnspace) { + if (retnspace != candidate) + CScope_AmbigNameError(retnspace, candidate, NULL); + } else { + retnspace = candidate; + } + } + if (fail) + return NULL; + } + + return retnspace; +} + +static NameSpaceObjectList *CScope_FindLookupName(NameSpaceLookupList *list, HashNameNode *name, NameSpace **foundnspace) { + NameSpaceName *scanname; + NameSpaceObjectList *tmpOL; + NameSpaceObjectList *r31; + NameSpaceObjectList *r30; + NameSpaceList *r29; + NameSpace *r28; + Boolean r27; + NameSpaceObjectList *r6; + NameSpaceObjectList *scanOL; + NameSpaceObjectList *newlist; + + if (list->nspace) { + for (scanname = list->nspace->tparams; scanname; scanname = scanname->next) { + if (scanname->name == name) + return &scanname->first; + } + + if ((tmpOL = CScope_FindName(list->nspace, name))) { + r31 = tmpOL; + r28 = list->nspace; + } else { + r31 = NULL; + r28 = NULL; + } + } else { + r31 = NULL; + r28 = NULL; + } + + r27 = 0; + for (r29 = list->namespaces; r29; r29 = r29->next) { + if ((tmpOL = CScope_FindName(r29->nspace, name))) { + if (r31) { + for (r30 = tmpOL; r30; r30 = r30->next) { + for (r6 = r31; r6; r6 = r6->next) { + if (r6->object == r30->object) + break; + if (r6->object->otype == r30->object->otype) { + switch (r6->object->otype) { + case OT_TYPE: + if ((OBJ_TYPE(r6->object)->type == OBJ_TYPE(r30->object)->type) && (OBJ_TYPE(r6->object)->unk6 == OBJ_TYPE(r30->object)->unk6)) + goto break1; + break; + case OT_TYPETAG: + if (OBJ_TYPE_TAG(r6->object)->type == OBJ_TYPE_TAG(r30->object)->type) + goto break1; + break; + case OT_ENUMCONST: + if (OBJ_ENUM_CONST(r6->object)->type == OBJ_ENUM_CONST(r30->object)->type) + goto break1; + break; + case OT_OBJECT: + if (OBJECT(r6->object)->datatype == DALIAS) { + if (OBJECT(r30->object)->datatype == DALIAS) { + if (OBJECT(r6->object)->u.alias.object == OBJECT(r30->object)->u.alias.object) + goto break1; + } else { + if (OBJECT(r6->object)->u.alias.object == OBJECT(r30->object)) + goto break1; + } + } else { + if ((OBJECT(r30->object)->datatype == DALIAS) && OBJECT(r6->object) == OBJECT(r30->object)->u.alias.object) + goto break1; + } + break; + } + } + } + break1: + if (!r6) { + if (!r27) { + r31 = CScope_CopyNameSpaceObjectList(r31); + r27 = 1; + } + if (CScope_ObjectIsFunction(OBJECT(r30->object))) { + for (scanOL = r31; scanOL; scanOL = scanOL->next) { + if (!CScope_ObjectIsFunction(OBJECT(scanOL->object))) { + if (scanOL->object->otype != OT_TYPETAG) { + CScope_AmbigNameError(r28, r29->nspace, name); + break; + } + } + } + } else if (r30->object->otype == OT_TYPETAG) { + for (scanOL = r31; scanOL; scanOL = scanOL->next) { + if (scanOL->object->otype == OT_TYPETAG) { + CScope_AmbigNameError(r28, r29->nspace, name); + break; + } + } + } else { + for (scanOL = r31; scanOL; scanOL = scanOL->next) { + if (scanOL->object->otype != OT_TYPETAG) { + CScope_AmbigNameError(r28, r29->nspace, name); + break; + } + } + } + + if (!scanOL) { + newlist = lalloc(sizeof(NameSpaceObjectList)); + newlist->object = r30->object; + newlist->next = r31; + r31 = newlist; + } + } + } + } else { + r31 = tmpOL; + r28 = r29->nspace; + } + } + } + + if (foundnspace) + *foundnspace = r28; + return r31; +} + +static NameSpaceObjectList *CScope_NSIteratorFind(CScopeNSIterator *iterator, HashNameNode *name) { + NameSpaceObjectList *list; + + if (iterator->lookup) { + if (iterator->lookup->namespaces) + return CScope_FindLookupName(iterator->lookup, name, NULL); + if (iterator->lookup->nspace->theclass) { + if (CScope_FindClassMember(iterator->result, iterator->lookup->nspace, name, 0)) { + list = iterator->result->nsol_14; + iterator->result->nsol_14 = NULL; + return list; + } else { + return NULL; + } + } + + if ((list = CScope_FindName(iterator->lookup->nspace, name))) + return list; + } else { + if (iterator->nspace->theclass) { + if (CScope_FindClassMember(iterator->result, iterator->nspace, name, 0)) { + list = iterator->result->nsol_14; + iterator->result->nsol_14 = NULL; + return list; + } else { + return NULL; + } + } + + if ((list = CScope_FindName(iterator->nspace, name))) + return list; + } + + return NULL; +} + +static NameSpaceObjectList *CScope_NSIteratorNonClassFind(CScopeNSIterator *iterator, HashNameNode *name) { + NameSpaceObjectList *list; + + if (iterator->lookup) { + if (iterator->lookup->namespaces) + return CScope_FindLookupName(iterator->lookup, name, NULL); + if (iterator->lookup->nspace->theclass) + return NULL; + if ((list = CScope_FindName(iterator->lookup->nspace, name))) + return list; + } else { + if (iterator->nspace->theclass) + return NULL; + if ((list = CScope_FindName(iterator->nspace, name))) + return list; + } + + return NULL; +} + +static NameSpace *CScope_NSIteratorFindNameSpace(CScopeNSIterator *iterator, HashNameNode *name) { + NameSpace *nspace; + NameSpaceObjectList *list; + + if (iterator->lookup) { + if (iterator->lookup->namespaces) + return CScope_FindLookupNameSpace(iterator, iterator->lookup, name); + if (iterator->lookup->nspace->theclass) { + if (CScope_FindClassMember(iterator->result, iterator->lookup->nspace, name, 2)) { + nspace = iterator->result->nspace_0; + iterator->result->nspace_0 = NULL; + return nspace; + } else { + return NULL; + } + } + + if ((list = CScope_FindName(iterator->lookup->nspace, name))) + return CScope_ExtractNameSpace(list, NULL); + } else { + if (iterator->nspace->theclass) { + if (CScope_FindClassMember(iterator->result, iterator->nspace, name, 2)) { + nspace = iterator->result->nspace_0; + iterator->result->nspace_0 = NULL; + return nspace; + } else { + return NULL; + } + } + + if ((list = CScope_FindName(iterator->nspace, name))) + return CScope_ExtractNameSpace(list, NULL); + } + + return NULL; +} + +static Boolean CScope_SetupParseNameResult(CScopeParseResult *result, NameSpaceObjectList *list, HashNameNode *name) { + if (!list->next || list->next->object->otype == OT_TYPETAG) { + switch (list->object->otype) { + case OT_NAMESPACE: + CError_Error(321); + return 0; + case OT_TYPE: + result->x8 = OBJ_TYPE(list->object)->type; + result->xC = OBJ_TYPE(list->object)->unk6; + result->obj_10 = list->object; + result->name_4 = name; + result->x20 = 1; + break; + case OT_TYPETAG: + result->x8 = OBJ_TYPE_TAG(list->object)->type; + result->xC = NULL; + result->obj_10 = list->object; + result->name_4 = name; + result->x20 = 1; + break; + default: + result->obj_10 = list->object; + } + } else { + result->nsol_14 = list; + } + + return 1; +} + +Boolean CScope_FindQualifiedClassMember(CScopeParseResult *result, TypeClass *tclass, HashNameNode *name) { + NameSpaceObjectList *list; + + memclrw(result, sizeof(CScopeParseResult)); + CDecl_CompleteType((Type *) tclass); + + if (CScope_FindClassMember(result, tclass->nspace, name, 0)) { + list = result->nsol_14; +#line 1780 + CError_ASSERT(list); + result->nsol_14 = NULL; + + if (CScope_SetupParseNameResult(result, list, name) && !result->x8) + return 1; + else + CError_Error(340, name->name); + } + + return 0; +} + +static NameSpace *CScope_FindQualifiedNameSpace(CScopeParseResult *result, NameSpace *nspace, HashNameNode *name) { + NameSpaceObjectList *list; + NameSpace *cand; + NameSpace *found; + NameSpaceList *scan; + NameSpaceLookupList *lookup; + Boolean fail = 0; + + if (nspace->theclass) { + if (CScope_FindClassMember(result, nspace, name, 2)) { + nspace = result->nspace_0; + result->nspace_0 = NULL; + return nspace; + } else { + return NULL; + } + } + + if ((list = CScope_FindQualName(nspace, name)) && CScope_ExtractNameSpace(list, &fail)) + return nspace; + + if (!fail && nspace->usings) { + found = NULL; + for (lookup = CScope_BuildNameSpaceMemberLookupList(nspace); lookup; lookup = lookup->next) { + for (scan = lookup->namespaces; scan; scan = scan->next) { + if ((list = CScope_FindQualName(scan->nspace, name)) && (cand = CScope_ExtractNameSpace(list, &fail))) { + if (found && cand != found) + CScope_AmbigNameError(found, cand, NULL); + found = cand; + } + + if (fail) + return NULL; + } + + if (found) + return found; + } + } + + return NULL; +} + +static NameSpaceObjectList *CScope_FindQualifiedName(CScopeParseResult *result, NameSpace *nspace, HashNameNode *name, NameSpace **foundnspace) { + NameSpaceObjectList *list; + NameSpaceLookupList *lookup; + + if (nspace->theclass) { + CDecl_CompleteType((Type *) nspace->theclass); + if (CScope_FindClassMember(result, nspace, name, 0)) { + list = result->nsol_14; + result->nsol_14 = NULL; + return list; + } else { + return NULL; + } + } + + if ((list = CScope_FindQualName(nspace, name))) { + *foundnspace = nspace; + return list; + } + + if (nspace->usings) { + for (lookup = CScope_BuildNameSpaceMemberLookupList(nspace); lookup; lookup = lookup->next) { + if ((list = CScope_FindLookupName(lookup, name, foundnspace))) + return list; + } + } + + return NULL; +} + +static Boolean CScope_FindQualifiedTag(CScopeParseResult *result, NameSpace *nspace, HashNameNode *name) { + NameSpaceObjectList *list; + NameSpaceLookupList *lookup; + Type *best; + NameSpace *bestnspace; + NameSpaceList *scan; + + if (nspace->theclass) { + CDecl_CompleteType((Type *) nspace->theclass); + return CScope_FindClassMember(result, nspace, name, 1) != 0; + } + + if ((list = CScope_FindQualName(nspace, name))) { + for (; list; list = list->next) { + if (list->object->otype == OT_TYPETAG) { + result->x8 = OBJ_TYPE_TAG(list->object)->type; + return 1; + } + } + } + + if (nspace->usings) { + best = NULL; + for (lookup = CScope_BuildNameSpaceMemberLookupList(nspace); lookup; lookup = lookup->next) { + for (scan = lookup->namespaces; scan; scan = scan->next) { + for (list = CScope_FindQualName(scan->nspace, name); list; list = list->next) { + if (list->object->otype == OT_TYPETAG) { + if (best && best != OBJ_TYPE_TAG(list->object)->type) + CScope_AmbigNameError(scan->nspace, bestnspace, name); + best = OBJ_TYPE_TAG(list->object)->type; + bestnspace = scan->nspace; + break; + } + } + } + + if (best) { + result->x8 = best; + return 1; + } + } + } + + return 0; +} + +inline void CScope_NSIteratorInit(CScopeNSIterator *iterator, NameSpace *nspace, CScopeParseResult *result) { + // assumed name + if (nspace->usings) { + iterator->nspace = NULL; + iterator->lookup = CScope_BuildNameSpaceLookupList(nspace); + } else { + iterator->nspace = nspace; + iterator->lookup = NULL; + } + iterator->result = result; +} + +inline Boolean CScope_NSIteratorNext(CScopeNSIterator *iterator) { + // assumed name + if (iterator->lookup) + return (iterator->lookup = iterator->lookup->next) != NULL; + if (iterator->result->x1D) + return 0; + + if ((iterator->nspace = iterator->nspace->parent)) { + if (iterator->nspace->usings && !iterator->result->x1D) { + iterator->lookup = CScope_BuildNameSpaceLookupList(iterator->nspace); + iterator->nspace = NULL; + } + return 1; + } else { + return 0; + } +} + +Type *CScope_GetType(NameSpace *nspace, HashNameNode *name, void **unk6) { + CScopeParseResult result; + CScopeNSIterator iterator; + NameSpaceObjectList *list; + Boolean ok; + + memclrw(&result, sizeof(result)); + CScope_NSIteratorInit(&iterator, nspace, &result); + + do { + for (list = CScope_NSIteratorFind(&iterator, name); list; list = list->next) { + if (list->object->otype == OT_TYPETAG) { + if (unk6) + *unk6 = NULL; + return OBJ_TYPE_TAG(list->object)->type; + } + if (list->object->otype == OT_TYPE) { + if (unk6) + *unk6 = OBJ_TYPE(list->object)->unk6; + return OBJ_TYPE(list->object)->type; + } + } + } while (CScope_NSIteratorNext(&iterator)); + + return NULL; +} + +Type *CScope_GetTagType(NameSpace *nspace, HashNameNode *name) { + CScopeParseResult result; + CScopeNSIterator iterator; + NameSpaceObjectList *list; + Boolean ok; + + memclrw(&result, sizeof(result)); + CScope_NSIteratorInit(&iterator, nspace, &result); + + do { + for (list = CScope_NSIteratorFind(&iterator, name); list; list = list->next) { + if (list->object->otype == OT_TYPETAG) + return OBJ_TYPE_TAG(list->object)->type; + } + } while (CScope_NSIteratorNext(&iterator)); + + return NULL; +} + +static Boolean CScope_DependentTemplateMember(CScopeParseResult *result, TypeTemplDep *ttempldep, Boolean flag1, Boolean flag2) { + // does not match, sign extension/caching mishap + SInt32 streamstate; + short token; + short token2; + TypeTemplDep *newtype; + TypeTemplDep *newtype2; + + CPrep_TokenStreamGetState(&streamstate); +#line 2026 + CError_ASSERT(lex() == TK_COLON_COLON); + + do { + token = lex(); + if (token == TK_OPERATOR && flag1) { + if (!CParser_ParseOperatorName(NULL, 1, 1)) + return 0; + newtype = CDecl_NewTemplDepType(TEMPLDEP_QUALNAME); + newtype->u.qual.type = ttempldep; + newtype->u.qual.name = tkidentifier; + CPrep_TokenStreamSetState(&streamstate); + lex(); + tk = lex(); + result->x8 = (Type *) newtype; + return 1; + } else if (token == TK_TEMPLATE) { + if (lex() != TK_IDENTIFIER) { + CError_Error(107); + return 0; + } + + CPrep_TokenStreamGetState(&streamstate); + newtype = CDecl_NewTemplDepType(TEMPLDEP_QUALNAME); + newtype->u.qual.type = ttempldep; + newtype->u.qual.name = tkidentifier; + if ((token2 = lex()) != '<') { + CError_Error(230); + return 0; + } + tk = token2; + newtype2 = CDecl_NewTemplDepType(TEMPLDEP_QUALTEMPL); + newtype2->u.qualtempl.type = newtype; + newtype2->u.qualtempl.args = CTempl_ParseUncheckTemplArgs(NULL, 1); + CPrep_TokenStreamGetState(&streamstate); + if (lex() == TK_COLON_COLON) { + ttempldep = newtype2; + continue; + } else { + CPrep_TokenStreamSetState(&streamstate); + result->x8 = (Type *) newtype2; + return 1; + } + } else if (token == TK_IDENTIFIER) { + newtype = CDecl_NewTemplDepType(TEMPLDEP_QUALNAME); + newtype->u.qual.type = ttempldep; + newtype->u.qual.name = tkidentifier; + tk = token; + + CPrep_TokenStreamGetState(&streamstate); + token2 = lex(); + tkidentifier = newtype->u.qual.name; + if (token2 == TK_COLON_COLON) { + ttempldep = newtype; + continue; + } + + if ((token2 == '<') && !flag2) { + tk = token2; + newtype2 = newtype; + newtype = CDecl_NewTemplDepType(TEMPLDEP_QUALTEMPL); + newtype->u.qualtempl.type = newtype2; + newtype->u.qualtempl.args = CTempl_ParseUncheckTemplArgs(NULL, 1); + + CPrep_TokenStreamGetState(&streamstate); + if (lex() == TK_COLON_COLON) { + ttempldep = newtype; + continue; + } + } + + CPrep_TokenStreamSetState(&streamstate); + result->x8 = (Type *) newtype; + return 1; + } else { + CPrep_TokenStreamSetState(&streamstate); + result->x8 = (Type *) ttempldep; + return 1; + } + } while (1); +} + +static Boolean CScope_CheckDtorName(TypeClass *tclass, Boolean *flag) { + if ((tk = lex()) != TK_IDENTIFIER) + CError_Error(107); + + if (tclass) { + *flag = 0; + if ((tclass->classname == tkidentifier) || (CScope_GetType(tclass->nspace, tkidentifier, NULL) == (Type *) tclass) || (CScope_GetType(cscope_current, tkidentifier, NULL) == (Type *) tclass)) { + if (!CClass_Destructor(tclass)) + *flag = 1; + if ((tclass->flags & CLASS_FLAGS_800) && (lookahead() == '<')) { + tk = lex(); + if (!CTemplTool_EqualArgs(TEMPL_CLASS_INST(tclass)->inst_args, CTempl_ParseUncheckTemplArgs(NULL, 0))) + CError_Error(374); + } + return 1; + } + } + + CError_Error(141); + return 0; +} + +static Boolean CScope_ParseQualifiedName(CScopeParseResult *result, NameSpace *nspace) { + NameSpaceObjectList *list; + HashNameNode *saveidentifier; + TypeClass *tclass; + Boolean flag = 0; + + do { + switch (tk) { + case TK_TEMPLATE: + if ((tk = lex()) != TK_IDENTIFIER) { + CError_Error(107); + return 0; + } + case TK_IDENTIFIER: + saveidentifier = tkidentifier; + if (lookahead() == TK_COLON_COLON) { + tk = lex(); + nspace = CScope_FindQualifiedNameSpace(result, nspace, saveidentifier); + if (!nspace) + return 0; + result->x1D = 1; + tk = lex(); + continue; + } + break; + case TK_OPERATOR: + if (!CParser_ParseOperatorName(NULL, 1, 1)) + return 0; + CPrep_UnLex(); + saveidentifier = tkidentifier; + break; + case '~': + if (!CScope_CheckDtorName(nspace->theclass, &flag)) + return 0; + saveidentifier = destructor_name_node; + flag = 1; + break; + default: + CError_Error(107); + return 0; + } + + if (!(list = CScope_FindQualifiedName(result, nspace, saveidentifier, &result->nspace_0)) || !CScope_SetupParseNameResult(result, list, saveidentifier)) { + if (flag) { + result->x1C = 1; + return 1; + } + if (nspace->theclass && !(nspace->theclass->flags & CLASS_FLAGS_2)) + CError_Error(136, nspace->theclass, 0); + else + CError_Error(140, saveidentifier->name); + return 0; + } + + if (result->x8 && (result->x8->type == TYPECLASS) && (lookahead() == '<')) { + tclass = TYPE_CLASS(result->x8); + if (tclass->flags & CLASS_FLAGS_800) + tclass = TYPE_CLASS(TEMPL_CLASS_INST(tclass)->templ); + else if (!(tclass->flags & CLASS_FLAGS_100)) + return 1; + + tk = lex(); + result->x8 = CTempl_ClassGetType(tclass); + if ((result->x8->type == TYPECLASS) && (lookahead() == TK_COLON_COLON)) { + lex(); + tk = lex(); + result->x1D = 1; + nspace = TYPE_CLASS(result->x8)->nspace; + result->x8 = NULL; + result->obj_10 = NULL; + continue; + } + } + + return 1; + } while (1); +} + +Boolean CScope_ParseExprName(CScopeParseResult *result) { + CScopeNSIterator iterator; + HashNameNode *name; + NameSpaceObjectList *list; + Boolean flag; + + if (!copts.cplusplus) { + memclrw(result, sizeof(CScopeParseResult)); + if (tk != TK_IDENTIFIER) { + CError_Error(107); + return 0; + } + + name = tkidentifier; + CScope_NSIteratorInit(&iterator, cscope_current, result); + do { + if ((list = CScope_NSIteratorFind(&iterator, name)) && (list->object->otype != OT_TYPETAG)) { + result->nspace_0 = iterator.lookup ? iterator.lookup->nspace : iterator.nspace; + return CScope_SetupParseNameResult(result, list, name); + } + } while (CScope_NSIteratorNext(&iterator)); + + result->nspace_0 = cscope_current; + result->name_4 = name; + return 1; + } else { + if ((tk == TK_COLON_COLON || tk == TK_IDENTIFIER) && CScope_ParseQualifiedNameSpace(result, 1, 1)) { + if (result->x8) + return 1; +#line 2313 + CError_ASSERT(result->nspace_0); + } else { + memclrw(result, sizeof(CScopeParseResult)); + result->nspace_0 = cscope_current; + } + + switch (tk) { + case TK_TEMPLATE: + if (!result->x1D) + CError_Error(373); + + if ((tk = lex()) != TK_IDENTIFIER) { + CError_Error(107); + return 0; + } + case TK_IDENTIFIER: + name = tkidentifier; + break; + case TK_OPERATOR: + if (!CParser_ParseOperatorName(NULL, 1, 1)) + return 0; + name = tkidentifier; + CPrep_UnLex(); + break; + case '~': + if (!CScope_CheckDtorName(result->nspace_0->theclass, &flag)) + return 0; + if (flag) { + result->x1C = 1; + return 1; + } + name = destructor_name_node; + break; + default: + CError_Error(107); + return 0; + } + + if (result->x1D) { + if (!(list = CScope_FindQualifiedName(result, result->nspace_0, name, &result->nspace_0))) { + CError_Error(140, CError_GetNameString(result->nspace_0, name)); + return 0; + } else { + return CScope_SetupParseNameResult(result, list, name); + } + } + + CScope_NSIteratorInit(&iterator, result->nspace_0, result); + do { + if ((list = CScope_NSIteratorFind(&iterator, name))) { + result->nspace_0 = iterator.lookup ? iterator.lookup->nspace : iterator.nspace; + return CScope_SetupParseNameResult(result, list, name); + } + } while (CScope_NSIteratorNext(&iterator)); + + if (result->x1D) { + CError_Error(140, name->name); + return 0; + } else { + result->nspace_0 = cscope_current; + result->name_4 = name; + return 1; + } + } +} + +Boolean CScope_ParseDeclName(CScopeParseResult *result) { + CScopeNSIterator iterator; + HashNameNode *name; + NameSpaceObjectList *list; + NameSpace *nspace; + Boolean flag; + CScopeSave save; + short op; + + if (!copts.cplusplus) { + non_cpp_mode: + if (tk != TK_IDENTIFIER) { + CError_Error(107); + return 0; + } + memclrw(result, sizeof(CScopeParseResult)); + + name = tkidentifier; + CScope_NSIteratorInit(&iterator, cscope_current, result); + do { + if ((list = CScope_NSIteratorFind(&iterator, name)) && (copts.cplusplus || (list->object->otype != OT_TYPETAG))) { + result->nspace_0 = iterator.lookup ? iterator.lookup->nspace : iterator.nspace; + return CScope_SetupParseNameResult(result, list, name); + } + } while (CScope_NSIteratorNext(&iterator)); + + result->nspace_0 = cscope_current; + result->name_4 = name; + return 0; + } else { + if ((tk != TK_COLON_COLON) && (tk != TK_IDENTIFIER)) { + CError_Error(107); + return 0; + } + + if (!CScope_ParseQualifiedNameSpace(result, 0, 0)) + goto non_cpp_mode; + + if (result->x8) + return 1; + + nspace = result->nspace_0; +#line 2435 + CError_ASSERT(nspace); + + switch (tk) { + case TK_OPERATOR: + CScope_SetNameSpaceScope(nspace, &save); + if (!CParser_ParseOperatorName(&op, 1, 1)) { + CScope_RestoreScope(&save); + return 0; + } + CScope_RestoreScope(&save); + if (op) + CError_Error(121); + result->x21 = 1; + return 1; + case TK_IDENTIFIER: + name = tkidentifier; + if (nspace->theclass && nspace->theclass->classname == tkidentifier) + name = constructor_name_node; + break; + case '~': + if (!nspace->theclass) { + CError_Error(121); + return 0; + } + tk = lex(); + if (tk != TK_IDENTIFIER) { + CError_Error(107); + return 0; + } + if (nspace->theclass->classname != tkidentifier) + CError_Error(121); + name = destructor_name_node; + break; + default: + CError_Error(107); + return 0; + } + + if (result->x1D) { + if (!(list = CScope_FindQualifiedName(result, result->nspace_0, name, &result->nspace_0))) { + CError_Error(140, name->name); + return 0; + } else { + return CScope_SetupParseNameResult(result, list, name); + } + } + + CScope_NSIteratorInit(&iterator, nspace, result); + do { + if ((list = CScope_NSIteratorFind(&iterator, name))) { + result->nspace_0 = iterator.lookup ? iterator.lookup->nspace : iterator.nspace; + return CScope_SetupParseNameResult(result, list, name); + } + } while (CScope_NSIteratorNext(&iterator)); + + CError_Error(140, name->name); + return 0; + } +} + +Boolean CScope_ParseQualifiedNameSpace(CScopeParseResult *result, Boolean flag1, Boolean flag2) { + // mostly matches, some registers are awkwardly swapped + HashNameNode *name; // r25 + NameSpace *nspace; // r24 + short t; // r23 + Type *type; // r28? + Type *type2; // r21? + NameSpaceObjectList *list; // r21 + CScopeNSIterator iterator; + + memclrw(result, sizeof(CScopeParseResult)); + nspace = NULL; + if (tk == TK_COLON_COLON) { + result->nspace_0 = nspace = cscope_root; + result->x1D = 1; + tk = lex(); + } + + restart: + if (tk != TK_IDENTIFIER) { + if (tk != TK_TEMPLATE) + return nspace != NULL; + if (!result->x1D) + CError_Error(373); + if ((tk = lex()) != TK_IDENTIFIER) { + CError_Error(107); + return 0; + } + } + + name = tkidentifier; + t = lookahead(); + tkidentifier = name; + + if (t != TK_COLON_COLON && t != '<') + return nspace != NULL; + + CScope_NSIteratorInit(&iterator, nspace ? nspace : cscope_current, result); + // r28 = r23 ??? + do { + // list = r21 + for (list = CScope_NSIteratorFind(&iterator, name); list; list = list->next) { + if (list->object->otype == OT_NAMESPACE) { +#line 2565 + CError_ASSERT(!nspace || !nspace->theclass); + + result->nspace_0 = nspace = OBJ_NAMESPACE(list->object)->nspace; + if ((tk = lex()) != TK_COLON_COLON) { + CError_Error(321); + return 0; + } + + result->x1D = 1; + tk = lex(); + goto restart; + } + if (list->object->otype == OT_TYPETAG) { + type = OBJ_TYPE_TAG(list->object)->type; + if (type->type != TYPECLASS) { + if (t == '<') { + result->x8 = type; + return 1; + } else { + CError_Error(121); + return 0; + } + } + parse_thing: + if (t == '<') { + if (TYPE_CLASS(type)->flags & CLASS_FLAGS_800) { + type = (Type *) TEMPL_CLASS_INST(type)->templ; + } else if (!(TYPE_CLASS(type)->flags & CLASS_FLAGS_100)) { + result->x8 = type; + return 1; + } + } + if ((tk = lex()) == '<') { +#line 2609 + CError_ASSERT(TYPE_CLASS(type)->flags & CLASS_FLAGS_100); + type2 = CTempl_ClassGetType(TYPE_CLASS(type)); + if (type2->type == TYPETEMPLATE) { + if (lookahead() != TK_COLON_COLON) { + result->x8 = type2; + return 1; + } + return CScope_DependentTemplateMember(result, TYPE_TEMPLATE(type2), flag1, flag2); + } else if (type2->type != TYPECLASS) { + return 0; + } + + result->nspace_0 = nspace = TYPE_CLASS(type2)->nspace; + if (lookahead() != TK_COLON_COLON) { + result->x8 = type2; + return 1; + } + tk = lex(); + CDecl_CompleteType(type2); + } else { +#line 2632 + CError_ASSERT(tk == TK_COLON_COLON); + if (!(TYPE_CLASS(type)->flags & CLASS_FLAGS_100) || CParser_CheckTemplateClassUsage(TEMPL_CLASS(type), 1)) + result->nspace_0 = nspace = TYPE_CLASS(type)->nspace; + CDecl_CompleteType(type); + } + + result->x1D = 1; + tk = lex(); + goto restart; + } + if (list->object->otype == OT_TYPE) { + type2 = OBJ_TYPE(list->object)->type; + if (type2->type != TYPECLASS) { + if (type2->type == TYPETEMPLATE) { + if (TYPE_TEMPLATE(type2)->dtype == TEMPLDEP_ARGUMENT && TYPE_TEMPLATE(type2)->u.pid.type == TPT_TEMPLATE) { + type2 = CTempl_ParseTemplTemplParam(type2); + if ((type2->type != TYPETEMPLATE) || ((t = lookahead()) != TK_COLON_COLON)) { + result->x8 = type2; + return 1; + } + } + if (t == TK_COLON_COLON) + return CScope_DependentTemplateMember(result, TYPE_TEMPLATE(type2), flag1, flag2); + } + if (t == '<') { + result->x8 = type2; + return 1; + } else { + CError_Error(121); + return 0; + } + } else { + if ((t == '<') && (TYPE_CLASS(type2)->flags & CLASS_FLAGS_100)) { + type = type2; + goto parse_thing; + } + if ((tk = lex()) == '<') { + result->x8 = type2; + return 1; + } +#line 2686 + CError_ASSERT(tk == TK_COLON_COLON); + if (!type2->size) + CDecl_CompleteType(type2); + result->nspace_0 = nspace = TYPE_CLASS(type2)->nspace; + result->x1D = 1; + tk = lex(); + goto restart; + } + } + if (t == '<') + return nspace != NULL; + } + } while (CScope_NSIteratorNext(&iterator)); + + CError_Error(140, name->name); + return 0; +} + +Boolean CScope_ParseElaborateName(CScopeParseResult *result) { + CScopeNSIterator iterator; + HashNameNode *name; + NameSpaceObjectList *list; + Boolean flag; + + if (!copts.cplusplus) { + memclrw(result, sizeof(CScopeParseResult)); + if (tk != TK_IDENTIFIER) { + CError_Error(107); + return 0; + } + + name = tkidentifier; + CScope_NSIteratorInit(&iterator, cscope_current, result); + do { + for (list = CScope_NSIteratorFind(&iterator, name); list; list = list->next) { + if (list->object->otype == OT_TYPETAG) { + result->nspace_0 = iterator.lookup ? iterator.lookup->nspace : iterator.nspace; + return CScope_SetupParseNameResult(result, list, name); + } + } + } while (CScope_NSIteratorNext(&iterator)); + + result->name_4 = name; + return 1; + } else { + if ((tk != TK_COLON_COLON) && (tk != TK_IDENTIFIER)) { + CError_Error(107); + return 0; + } + + if (!CScope_ParseQualifiedNameSpace(result, 0, 0)) { + result->nspace_0 = cscope_current; + if (tk != TK_IDENTIFIER) { + CError_Error(107); + return 0; + } + name = tkidentifier; + } else { + if (result->x8) + return 1; +#line 2760 + CError_ASSERT(result->nspace_0); + + if (tk != TK_IDENTIFIER) { + CError_Error(107); + return 0; + } + name = tkidentifier; + + if (result->x1D) { + if (result->nspace_0->theclass) + return CScope_FindClassMember(result, result->nspace_0, name, 1) != 0; + else + return CScope_FindQualifiedTag(result, result->nspace_0, name); + } + } + + CScope_NSIteratorInit(&iterator, result->nspace_0, result); + do { + for (list = CScope_NSIteratorFind(&iterator, name); list; list = list->next) { + if (list->object->otype == OT_TYPETAG || list->object->otype == OT_TYPE) { + result->nspace_0 = iterator.lookup ? iterator.lookup->nspace : iterator.nspace; + return CScope_SetupParseNameResult(result, list, name); + } + } + } while (CScope_NSIteratorNext(&iterator)); + + result->name_4 = name; + return 1; + } +} + +Boolean CScope_FindObject(NameSpace *nspace, CScopeParseResult *result, HashNameNode *name) { + CScopeNSIterator iterator; + NameSpaceObjectList *list; + + memclrw(result, sizeof(CScopeParseResult)); + CScope_NSIteratorInit(&iterator, nspace, result); + do { + for (list = CScope_NSIteratorFind(&iterator, name); list; list = list->next) { + if (copts.cplusplus || list->object->otype != OT_TYPETAG) { + result->nspace_0 = iterator.lookup ? iterator.lookup->nspace : iterator.nspace; + return CScope_SetupParseNameResult(result, list, name); + } + } + } while (CScope_NSIteratorNext(&iterator)); + + return 0; +} + +Boolean CScope_FindNonClassObject(NameSpace *nspace, CScopeParseResult *result, HashNameNode *name) { + CScopeNSIterator iterator; + NameSpaceObjectList *list; + + memclrw(result, sizeof(CScopeParseResult)); + CScope_NSIteratorInit(&iterator, nspace, result); + do { + for (list = CScope_NSIteratorNonClassFind(&iterator, name); list; list = list->next) { + if (copts.cplusplus || list->object->otype != OT_TYPETAG) { + result->nspace_0 = iterator.lookup ? iterator.lookup->nspace : iterator.nspace; + return CScope_SetupParseNameResult(result, list, name); + } + } + } while (CScope_NSIteratorNext(&iterator)); + + return 0; +} + +NameSpaceObjectList *CScope_FindObjectList(CScopeParseResult *result, HashNameNode *name) { + CScopeNSIterator iterator; + NameSpaceObjectList *list; + + memclrw(result, sizeof(CScopeParseResult)); + CScope_NSIteratorInit(&iterator, cscope_current, result); + do { + for (list = CScope_NSIteratorFind(&iterator, name); list; list = list->next) { + if (copts.cplusplus || list->object->otype != OT_TYPETAG) { + result->nspace_0 = iterator.lookup ? iterator.lookup->nspace : iterator.nspace; + return list; + } + } + } while (CScope_NSIteratorNext(&iterator)); + + return 0; +} + +Boolean CScope_PossibleTypeName(HashNameNode *name) { + CScopeParseResult result; + CScopeNSIterator iterator; + NameSpaceObjectList *list; + + memclrw(&result, sizeof(CScopeParseResult)); + CScope_NSIteratorInit(&iterator, cscope_current, &result); + do { + if ((list = CScope_NSIteratorFind(&iterator, name))) { + switch (list->object->otype) { + case OT_TYPE: + case OT_NAMESPACE: + return 1; + case OT_TYPETAG: + if (copts.cplusplus) + return 1; + break; + default: + return 0; + } + } + } while (CScope_NSIteratorNext(&iterator)); + + return 0; +} + +Boolean CScope_FindClassMemberObject(TypeClass *tclass, CScopeParseResult *result, HashNameNode *name) { + NameSpaceObjectList *list; + + memclrw(result, sizeof(CScopeParseResult)); + + if (CScope_FindClassMember(result, tclass->nspace, name, 0)) { + list = result->nsol_14; + result->nsol_14 = NULL; + if (list && list->object->otype == OT_OBJECT) + return CScope_SetupParseNameResult(result, list, name); + } + + return 0; +} + +void CScope_InitObjectIterator(CScopeObjectIterator *iterator, NameSpace *nspace) { + memclrw(iterator, sizeof(CScopeObjectIterator)); + iterator->nspace = nspace; + if (!iterator->nspace->is_hash) + iterator->nextname = nspace->data.list; + else + iterator->nextname = nspace->data.hash[0]; +} + +ObjBase *CScope_NextObjectIteratorObject(CScopeObjectIterator *iterator) { + ObjBase *obj; + + do { + if (iterator->currlist) { + do { + obj = iterator->currlist->object; + if (obj->otype == OT_OBJECT) { + iterator->currlist = iterator->currlist->next; + return obj; + } + } while ((iterator->currlist = iterator->currlist->next)); + } + + if (iterator->nextname) { + iterator->currlist = &iterator->nextname->first; + iterator->nextname = iterator->nextname->next; + } else { + if (!iterator->nspace->is_hash || ++iterator->hashindex >= 1024) + return NULL; + iterator->nextname = iterator->nspace->data.hash[iterator->hashindex]; + } + } while (1); +} + +NameSpaceObjectList *CScope_NextObjectIteratorObjectList(CScopeObjectIterator *iterator) { + NameSpaceName *nsname; + + do { + if ((nsname = iterator->nextname)) { + iterator->nextname = nsname->next; + return &nsname->first; + } else { + if (!iterator->nspace->is_hash || ++iterator->hashindex >= 1024) + return NULL; + iterator->nextname = iterator->nspace->data.hash[iterator->hashindex]; + } + } while (1); +} + +void CScope_DefineTypeTag(NameSpace *nspace, HashNameNode *name, Type *type) { + ObjTypeTag *ott; + + ott = galloc(sizeof(ObjTypeTag)); + memclrw(ott, sizeof(ObjTypeTag)); + ott->otype = OT_TYPETAG; + ott->access = nspace->theclass ? global_access : ACCESSPUBLIC; + ott->type = type; + CScope_AddObject(nspace, name, OBJ_BASE(ott)); +} + +Type *CScope_GetLocalTagType(NameSpace *nspace, HashNameNode *name) { + NameSpaceObjectList *list; + + for (list = CScope_FindQualName(nspace, name); list; list = list->next) { + if (list->object->otype == OT_TYPETAG) + return OBJ_TYPE_TAG(list->object)->type; + } + + return NULL; +} + +Boolean CScope_FindTypeName(NameSpace *nspace, HashNameNode *name, CScopeParseResult *result) { + CScopeNSIterator iterator; + NameSpaceObjectList *list; + NameSpaceObjectList *scan; + + memclrw(result, sizeof(CScopeParseResult)); + CScope_NSIteratorInit(&iterator, nspace, result); + + do { + list = CScope_NSIteratorFind(&iterator, name); + for (scan = list; scan; scan = scan->next) { + switch (scan->object->otype) { + case OT_NAMESPACE: + result->nspace_0 = OBJ_NAMESPACE(scan->object)->nspace; + return 1; + case OT_TYPE: + case OT_TYPETAG: + return CScope_SetupParseNameResult(result, scan, name); + default: + return 0; + } + } + } while (CScope_NSIteratorNext(&iterator)); + + return 0; +} + +static NameSpaceObjectList *CScope_GetLocalObjects(NameSpaceObjectList *objs) { + NameSpaceObjectList *list; + NameSpaceObjectList **ptr; + + list = objs; + while (list) { + if (list->object->otype == OT_OBJECT && OBJECT(list->object)->datatype == DALIAS) { + list = CScope_CopyNameSpaceObjectList(objs); + ptr = &list; + while (*ptr) { + if ((*ptr)->object->otype == OT_OBJECT && OBJECT((*ptr)->object)->datatype == DALIAS) + *ptr = (*ptr)->next; + else + ptr = &(*ptr)->next; + } + return list; + } else { + list = list->next; + } + } + + return objs; +} + +NameSpaceObjectList *CScope_GetLocalObject(NameSpace *nspace, HashNameNode *name) { + NameSpaceObjectList *list; + + if ((list = CScope_FindQualName(nspace, name))) { + switch (list->object->otype) { + case OT_OBJECT: + return CScope_GetLocalObjects(list); + default: + CError_Error(122, name->name); + return NULL; + case OT_TYPETAG: + break; + } + } + + return NULL; +} + +static BClassList *CScope_GetBaseAccessPathEnd(BClassList *list) { + BClassList *best = list; + ClassList *scan; + + do { + if (!list->next) + return best; + + for (scan = TYPE_CLASS(list->type)->bases; scan; scan = scan->next) { + if (TYPE_CLASS(list->next->type) == scan->base) + break; + } + + if (!scan) + best = list->next; + list = list->next; + } while (1); +} + +BClassList *CScope_GetClassAccessPath(BClassList *list, TypeClass *tclass) { + BClassList *scan; + BClassList *list2; + + if (!list) + return NULL; + + list = CScope_GetBaseAccessPathEnd(list); + for (scan = list; scan; scan = scan->next) { + if (scan->type == (Type *) tclass) + return scan; + } + + if ((list2 = CScope_GetAccessPath(tclass, TYPE_CLASS(list->type)))) { + for (scan = list2; scan; scan = scan->next) { + if (scan->type == list->type) { + scan->next = list->next; + return list2; + } + } +#line 3217 + CError_FATAL(); + } + + return NULL; +} + +static Boolean CScope_FixMemberResult(TypeClass *tclass, CScopeParseResult *result) { + if (!(result->bcl_18 = CScope_GetClassAccessPath(result->bcl_18, tclass))) { + if (result->name_4) + CError_Error(150, result->name_4->name); + else + CError_Error(328); + return 0; + } else { + return 1; + } +} + +Boolean CScope_ParseMemberName(TypeClass *tclass, CScopeParseResult *result, Boolean flag) { + HashNameNode *name; + NameSpaceObjectList *list; + short t; + Boolean dtorflag; + + if (tk == TK_COLON_COLON) { + restart: + if (!CScope_ParseExprName(result)) + return 0; + + if (result->x8 && result->x8->type == TYPETEMPLATE && TYPE_TEMPLATE(result->x8)->dtype == TEMPLDEP_QUALNAME) { + if (flag) + return 1; + CError_Error(340, TYPE_TEMPLATE(result->x8)->u.qual.name->name); + result->x8 = NULL; + return 0; + } + + if (result->x1C) + return 1; + else + return CScope_FixMemberResult(tclass, result); + } + + if (tk == TK_IDENTIFIER) { + name = tkidentifier; + t = lookahead(); + tkidentifier = name; + switch (t) { + case TK_COLON_COLON: + memclrw(result, sizeof(CScopeParseResult)); + if (!CScope_FindClassMember(result, tclass->nspace, name, 2)) + goto restart; + break; + case '<': + if (flag) + goto restart; + break; + } + } else if (tk == '~') { + memclrw(result, sizeof(CScopeParseResult)); + if (CScope_CheckDtorName(tclass, &dtorflag)) { + if (dtorflag) { + result->x1C = 1; + return 1; + } + + if (!(list = CScope_FindQualifiedName(result, tclass->nspace, destructor_name_node, &result->nspace_0))) { + CError_Error(140, CError_GetNameString(result->nspace_0, destructor_name_node)); + return 0; + } else { + return CScope_SetupParseNameResult(result, list, destructor_name_node); + } + } + return 0; + } + + memclrw(result, sizeof(CScopeParseResult)); + return CScope_ParseQualifiedName(result, tclass->nspace); +} + +static void CScope_AddUsingObject(BClassList *bcl, NameSpace *nspace, ObjBase *obj, HashNameNode *name, AccessType access) { + NameSpaceObjectList *list; + BClassList *pathcopy; + TypeClass *tclass; + ObjBase *copy; + Object *objscan; + + if (bcl) { + if (!nspace->theclass) + CError_Error(200); + else + CClass_CheckPathAccess(bcl, NULL, obj->access); + } + + if (obj->otype == OT_TYPE) { + if (!nspace->theclass) { + if ((list = CScope_FindQualName(nspace, name)) && (list->object->otype == OT_TYPE) && + (OBJ_TYPE(obj)->type == OBJ_TYPE(list->object)->type) && + (OBJ_TYPE(obj)->unk6 == OBJ_TYPE(list->object)->unk6)) + return; + } + copy = galloc(sizeof(ObjType)); + *OBJ_TYPE(copy) = *OBJ_TYPE(obj); + copy->access = access; + CScope_AddObject(nspace, name, copy); + } else if (obj->otype == OT_TYPETAG) { + if (!nspace->theclass) { + if ((list = CScope_FindQualName(nspace, name)) && (list->object->otype == OT_TYPETAG) && + (OBJ_TYPE_TAG(obj)->type == OBJ_TYPE_TAG(list->object)->type)) + return; + } + copy = galloc(sizeof(ObjTypeTag)); + *OBJ_TYPE_TAG(copy) = *OBJ_TYPE_TAG(obj); + copy->access = access; + CScope_AddObject(nspace, name, copy); + } else if (obj->otype == OT_ENUMCONST) { + copy = galloc(sizeof(ObjEnumConst)); + *OBJ_ENUM_CONST(copy) = *OBJ_ENUM_CONST(obj); + copy->access = access; + CScope_AddObject(nspace, OBJ_ENUM_CONST(copy)->name, copy); + } else if (obj->otype == OT_MEMBERVAR) { + if (nspace->theclass) { + copy = galloc(sizeof(ObjMemberVarPath)); + *OBJ_MEMBER_VAR(copy) = *OBJ_MEMBER_VAR(obj); + copy->access = access; + pathcopy = CScope_GetClassAccessPath(CClass_GetPathCopy(bcl, 1), nspace->theclass); + if (pathcopy && pathcopy->type == (Type *) nspace->theclass) { + OBJ_MEMBER_VAR_PATH(copy)->has_path = 1; + OBJ_MEMBER_VAR_PATH(copy)->path = pathcopy; + } else { + CError_Error(221); + } + CScope_AddObject(nspace, OBJ_MEMBER_VAR(copy)->name, copy); + } else { + CError_Error(221); + } + } else if (obj->otype == OT_OBJECT) { + if (!nspace->theclass) { + for (list = CScope_FindQualName(nspace, OBJECT(obj)->name); list; list = list->next) { + if (list->object->otype == OT_OBJECT) { + objscan = OBJECT(list->object); + while (objscan->datatype == DALIAS) + objscan = objscan->u.alias.object; + if (OBJECT(obj) == objscan) + return; + } + } + } + + copy = galloc(sizeof(Object)); + *OBJECT(copy) = *OBJECT(obj); + copy->access = access; + OBJECT(copy)->datatype = DALIAS; + OBJECT(copy)->u.alias.object = OBJECT(obj); + OBJECT(copy)->u.alias.member = NULL; + OBJECT(copy)->u.alias.offset = 0; + + if (OBJECT(copy)->type->type == TYPEFUNC && (TYPE_FUNC(OBJECT(copy)->type)->flags & FUNC_FLAGS_METHOD) && !TYPE_METHOD(OBJECT(copy)->type)->x26) { + if (!(tclass = nspace->theclass) || !(OBJECT(copy)->u.alias.member = CScope_GetClassAccessPath( + CClass_GetPathCopy(bcl, 1), tclass)) || (OBJECT(copy)->u.alias.member->type != (Type *) nspace->theclass)) { + CError_Error(221); + OBJECT(copy)->u.alias.member = NULL; + } + } + + CScope_AddObject(nspace, OBJECT(copy)->name, copy); + } else { + CError_Error(200); + } +} + +void CScope_AddClassUsingDeclaration(TypeClass *tclass, TypeClass *tclass2, HashNameNode *name, AccessType access) { + CScopeParseResult result; + NameSpaceObjectList *scan; + + memclrw(&result, sizeof(CScopeParseResult)); + if (!CScope_FindClassMember(&result, tclass2->nspace, name, 0) || !CScope_FixMemberResult(tclass, &result)) { + CError_Error(340, name->name); + return; + } + + if (result.nsol_14) { + for (scan = result.nsol_14; scan; scan = scan->next) { + switch (scan->object->otype) { + case OT_ENUMCONST: + case OT_MEMBERVAR: + case OT_OBJECT: + CScope_AddUsingObject(result.bcl_18, tclass->nspace, scan->object, result.name_4, access); + break; + } + } + } else { + if (result.obj_10) + CScope_AddUsingObject(result.bcl_18, tclass->nspace, result.obj_10, result.name_4, access); + else + CError_Error(340, name->name); + } +} + +void CScope_ParseUsingDeclaration(NameSpace *nspace, AccessType access) { + // almost matches, slight bit of register weirdness + CScopeParseResult result; + + if (nspace->theclass) { + Boolean flag_r27 = (TYPE_CLASS(nspace->theclass)->flags & CLASS_FLAGS_100) ? 1 : 0; + Boolean flag_r26 = 0; + if (tk == TK_TYPENAME) { + if (!flag_r27) + CError_Error(200); + flag_r26 = 1; + tk = lex(); + } + + if (!CScope_ParseMemberName(nspace->theclass, &result, flag_r27)) { + CError_Error(200); + return; + } + + if (result.x8 && result.x8->type == TYPETEMPLATE && TYPE_TEMPLATE(result.x8)->dtype == TEMPLDEP_QUALNAME) { +#line 3578 + CError_ASSERT(flag_r27); + + if (flag_r26) { + ObjType *objtype = galloc(sizeof(ObjType)); + memclrw(objtype, sizeof(ObjType)); + objtype->otype = OT_TYPE; + objtype->access = access; + objtype->type = result.x8; + CScope_AddObject(nspace, TYPE_TEMPLATE(result.x8)->u.qual.name, OBJ_BASE(objtype)); + } else { + CTemplClass_RegisterUsingDecl(TEMPL_CLASS(nspace->theclass), result.x8, access); + } + + if ((tk = lex()) != ';') + CError_Error(123); + return; + } + + if (!result.x1D) { + CError_Error(200); + return; + } + } else { + NameSpace *savenspace = cscope_current; + cscope_current = nspace; + if (!CScope_ParseExprName(&result) || !result.x1D) { + cscope_current = savenspace; + CError_Error(200); + return; + } else { + cscope_current = savenspace; + } + } + + if (result.nsol_14) { + NameSpaceObjectList *scan; + for (scan = result.nsol_14; scan; scan = scan->next) { + if (scan->object->otype == OT_OBJECT) + CScope_AddUsingObject(result.bcl_18, nspace, scan->object, result.name_4, access); + } + } else { + if (result.obj_10) + CScope_AddUsingObject(result.bcl_18, nspace, result.obj_10, result.name_4, access); + else + CError_Error(200); + } + + if ((tk = lex()) != ';') + CError_Error(123); +} + +static NameSpace *CScope_ParseQualifiedNamespaceSpecifier(NameSpace *nspace) { + CScopeParseResult result; + CScopeNSIterator iterator; + NameSpaceObjectList *list; + + memclrw(&result, sizeof(CScopeParseResult)); + if (tk == TK_COLON_COLON) { + nspace = cscope_root; + result.x1D = 1; + tk = lex(); + } + + do { + if (tk != TK_IDENTIFIER) { + CError_Error(107); + break; + } + + CScope_NSIteratorInit(&iterator, nspace, &result); + do { + if ((list = CScope_NSIteratorFind(&iterator, tkidentifier)) && list->object->otype == OT_NAMESPACE) { + nspace = OBJ_NAMESPACE(list->object)->nspace; + goto some_goto; + } + } while (CScope_NSIteratorNext(&iterator)); + CError_Error(140, tkidentifier->name); + some_goto: + if ((tk = lex()) != TK_COLON_COLON) + break; + result.x1D = 1; + tk = lex(); + } while (1); + + return nspace; +} + +void CScope_ParseNameSpaceAlias(HashNameNode *name) { + NameSpaceObjectList *list; + ObjNameSpace *objns; + + list = CScope_FindQualName(cscope_current, name); + if (!list) { + tk = lex(); + objns = galloc(sizeof(ObjNameSpace)); + memclrw(objns, sizeof(ObjNameSpace)); + objns->otype = OT_NAMESPACE; + objns->access = ACCESSPUBLIC; + objns->nspace = CScope_ParseQualifiedNamespaceSpecifier(cscope_current); + CScope_AddObject(cscope_current, name, OBJ_BASE(objns)); + } else if (list->object->otype != OT_NAMESPACE) { + CError_Error(320); + tk = lex(); + CScope_ParseQualifiedNamespaceSpecifier(cscope_current); + } else { + tk = lex(); + if (CScope_ParseQualifiedNamespaceSpecifier(cscope_current) != OBJ_NAMESPACE(list->object)->nspace) + CError_Error(122, name->name); + } + + if (tk != ';') + CError_Error(123); +} + +void CScope_ParseUsingDirective(NameSpace *nspace) { + NameSpace *target; + NameSpaceList *list; + + target = CScope_ParseQualifiedNamespaceSpecifier(nspace); + if (target != nspace) { + for (list = nspace->usings; list; list = list->next) { + if (list->nspace == target) + break; + } + if (!list) { + list = galloc(sizeof(NameSpaceList)); + list->next = nspace->usings; + list->nspace = target; + nspace->usings = list; + } + } else { + CError_Error(321); + } + + if (tk != ';') + CError_Error(123); +} diff --git a/compiler_and_linker/FrontEnd/Common/CompilerTools.c b/compiler_and_linker/FrontEnd/Common/CompilerTools.c new file mode 100644 index 0000000..3eae51d --- /dev/null +++ b/compiler_and_linker/FrontEnd/Common/CompilerTools.c @@ -0,0 +1,1216 @@ +#include "compiler/CompilerTools.h" +#include "cos.h" + +extern Boolean systemHandles; + +UInt32 bit_masks[32] = { + 0, 1, 3, 7, + 0xF, 0x1F, 0x3F, 0x7F, + 0xFF, 0x1FF, 0x3FF, 0x7FF, + 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF, + 0xFFFF, 0x1FFFF, 0x3FFFF, 0x7FFFF, + 0xFFFFF, 0x1FFFFF, 0x3FFFFF, 0x7FFFFF, + 0xFFFFFF, 0x1FFFFFF, 0x3FFFFFF, 0x7FFFFFF, + 0xFFFFFFF, 0x1FFFFFFF, 0x3FFFFFFF, 0x7FFFFFFF +}; + +static short lheaplockcount; +static void (*heaperror)(); +static HeapMem bheap; +static HeapMem oheap; +static HeapMem aheap; +static HeapMem lheap; +static HeapMem gheap; +long hash_name_id; +HashNameNode **name_hash_nodes; +void (*GListErrorProc)(); + +void CompilerGetPString(short index, unsigned char *string) { + COS_GetPString(string, 10100, index); +} + +void CompilerGetCString(short index, char *string) { + COS_GetString(string, 10100, index); +} + +unsigned char *CTool_CtoPstr(char *cstr) { + char *cp = cstr; + int length = 0; + int i; + + while (*cp) { + ++length; + ++cp; + } + + for (i = length; i > 0; i--) { + cp[0] = cp[-1]; + --cp; + } + + cstr[0] = length; + return (unsigned char *) cstr; +} + +static void GListError() { + if (GListErrorProc) + GListErrorProc(); +} + +short InitGList(GList *gl, SInt32 size) { + if ((gl->data = COS_NewOSHandle(size)) == 0) + if ((gl->data = COS_NewHandle(size)) == 0) + return -1; + gl->size = 0; + gl->growsize = size >> 1; + gl->hndlsize = size; + return 0; +} + +void FreeGList(GList *gl) { + if (gl->data != 0) { + COS_FreeHandle(gl->data); + gl->data = 0; + } + gl->hndlsize = 0; + gl->size = 0; +} + +void LockGList(GList *gl) { + COS_LockHandleHi(gl->data); +} + +void UnlockGList(GList *gl) { + COS_UnlockHandle(gl->data); +} + +void ShrinkGList(GList *gl) { + COS_ResizeHandle(gl->data, gl->hndlsize = gl->size); +} + +void AppendGListData(GList *gl, const void *data, SInt32 size) { + if ((gl->size + size) > gl->hndlsize) { + if (!COS_ResizeHandle(gl->data, gl->hndlsize += size + gl->growsize)) + GListError(); + } + + memcpy(*gl->data + gl->size, data, size); + gl->size += size; +} + +void AppendGListNoData(GList *gl, SInt32 size) { + if ((gl->size + size) > gl->hndlsize) { + if (!COS_ResizeHandle(gl->data, gl->hndlsize += size + gl->growsize)) + GListError(); + } + + gl->size += size; +} + +void AppendGListByte(GList *gl, SInt8 thebyte) { + if ((gl->size + 1) > gl->hndlsize) { + if (!COS_ResizeHandle(gl->data, gl->hndlsize += 1 + gl->growsize)) + GListError(); + } + + (*gl->data)[gl->size++] = thebyte; +} + +void AppendGListWord(GList *gl, SInt16 theword) { + char *ptr; + + if ((gl->size + 2) > gl->hndlsize) { + if (!COS_ResizeHandle(gl->data, gl->hndlsize += 2 + gl->growsize)) + GListError(); + } + + ptr = *gl->data + gl->size; + gl->size += 2; + *(ptr++) = ((unsigned char *) &theword)[0]; + *(ptr++) = ((unsigned char *) &theword)[1]; +} + +void AppendGListTargetEndianWord(GList *gl, SInt16 theword) { + char *ptr; + + if ((gl->size + 2) > gl->hndlsize) { + if (!COS_ResizeHandle(gl->data, gl->hndlsize += 2 + gl->growsize)) + GListError(); + } + + ptr = *gl->data + gl->size; + gl->size += 2; + *(ptr++) = ((unsigned char *) &theword)[0]; + *(ptr++) = ((unsigned char *) &theword)[1]; +} + +void AppendGListLong(GList *gl, SInt32 theword) { + char *ptr; + + if ((gl->size + 4) > gl->hndlsize) { + if (!COS_ResizeHandle(gl->data, gl->hndlsize += 4 + gl->growsize)) + GListError(); + } + + ptr = *gl->data + gl->size; + gl->size += 4; + *(ptr++) = ((unsigned char *) &theword)[0]; + *(ptr++) = ((unsigned char *) &theword)[1]; + *(ptr++) = ((unsigned char *) &theword)[2]; + *(ptr++) = ((unsigned char *) &theword)[3]; +} + +void AppendGListTargetEndianLong(GList *gl, SInt32 theword) { + char *ptr; + + if ((gl->size + 4) > gl->hndlsize) { + if (!COS_ResizeHandle(gl->data, gl->hndlsize += 4 + gl->growsize)) + GListError(); + } + + ptr = *gl->data + gl->size; + gl->size += 4; + *(ptr++) = ((unsigned char *) &theword)[0]; + *(ptr++) = ((unsigned char *) &theword)[1]; + *(ptr++) = ((unsigned char *) &theword)[2]; + *(ptr++) = ((unsigned char *) &theword)[3]; +} + +void AppendGListID(GList *gl, const char *name) { + UInt32 n = strlen(name) + 1; + if ((gl->size + n) > gl->hndlsize) { + if (!COS_ResizeHandle(gl->data, gl->hndlsize += n + gl->growsize)) + GListError(); + } + + memcpy(*gl->data + gl->size, name, n); + gl->size += n; +} + +void AppendGListName(GList *gl, const char *name) { + UInt32 n = strlen(name); + if ((gl->size + n) > gl->hndlsize) { + if (!COS_ResizeHandle(gl->data, gl->hndlsize += n + gl->growsize)) + GListError(); + } + + memcpy(*gl->data + gl->size, name, n); + gl->size += n; +} + +void RemoveGListData(GList *gl, SInt32 size) { + gl->size -= size; + if (gl->hndlsize > (gl->size + gl->growsize * 2)) + COS_ResizeHandle(gl->data, gl->hndlsize = gl->size + gl->growsize); +} + +SInt16 GetGListByte(GList *gl) { + return (*gl->data)[gl->size++]; +} + +SInt16 GetGListWord(GList *gl) { + char *ptr; + union { unsigned char bytes[2]; short s; } data; + + // according to stabs, this one just uses a local short called 'n', not a union + ptr = *gl->data + gl->size; + gl->size += 2; + data.bytes[0] = ptr[0]; + data.bytes[1] = ptr[1]; + return data.s; +} + +SInt32 GetGListLong(GList *gl) { + char *ptr; + union { unsigned char bytes[4]; long l; } data; + + // according to stabs, this one just uses a local long called 'n', not a union + ptr = *gl->data + gl->size; + gl->size += 4; + data.bytes[0] = ptr[0]; + data.bytes[1] = ptr[1]; + data.bytes[2] = ptr[2]; + data.bytes[3] = ptr[3]; + return data.l; +} + +short GetGListID(GList *gl, char *name) { + short n; + char *a; + char *b; + + n = 1; + a = *gl->data + gl->size; + b = name; + while (*a) { + *(b++) = *(a++); + n++; + } + + *b = *a; + gl->size += n; + return n; +} + +void GetGListData(GList *gl, char *where, SInt32 size) { + memcpy(where, *gl->data + gl->size, size); + gl->size += size; +} + +static UInt32 hashpjw(const char *p) { + UInt32 h = 0; + UInt32 g; + + while (*p) { + h = (h << 4) + *p; + g = h & 0xF0000000; + if (g) { + h ^= (g >> 24); + h ^= g; + } + p++; + } + + return h % 0xFFFFFD; +} + +static SInt16 PHash(const unsigned char *string) { + SInt16 i; + SInt16 hashval; + UInt8 u; + + if ((hashval = *(string++))) { + i = hashval; + u = 0; + while (i > 0) { + u = (u >> 3) | (u << 5); + u += *(string++); + --i; + } + + hashval = (hashval << 8) | u; + } + + return hashval & 0x7FF; +} + +SInt16 CHash(const char *string) { + SInt16 i; + SInt16 hashval; + UInt8 u; + + if ((hashval = (UInt8) strlen(string))) { + i = hashval; + u = 0; + while (i > 0) { + u = (u >> 3) | (u << 5); + u += *(string++); + --i; + } + hashval = (hashval << 8) | u; + } + + return hashval & 0x7FF; +} + +HashNameNode *GetHashNameNode(const char *name) { + HashNameNode *node; + SInt16 n; + + if ((node = name_hash_nodes[n = CHash(name)]) == NULL) { + node = galloc(strlen(name) + sizeof(HashNameNode)); + name_hash_nodes[n] = node; + node->next = NULL; + node->id = hash_name_id++; + node->hashval = n; + strcpy(node->name, name); + return node; + } else { + for (;;) { + if (strcmp(name, node->name) == 0) { + if (node->id < 0) + node->id = hash_name_id++; + return node; + } + + if (node->next == NULL) { + node->next = galloc(strlen(name) + sizeof(HashNameNode)); + node = node->next; + node->next = NULL; + node->id = hash_name_id++; + node->hashval = n; + strcpy(node->name, name); + return node; + } else { + node = node->next; + } + } + } +} + +HashNameNode *GetHashNameNodeHash(const char *name, SInt16 hashval) { + HashNameNode *node; + + if ((node = name_hash_nodes[hashval]) == NULL) { + node = galloc(strlen(name) + sizeof(HashNameNode)); + name_hash_nodes[hashval] = node; + node->next = NULL; + node->id = hash_name_id++; + node->hashval = hashval; + strcpy(node->name, name); + return node; + } else { + for (;;) { + if (strcmp(name, node->name) == 0) + return node; + + if (node->next == NULL) { + node->next = galloc(strlen(name) + sizeof(HashNameNode)); + node = node->next; + node->next = NULL; + node->id = hash_name_id++; + node->hashval = hashval; + strcpy(node->name, name); + return node; + } else { + node = node->next; + } + } + } +} + +HashNameNode *GetHashNameNodeHash2(const char *name, SInt16 hashval) { + HashNameNode *node; + + if ((node = name_hash_nodes[hashval]) == NULL) { + node = galloc(strlen(name) + sizeof(HashNameNode)); + name_hash_nodes[hashval] = node; + node->next = NULL; + node->id = -1; + node->hashval = hashval; + strcpy(node->name, name); + return node; + } else { + for (;;) { + if (strcmp(name, node->name) == 0) + return node; + + if (node->next == NULL) { + node->next = galloc(strlen(name) + sizeof(HashNameNode)); + node = node->next; + node->next = NULL; + node->id = -1; + node->hashval = hashval; + strcpy(node->name, name); + return node; + } else { + node = node->next; + } + } + } +} + +HashNameNode *GetHashNameNodeExport(const char *name) { + HashNameNode *node; + SInt16 n; + + if ((node = name_hash_nodes[n = CHash(name)]) == NULL) { + node = galloc(strlen(name) + sizeof(HashNameNode)); + name_hash_nodes[n] = node; + node->next = NULL; + node->id = -1; + node->hashval = n; + strcpy(node->name, name); + return node; + } else { + for (;;) { + if (strcmp(name, node->name) == 0) + return node; + + if (node->next == NULL) { + node->next = galloc(strlen(name) + sizeof(HashNameNode)); + node = node->next; + node->next = NULL; + node->id = -1; + node->hashval = n; + strcpy(node->name, name); + return node; + } else { + node = node->next; + } + } + } +} + +SInt32 GetHashNameNodeExportID(HashNameNode *node) { + if (node->id < 0) + node->id = hash_name_id++; + return node->id; +} + +HashNameNode *GetHashNameNodeByID(SInt32 id) { + HashNameNode *node; + short i; + + for (i = 0; i < 2048; i++) { + for (node = name_hash_nodes[i]; node; node = node->next) { + if (id == node->id) + return node; + } + } + + return NULL; +} + +void NameHashExportReset() { + HashNameNode *node; + short i; + + for (i = 0; i < 2048; i++) { + node = name_hash_nodes[i]; + while (node) { + node->id = -1; + node = node->next; + } + } + + hash_name_id = 1; +} + +void NameHashWriteNameTable(GList *glist) { + HashNameNode *node; + HashNameNode **nodes; + short i; + SInt32 n; + + nodes = galloc(sizeof(HashNameNode *) * hash_name_id); + + for (i = 0; i < 2048; i++) { + node = name_hash_nodes[i]; + while (node) { + if (node->id > 0) + nodes[node->id] = node; + node = node->next; + } + } + + for (n = 1; n < hash_name_id; n++) { + node = nodes[n]; + AppendGListWord(glist, node->hashval); + AppendGListID(glist, node->name); + } + + if (glist->size & 1) + AppendGListByte(glist, 0); +} + +void NameHashWriteTargetEndianNameTable(GList *glist) { + HashNameNode *node; + HashNameNode **nodes; + short i; + SInt32 n; + + nodes = galloc(sizeof(HashNameNode *) * hash_name_id); + memclrw(nodes, sizeof(HashNameNode *) * hash_name_id); + + for (i = 0; i < 2048; i++) { + node = name_hash_nodes[i]; + while (node) { + if (node->id > 0) + nodes[node->id] = node; + node = node->next; + } + } + + for (n = 1; n < hash_name_id; n++) { + node = nodes[n]; + if (node == NULL) { + AppendGListTargetEndianWord(glist, 0); + AppendGListID(glist, ""); + } else { + AppendGListTargetEndianWord(glist, node->hashval); + AppendGListID(glist, node->name); + } + } + + if (glist->size & 1) + AppendGListByte(glist, 0); +} + +void InitNameHash() { + name_hash_nodes = galloc(2048 * sizeof(HashNameNode *)); + memclrw(name_hash_nodes, 2048 * sizeof(HashNameNode *)); + hash_name_id = 1; +} + +SInt32 CTool_TotalHeapSize() { + HeapBlock *blockp; + SInt32 size = 0; + + for (blockp = gheap.blocks; blockp; blockp = blockp->next) { + size += blockp->blocksize; + } + for (blockp = lheap.blocks; blockp; blockp = blockp->next) { + size += blockp->blocksize; + } + for (blockp = aheap.blocks; blockp; blockp = blockp->next) { + size += blockp->blocksize; + } + for (blockp = oheap.blocks; blockp; blockp = blockp->next) { + size += blockp->blocksize; + } + for (blockp = bheap.blocks; blockp; blockp = blockp->next) { + size += blockp->blocksize; + } + + return size; +} + +static void getheapinfo(HeapInfo *result, HeapMem *heap) { + HeapBlock *block; + + result->allocsize = heap->allocsize; + for (block = heap->blocks; block; block = block->next) { + result->total_size += block->blocksize - sizeof(HeapBlock); + result->total_free += block->blockfree; + result->blocks++; + if (block->blockfree > result->largest_free_block) + result->largest_free_block = block->blockfree; + } + + result->average_block_size = result->total_size / result->blocks; + result->average_block_free = result->total_free / result->blocks; +} + +void CTool_GetHeapInfo(HeapInfo *result, unsigned char heapID) { + memclrw(result, sizeof(HeapInfo)); + + switch (heapID) { + case 0: + getheapinfo(result, &gheap); + break; + case 1: + getheapinfo(result, &lheap); + break; + case 2: + getheapinfo(result, &aheap); + break; + case 3: + getheapinfo(result, &oheap); + break; + case 4: + getheapinfo(result, &bheap); + break; + case 5: + getheapinfo(result, &gheap); + getheapinfo(result, &lheap); + getheapinfo(result, &aheap); + getheapinfo(result, &oheap); + getheapinfo(result, &bheap); + break; + } +} + +static void MoreHeapSpace(HeapMem *heapp, SInt32 size) { + HeapBlock *blockp; + Handle hndl; + + blockp = heapp->blocks; + if (blockp) { + heapp->curblock->blockfree = heapp->curfree; + while (blockp) { + if (blockp->blockfree >= size) + goto gotBlock; + blockp = blockp->next; + } + } + + /* create new block */ + size += heapp->allocsize; + if (systemHandles) { + hndl = COS_NewOSHandle(size << 1); + if (hndl != 0) + goto createdTempDoubleBlock; + hndl = COS_NewOSHandle(size); + if (hndl != 0) + goto createdBlock; + } + hndl = COS_NewHandle(size); + if (hndl != 0) + goto createdBlock; + + if (heaperror) + heaperror(); + return; + + createdTempDoubleBlock: + size <<= 1; + goto createdBlock; + createdBlock: + COS_LockHandleHi(hndl); + blockp = (HeapBlock *) *hndl; + blockp->next = heapp->blocks; + heapp->blocks = blockp; + blockp->blockhandle = hndl; + blockp->blocksize = size; + blockp->blockfree = size - sizeof(HeapBlock); + gotBlock: + heapp->curblock = blockp; + heapp->curfree = blockp->blockfree; + heapp->curfreep = ((char *) blockp) + blockp->blocksize - blockp->blockfree; +} + +short initheaps(heaperror_t heaperrorproc) { + heaperror = NULL; + lheaplockcount = 0; + + memclrw(&gheap, sizeof(HeapMem)); + memclrw(&lheap, sizeof(HeapMem)); + memclrw(&aheap, sizeof(HeapMem)); + memclrw(&oheap, sizeof(HeapMem)); + memclrw(&bheap, sizeof(HeapMem)); + + gheap.allocsize = 0x38000; + lheap.allocsize = 0x10000; + aheap.allocsize = 0x4000; + oheap.allocsize = 0x40000; + bheap.allocsize = 0x4000; + + MoreHeapSpace(&gheap, 0); + MoreHeapSpace(&lheap, 0); + MoreHeapSpace(&aheap, 0); + MoreHeapSpace(&oheap, 0); + MoreHeapSpace(&bheap, 0); + + gheap.allocsize = 0x8000; + lheap.allocsize = 0x8000; + + heaperror = heaperrorproc; + + if (!gheap.curblock || !lheap.curblock || !aheap.curblock || !oheap.curblock || !bheap.curblock) + return -1; + else + return 0; +} + +short initgheap(heaperror_t heaperrorproc) { + heaperror = NULL; + lheaplockcount = 0; + + memclrw(&gheap, sizeof(HeapMem)); + memclrw(&lheap, sizeof(HeapMem)); + memclrw(&aheap, sizeof(HeapMem)); + memclrw(&oheap, sizeof(HeapMem)); + memclrw(&bheap, sizeof(HeapMem)); + + gheap.allocsize = 0x38000; + MoreHeapSpace(&gheap, 0); + gheap.allocsize = 0x8000; + + heaperror = heaperrorproc; + + if (!gheap.curblock) + return -1; + else + return 0; +} + +heaperror_t getheaperror() { + return heaperror; +} + +void setheaperror(heaperror_t heaperrorproc) { + heaperror = heaperrorproc; +} + +static void relheap(HeapMem *heapp) { + HeapBlock *blockp; + Handle hndl; + + blockp = heapp->blocks; + while (blockp) { + hndl = blockp->blockhandle; + blockp = blockp->next; + COS_FreeHandle(hndl); + } + + memclrw(heapp, sizeof(HeapMem)); +} + +void releaseheaps() { + relheap(&gheap); + relheap(&lheap); + relheap(&aheap); + relheap(&oheap); + relheap(&bheap); +} + +void releasegheap() { + relheap(&gheap); +} + +void releaseoheap() { + relheap(&gheap); + oheap.allocsize = 0x40000; + MoreHeapSpace(&oheap, 0); +} + +void *galloc(SInt32 s) { + char *cp; + + s = (s & ~7) + 8; + if (gheap.curfree < s) + MoreHeapSpace(&gheap, s); + + gheap.curfree -= s; + cp = gheap.curfreep; + gheap.curfreep = cp + s; + return cp; +} + +void *lalloc(SInt32 s) { + char *cp; + + s = (s & ~7) + 8; + if (lheap.curfree < s) + MoreHeapSpace(&lheap, s); + + lheap.curfree -= s; + cp = lheap.curfreep; + lheap.curfreep = cp + s; + return cp; +} + +void *aalloc(SInt32 s) { + char *cp; + + s = (s & ~7) + 8; + if (aheap.curfree < s) + MoreHeapSpace(&aheap, s); + + aheap.curfree -= s; + cp = aheap.curfreep; + aheap.curfreep = cp + s; + return cp; +} + +void *oalloc(SInt32 s) { + char *cp; + + s = (s & ~7) + 8; + if (oheap.curfree < s) + MoreHeapSpace(&oheap, s); + + oheap.curfree -= s; + cp = oheap.curfreep; + oheap.curfreep = cp + s; + return cp; +} + +void *balloc(SInt32 s) { + char *cp; + + s = (s & ~7) + 8; + if (bheap.curfree < s) + MoreHeapSpace(&bheap, s); + + bheap.curfree -= s; + cp = bheap.curfreep; + bheap.curfreep = cp + s; + return cp; +} + +void locklheap() { + lheaplockcount++; +} + +void unlocklheap() { + if (lheaplockcount > 0) + --lheaplockcount; +} + +void freelheap() { + // possible inline or macro? + HeapBlock *blockp; + + if (lheaplockcount == 0) { + blockp = lheap.blocks; + lheap.curblock = blockp; + lheap.curfreep = ((char *) blockp) + sizeof(HeapBlock); + lheap.curfree = blockp->blocksize - sizeof(HeapBlock); + + while (blockp) { + blockp->blockfree = blockp->blocksize - sizeof(HeapBlock); + blockp = blockp->next; + } + } +} + +void freeaheap() { + HeapBlock *blockp; + + blockp = aheap.blocks; + aheap.curblock = blockp; + aheap.curfreep = ((char *) blockp) + sizeof(HeapBlock); + aheap.curfree = blockp->blocksize - sizeof(HeapBlock); + + while (blockp) { + blockp->blockfree = blockp->blocksize - sizeof(HeapBlock); + blockp = blockp->next; + } +} + +void freeoheap() { + HeapBlock *blockp; + + blockp = oheap.blocks; + oheap.curblock = blockp; + oheap.curfreep = ((char *) blockp) + sizeof(HeapBlock); + oheap.curfree = blockp->blocksize - sizeof(HeapBlock); + + while (blockp) { + blockp->blockfree = blockp->blocksize - sizeof(HeapBlock); + blockp = blockp->next; + } +} + +void freebheap() { + HeapBlock *blockp; + + blockp = bheap.blocks; + bheap.curblock = blockp; + bheap.curfreep = ((char *) blockp) + sizeof(HeapBlock); + bheap.curfree = blockp->blocksize - sizeof(HeapBlock); + + while (blockp) { + blockp->blockfree = blockp->blocksize - sizeof(HeapBlock); + blockp = blockp->next; + } +} + +char *ScanHex(char *string, UInt32 *result, Boolean *overflow) { + short c; + UInt32 x; + + x = 0; + *overflow = 0; + + for (;;) { + c = *string; + if (c >= '0' && c <= '9') { + c -= '0'; + } else if (c >= 'A' && c <= 'F') { + c -= ('A' - 10); + } else if (c >= 'a' && c <= 'f') { + c -= ('a' - 10); + } else { + break; + } + + if (x & 0xF0000000) + *overflow = 1; + x = (x << 4) | c; + ++string; + } + + *result = x; + return string; +} + +char *ScanOct(char *string, UInt32 *result, Boolean *overflow) { + short c; + UInt32 x; + + x = 0; + *overflow = 0; + + for (;;) { + c = *string - '0'; + if (c >= 0 && c <= 9) { + if (c >= 8) { + *overflow = 1; + ++string; + break; + } + } else { + break; + } + + if (x & 0xE0000000) + *overflow = 1; + x = (x << 3) | c; + ++string; + } + + *result = x; + return string; +} + +char *ScanDec(char *string, UInt32 *result, Boolean *overflow) { + short c; + UInt32 x; + + x = 0; + *overflow = 0; + + for (;;) { + c = *string - '0'; + if (c >= 0 && c <= 9) { + if (x >= 0x19999999 && (x > 0x19999999 || c > 5)) + *overflow = 1; + } else { + break; + } + + x = (x << 3) + (x << 1) + c; + ++string; + } + + *result = x; + return string; +} + +static char *UnmangleClassname(char *name, char **classname, short *classnamesize, char **out, short *outsize, Boolean addclassname) { + char *cp; + short i; + short n; + short os; + + *classnamesize = 0; + if (*(name++) != '_' || *(name++) != '_') + return name; + + n = 0; + while (name[0] >= '0' && name[0] <= '9') { + n = (n * 10) + name[0] - '0'; + ++name; + } + + if (n > 0) { + *classname = name; + *classnamesize = n; + + if (addclassname) { + cp = *out; + os = *outsize; + for (i = 0; i < n && os < 255; i++, os++) { + *(cp++) = name[i]; + } + if (os < 255) { + *(cp++) = ':'; + os++; + } + if (os < 255) { + *(cp++) = ':'; + os++; + } + *out = cp; + *outsize = os; + } + } + + return name + n; +} + +static char *UnmangleAppend(char *name, char namesize, char **out, short *outsize) { + char *cp; + short i; + short os; + + cp = *out; + os = *outsize; + + for (i = 0; i < namesize && os < 255; i++, os++) { + *(cp++) = name[i]; + } + + *out = cp; + *outsize = os; +} + +void OldUnmangle(char *name, char *out, Boolean full) { + short n; + short namesize; + short classnamesize; + char *classname; + char *cptr; + + if (*name == '.') + ++name; + + namesize = 0; + cptr = name; + if (name[0] == '_' && name[1] == '_') { + if (name[2] == 'c' && name[3] == 't') { + cptr = UnmangleClassname(&name[4], &classname, &classnamesize, &out, &namesize, full); + if (classnamesize == 0) + goto invalid; + UnmangleAppend(classname, classnamesize, &out, &namesize); + } else if (name[2] == 'd' && name[3] == 't') { + cptr = UnmangleClassname(&name[4], &classname, &classnamesize, &out, &namesize, full); + if (classnamesize == 0) + goto invalid; + if (namesize <= 255) { + *(out++) = '~'; + namesize++; + } + UnmangleAppend(classname, classnamesize, &out, &namesize); + } else if (name[2] == 'n' && name[3] == 'w') { + cptr = UnmangleClassname(&name[4], &classname, &classnamesize, &out, &namesize, full); + UnmangleAppend("operator new", 15, &out, &namesize); + } else if (name[2] == 'd' && name[3] == 'l') { + cptr = UnmangleClassname(&name[4], &classname, &classnamesize, &out, &namesize, full); + UnmangleAppend("operator delete", 15, &out, &namesize); + } else { + invalid: + strncpy(out, name, 256); + return; + } + } else { + n = 0; + while (*cptr) { + ++cptr; + ++n; + if (cptr[0] == '_' && cptr[1] == '_') { + cptr = UnmangleClassname(cptr, &classname, &classnamesize, &out, &namesize, full); + break; + } + } + UnmangleAppend(name, n, &out, &namesize); + } + + if (full && cptr[0] == 'F') { + if (cptr[1] == 'v') { + UnmangleAppend("(void)", 6, &out, &namesize); + } else { + UnmangleAppend("(...)", 5, &out, &namesize); + } + } + + *out = 0; +} + +short hash(char *a) { + char hash = 0; + + while (*a) { + hash = hash << 1; + hash ^= *(a++); + } + + return hash & 0x7F; +} + +void memclr(void *ptr, SInt32 size) { + memset(ptr, 0, size); +} + +void memclrw(void *ptr, SInt32 size) { + memset(ptr, 0, size); +} + +void CToLowercase(char *a, char *b) { + char ch; + + do { + ch = tolower(*(a++)); + *(b++) = ch; + } while (ch); +} + +short getbit(SInt32 l) { + switch (l) { + case 0: return -1; + case 1: return 0; + case 2: return 1; + case 4: return 2; + case 8: return 3; + case 0x10: return 4; + case 0x20: return 5; + case 0x40: return 6; + case 0x80: return 7; + case 0x100: return 8; + case 0x200: return 9; + case 0x400: return 10; + case 0x800: return 11; + case 0x1000: return 12; + case 0x2000: return 13; + case 0x4000: return 14; + case 0x8000: return 15; + case 0x10000: return 16; + case 0x20000: return 17; + case 0x40000: return 18; + case 0x80000: return 19; + case 0x100000: return 20; + case 0x200000: return 21; + case 0x400000: return 22; + case 0x800000: return 23; + case 0x1000000: return 24; + case 0x2000000: return 25; + case 0x4000000: return 26; + case 0x8000000: return 27; + case 0x10000000: return 28; + case 0x20000000: return 29; + case 0x40000000: return 30; + case 0x80000000: return 31; + default: return -2; + } +} + +void CTool_EndianConvertWord64(CInt64 ci, char *result) { + UInt32 buf[2]; + buf[0] = ci.hi; + buf[1] = ci.lo; + memcpy(result, buf, 8); +} + +UInt16 CTool_EndianConvertInPlaceWord16Ptr(UInt16 *x) { + unsigned short v; + v = *x; + // this probably has a conversion on non-ppc + *x = v; + return v; +} + +UInt32 CTool_EndianConvertInPlaceWord32Ptr(UInt32 *x) { + unsigned long v; + v = *x; + // this probably has a conversion on non-ppc + *x = v; + return v; +} + +void CTool_EndianConvertVector128() { + // not correct but idc +} + +HashNameNode *CTool_GetPathName(const FSSpec *fss, SInt32 *moddateptr) { + char name[256]; + COS_FileGetPathName(name, fss, moddateptr); + return GetHashNameNodeExport(name); +} + +int strcat_safe(char *dest, const char *src, SInt32 len) { + SInt32 dest_len; + char ch; + + dest_len = strlen(dest); + dest += dest_len; + len -= dest_len; + if (len < 0) + return 1; + + while (len != 0) { + ch = *(dest++) = *(src++); + if (ch == 0) + break; + --len; + } + + if (len == 0 && dest[-1]) { + dest[-1] = 0; + return 1; + } else { + return 0; + } +} diff --git a/compiler_and_linker/unsorted/CCompiler.c b/compiler_and_linker/unsorted/CCompiler.c new file mode 100644 index 0000000..d496389 --- /dev/null +++ b/compiler_and_linker/unsorted/CCompiler.c @@ -0,0 +1,255 @@ +#include "compiler/common.h" +#include "compiler.h" +#include "compiler/types.h" +#include "pref_structs.h" +#include "compiler/CompilerTools.h" + +Boolean systemHandles; + +static Boolean using_license_manager; +Boolean crippled; +SInt32 license_cookie; +CParams cparams; + +// TODO move me to CParser.c, or maybe CMachine.c? +Type sttemplexpr = {TYPETEMPLDEPEXPR, 0}; +Type stillegal = {TYPEILLEGAL, 1}; +Type stvoid = {TYPEVOID, 0}; +TypePointer void_ptr = {TYPEPOINTER, 0, &stvoid, 0}; +TypeFunc rt_func = {TYPEFUNC, 0, NULL, NULL, &stvoid, 0, 0}; +// TODO move me to CParser.c + +static void get_extension(ConstStringPtr src, char *dst) { + int ep; + + dst[0] = 0; + for (ep = src[0]; src[ep] != '.'; ep--) {} + + if (ep >= 2) { + int x; + for (x = 0; (x + ep) <= src[0]; x++) + dst[x] = src[x + ep]; + dst[x] = 0; + } +} + +static int setup_param_block(CWPluginContext context) { + static char target_name[128]; + CWTargetInfo tinfo; + + memset(&cparams, 0, sizeof(CParams)); + cparams.context = context; + + if (CWGetPluginRequest(context, &cparams.pluginRequest) != cwNoErr) + return 0; + if (CWGetAPIVersion(context, &cparams.apiVersion) != cwNoErr) + return 0; + if (CWGetProjectFile(context, &cparams.projectFile) != cwNoErr) + return 0; + if (CWGetProjectFileCount(context, &cparams.projectFileCount) != cwNoErr) + return 0; + if (CWGetMainFileNumber(context, &cparams.mainFileNumber) != cwNoErr) + return 0; + if (CWGetMainFileSpec(context, &cparams.mainFileSpec) != cwNoErr) + return 0; + if (CWGetMainFileText(context, &cparams.mainFileText, &cparams.mainFileTextLength) != cwNoErr) + return 0; + if (CWIsPrecompiling(context, &cparams.isPrecompiling) != cwNoErr) + return 0; + if (CWIsAutoPrecompiling(context, &cparams.isAutoPrecompiling) != cwNoErr) + return 0; + if (CWIsPreprocessing(context, &cparams.isPreprocessing) != cwNoErr) + return 0; + if (CWIsGeneratingDebugInfo(context, &cparams.isGeneratingDebugInfo) != cwNoErr) + return 0; + if (CWIsCachingPrecompiledHeaders(context, &cparams.isCachingPrecompiledHeaders) != cwNoErr) + return 0; + if (CWGetBrowseOptions(context, &cparams.browseOptions) != cwNoErr) + return 0; + cparams.field276 = cparams.isPreprocessing == 0; + if (CWGetMainFileID(context, &cparams.mainFileID) != cwNoErr) + return 0; + if (CWGetTargetInfo(context, &tinfo) != cwNoErr) + return 0; + + cparams.targetOS = tinfo.targetOS; + cparams.targetCPU = tinfo.targetCPU; + cparams.targetName = target_name; + return CWGetTargetName(context, target_name, sizeof(target_name)) == cwNoErr; +} + +static short store_compile_results() { + CWResult result; + + if (cparams.objectDataHandle) + CWSecretAttachHandle(cparams.context, cparams.objectDataHandle, &cparams.objectdata.objectdata); + if (cparams.browseDataHandle) + CWSecretAttachHandle(cparams.context, cparams.browseDataHandle, &cparams.objectdata.browsedata); + + if (cparams.isPreprocessing) { + if (cparams.objectdata.objectdata) { + CWNewTextDocumentInfo docinfo; + memset(&docinfo, 0, sizeof(CWNewTextDocumentInfo)); + docinfo.text = cparams.objectdata.objectdata; + cparams.objectdata.objectdata = NULL; + result = CWCreateNewTextDocument(cparams.context, &docinfo); + } + } else { + result = CWStoreObjectData(cparams.context, cparams.mainFileNumber, &cparams.objectdata); + } + + return result; +} + +static void initialize_compiler_options(CParams *params) { + static PFrontEndC pFrontEnd; + PWarningC pWarningC; + PGlobalOptimizer pGlobalOptimizer; + Handle prefsdata; + char extension[256]; + + memclrw(&copts, sizeof(COpts)); + + CWSecretGetNamedPreferences(cparams.context, "C/C++ Compiler", &prefsdata); + pFrontEnd = *((PFrontEndC *) *prefsdata); + + copts.little_endian = 0; + copts.cplusplus = 1; + copts.objective_c = pFrontEnd.objective_c; + get_extension(params->mainFileSpec.name, extension); + if (!strcmp(extension, ".c") || !strcmp(extension, ".h") || !strcmp(extension, ".pch")) { + copts.cplusplus = pFrontEnd.cplusplus; + } else if (!strcmp(extension, ".m")) { + copts.cplusplus = pFrontEnd.cplusplus; + copts.objective_c = 1; + } else if (!strcmp(extension, ".mm") || !strcmp(extension, ".M")) { + copts.cplusplus = 1; + copts.objective_c = 1; + } + + copts.require_prototypes = pFrontEnd.checkprotos; + copts.ARM_conform = pFrontEnd.arm; + copts.ARM_scoping = pFrontEnd.arm; + copts.trigraphs = pFrontEnd.trigraphs; + copts.only_std_keywords = pFrontEnd.onlystdkeywords; + copts.enumsalwaysint = pFrontEnd.enumsalwaysint; + copts.mpwc_relax = pFrontEnd.mpwpointerstyle; + copts.ANSI_strict = pFrontEnd.ansistrict; + copts.mpwc_newline = pFrontEnd.mpwcnewline; + copts.exceptions = pFrontEnd.enableexceptions; + copts.dont_reuse_strings = pFrontEnd.dontreusestrings; + copts.pool_strings = pFrontEnd.poolstrings; + copts.dont_inline = pFrontEnd.dontinline; + copts.useRTTI = pFrontEnd.useRTTI; + copts.oldprefixname = pFrontEnd.oldprefixname; + copts.multibyteaware = pFrontEnd.multibyteaware; + copts.unsignedchars = pFrontEnd.unsignedchars; + copts.autoinline = pFrontEnd.autoinline; + copts.direct_to_som = pFrontEnd.direct_to_som; + copts.som_env_check = pFrontEnd.som_env_check; + copts.booltruefalse = pFrontEnd.booltruefalse; + copts.always_inline = pFrontEnd.alwaysinline; + copts.inlinelevel = pFrontEnd.inlinelevel; + copts.wchar_type = pFrontEnd.wchar_type; + copts.ecplusplus = pFrontEnd.ecplusplus; + copts.defer_codegen = pFrontEnd.defer_codegen; + copts.inline_max_size = 512; + copts.inline_max_total_size = 100000; + + CWSecretGetNamedPreferences(cparams.context, "C/C++ Warnings", &prefsdata); + pWarningC = *((PWarningC *) *prefsdata); + + copts.warn_illpragma = pWarningC.warn_illpragma; + copts.warn_emptydecl = pWarningC.warn_emptydecl; + copts.warn_possunwant = pWarningC.warn_possunwant; + copts.warn_unusedvar = pWarningC.warn_unusedvar; + copts.warn_unusedarg = pWarningC.warn_unusedarg; + copts.warn_extracomma = pWarningC.warn_extracomma; + copts.pedantic = pWarningC.pedantic; + copts.warningerrors = pWarningC.warningerrors; + copts.warn_hidevirtual = pWarningC.warn_hidevirtual; + copts.warn_implicitconv = pWarningC.warn_implicitconv; + copts.warn_notinlined = pWarningC.warn_notinlined; + copts.warn_structclass = pWarningC.warn_structclass; + + CWSecretGetNamedPreferences(cparams.context, "PPC Global Optimizer", &prefsdata); + pGlobalOptimizer = *((PGlobalOptimizer *) *prefsdata); + + copts.optimizationlevel = pGlobalOptimizer.optimizationlevel; + copts.optimize_for_size = (Boolean) (pGlobalOptimizer.optfor == 1); + + copts.crippled = crippled; + copts.loop_unroll_count = 8; + copts.loop_unroll_size_threshold = 100; + copts.isGeneratingDebugInfo = params->isGeneratingDebugInfo; + copts.pchCreator = CWFOURCHAR('C','W','I','E'); + copts.pchType = CWFOURCHAR('M','M','C','H'); + copts.text = CWFOURCHAR('T','E','X','T'); +} + +static void GetLicense() { + if (!license_cookie) { + crippled = 1; + CWCheckoutLicense(cparams.context, "MacOS_Plugins_MacOS_Unlimited", "7", 2, NULL, &license_cookie); + if (license_cookie) { + CWCheckinLicense(cparams.context, license_cookie); + crippled = 0; + } + + CWCheckoutLicense(cparams.context, "MacOS_Plugins_MacOS_Limited", "7", 0, NULL, &license_cookie); + using_license_manager = 1; + } +} + +static void ReleaseLicense() { + if (license_cookie && using_license_manager) + CWCheckinLicense(cparams.context, license_cookie); + using_license_manager = 0; + license_cookie = 0; +} + +CWPLUGIN_ENTRY(MWC_main)(CWPluginContext context) { + CWResult result; + SInt32 request; + + result = cwNoErr; + CWGetPluginRequest(context, &request); + + switch (request) { + case reqInitialize: + cparams.context = context; + license_cookie = 0; + CodeGen_InitCompiler(); + break; + case reqTerminate: + cparams.context = context; + CodeGen_TermCompiler(); + ReleaseLicense(); + break; + case reqCompile: + setup_param_block(context); + GetLicense(); + if (license_cookie) { + initialize_compiler_options(&cparams); + CodeGen_UpdateOptimizerOptions(); + CodeGen_InitBackEndOptions(); + CodeGen_UpdateOptimizerOptions(); + CodeGen_UpdateBackEndOptions(); + if (C_Compiler(&cparams)) + result = store_compile_results(); + else + result = cwErrRequestFailed; + } else { + result = cwErrSilent; + } + break; + } + + return CWDonePluginRequest(context, result); +} + +void PrintProgressFunction(const char *str) { + char buf[96]; + sprintf(buf, "Compiling function:\t%.64s", str); + CWShowStatus(cparams.context, buf, ""); +} diff --git a/compiler_and_linker/unsorted/CError.c b/compiler_and_linker/unsorted/CError.c new file mode 100644 index 0000000..e7493f3 --- /dev/null +++ b/compiler_and_linker/unsorted/CError.c @@ -0,0 +1,1096 @@ +#include "cos.h" +#include "compiler/CError.h" +#include "compiler/CInt64.h" +#include "compiler/CompilerTools.h" +#include "compiler/enode.h" +#include "compiler/objc.h" +#include "compiler/objects.h" +#include "compiler/scopes.h" +#include "compiler/templates.h" +#include "compiler/tokens.h" +#include "compiler.h" + +TStreamElement *cerror_locktoken; +static TStreamElement *cerror_token; +static short cerror_errorcount; +static SInt32 cerror_lasterrorline; +char cerror_synchdata[32]; +short cerror_synchoffset; +int CError_BreakPointcount; + +void CError_Init() { + cerror_errorcount = 0; + cerror_lasterrorline = -1; + cerror_token = 0; + cerror_locktoken = 0; +} + +void CError_SetErrorToken(TStreamElement *token) { + if (token && token->tokenfile) + cerror_token = token; +} + +void CError_SetNullErrorToken() { + cerror_token = (TStreamElement *) -1; +} + +void CError_LockErrorPos(TStreamElement *token, TStreamElement **saved) { + *saved = cerror_locktoken; + if (token && token->tokenfile) + cerror_locktoken = token; +} + +void CError_UnlockErrorPos(TStreamElement **saved) { + cerror_locktoken = *saved; +} + +void CError_ResetErrorSkip() { + cerror_lasterrorline = -1; +} + +void CError_GetErrorString(char *buf, short code) { +#line 142 + CError_ASSERT(code >= CErrorStr100 && code < CErrorStrMAX); + COS_GetString(buf, 10000, code - 99); +} + +void CError_BufferInit(CErrorBuffer *eb, char *buf, SInt32 bufSize) { + eb->start = eb->end = buf; + eb->size = eb->remaining = bufSize - 1; +} + +void CError_BufferGrow(CErrorBuffer *eb, SInt32 amount) { + char *newBuf; + + newBuf = lalloc(eb->size + amount); + memcpy(newBuf, eb->start, eb->size); + eb->start = newBuf; + eb->end = newBuf + eb->size - eb->remaining; + eb->size += amount; + eb->remaining += amount; +} + +void CError_BufferAppendChar(CErrorBuffer *eb, char ch) { + if (eb) { + if (!eb->remaining) + CError_BufferGrow(eb, 256); + *(eb->end++) = ch; + eb->remaining--; + } +} + +void CError_BufferAppendString(CErrorBuffer *eb, const char *str) { + size_t len; + + if (eb) { + len = strlen(str); + if (eb->remaining < len) + CError_BufferGrow(eb, len); + memcpy(eb->end, str, len); + eb->end += len; + eb->remaining -= len; + } +} + +void CError_BufferTerminate(CErrorBuffer *eb) { + if (eb->remaining == 0) + CError_BufferGrow(eb, 1); + *eb->end = 0; + eb->remaining = 0; +} + +void CError_BufferAppendQualifier(CErrorBuffer *eb, UInt32 qual) { + if (qual & Q_PASCAL) + CError_BufferAppendString(eb, "pascal "); + if (qual & Q_CONST) + CError_BufferAppendString(eb, "const "); + if (qual & Q_VOLATILE) + CError_BufferAppendString(eb, "volatile "); + if (qual & Q_EXPLICIT) + CError_BufferAppendString(eb, "explicit "); + if (qual & Q_RESTRICT) + CError_BufferAppendString(eb, "restrict "); +} + +void CError_BufferAppendTemplArgExpr(CErrorBuffer *eb, ENode *node) { + char buf[32]; + + if (node) { + switch (node->type) { + case EINTCONST: + CInt64_PrintDec(buf, node->data.intval); + CError_BufferAppendString(eb, buf); + return; + case EOBJREF: + CError_BufferAppendChar(eb, '&'); + CError_AppendObjectName(eb, node->data.objref); + return; + } + } + + CError_BufferAppendString(eb, "{targ_expr}"); +} + +void CError_BufferAppendTemplArg(CErrorBuffer *eb, TemplArg *targ) { + switch (targ->pid.type) { + case TPT_TYPE: + CError_BufferAppendType(eb, targ->data.typeparam.type, targ->data.typeparam.qual); + break; + case TPT_NONTYPE: + CError_BufferAppendTemplArgExpr(eb, targ->data.paramdecl.expr); + break; + case TPT_TEMPLATE: + CError_BufferAppendType(eb, targ->data.ttargtype, 0); + break; + default: +#line 300 + CError_FATAL(); + } +} + +void CError_BufferAppendTemplArgs(CErrorBuffer *eb, TemplArg *targs) { + if (targs) { + CError_BufferAppendChar(eb, '<'); + while (targs) { + CError_BufferAppendTemplArg(eb, targs); + if (targs->next) + CError_BufferAppendString(eb, ", "); + targs = targs->next; + } + CError_BufferAppendChar(eb, '>'); + } +} + +void CError_BufferAppendNameSpace(CErrorBuffer *eb, NameSpace *nspace) { + while (nspace) { + if (nspace->name) { + CError_BufferAppendNameSpace(eb, nspace->parent); + if (nspace->theclass) { + CError_BufferAppendString(eb, nspace->theclass->classname->name); + if (nspace->theclass->flags & CLASS_FLAGS_800) + CError_BufferAppendTemplArgs( + eb, + !TEMPL_CLASS_INST(nspace->theclass)->oargs ? TEMPL_CLASS_INST(nspace->theclass)->inst_args : TEMPL_CLASS_INST(nspace->theclass)->oargs + ); + } else { + CError_BufferAppendString(eb, nspace->name->name); + } + CError_BufferAppendString(eb, "::"); + return; + } + nspace = nspace->parent; + } +} + +void CError_BufferAppendPType(CErrorBuffer *eb, Type *ty) { + switch (ty->type) { + case TYPEPOINTER: + CError_BufferAppendPType(eb, TYPE_POINTER(ty)->target); + if (TYPE_POINTER(ty)->qual & Q_REFERENCE) + CError_BufferAppendString(eb, "&"); + else + CError_BufferAppendString(eb, "*"); + CError_BufferAppendQualifier(eb, TYPE_POINTER(ty)->qual); + break; + case TYPEMEMBERPOINTER: + CError_BufferAppendPType(eb, TYPE_MEMBER_POINTER(ty)->ty1); + CError_BufferAppendType(eb, TYPE_MEMBER_POINTER(ty)->ty2, 0); + CError_BufferAppendString(eb, "::*"); + CError_BufferAppendQualifier(eb, TYPE_MEMBER_POINTER(ty)->qual); + break; + } +} + +void CError_BufferAppendTemplDepType(CErrorBuffer *eb, TypeTemplDep *type) { + char buf[64]; + switch (type->dtype) { + case TEMPLDEP_ARGUMENT: + if (type->u.pid.nindex) + sprintf(buf, "T%ld_%ld", type->u.pid.nindex, type->u.pid.index); + else + sprintf(buf, "T%ld", type->u.pid.index); + CError_BufferAppendString(eb, buf); + break; + case TEMPLDEP_QUALNAME: + CError_BufferAppendTemplDepType(eb, type->u.qual.type); + CError_BufferAppendString(eb, "::"); + CError_BufferAppendString(eb, type->u.qual.name->name); + break; + case TEMPLDEP_TEMPLATE: + CError_BufferAppendType(eb, (Type *) type->u.templ.templ, 0); + CError_BufferAppendTemplArgs(eb, type->u.templ.args); + break; + case TEMPLDEP_ARRAY: + CError_BufferAppendType(eb, type->u.array.type, 0); + CError_BufferAppendChar(eb, '['); + CError_BufferAppendTemplArgExpr(eb, type->u.array.index); + CError_BufferAppendChar(eb, ']'); + break; + case TEMPLDEP_QUALTEMPL: + CError_BufferAppendTemplDepType(eb, type->u.qualtempl.type); + CError_BufferAppendString(eb, "::"); + CError_BufferAppendTemplArgs(eb, type->u.qualtempl.args); + break; + case TEMPLDEP_BITFIELD: + CError_BufferAppendType(eb, type->u.bitfield.type, 0); + CError_BufferAppendChar(eb, '['); + CError_BufferAppendTemplArgExpr(eb, type->u.bitfield.size); + CError_BufferAppendChar(eb, ']'); + break; + default: +#line 463 + CError_FATAL(); + } +} + +void CError_BufferAppendFuncArgs(CErrorBuffer *eb, TypeFunc *tfunc, Boolean isMethod) { + // not matching - weirdness with referencing string constants + FuncArg *arg; + UInt32 qual; + + qual = 0; + CError_BufferAppendChar(eb, '('); + if ((arg = tfunc->args)) { + if (isMethod) { + qual = arg->qual; + arg = arg->next; + if (arg) + arg = arg->next; + } else if ((tfunc->flags & FUNC_FLAGS_METHOD) && !TYPE_METHOD(tfunc)->x26) { + qual = arg->qual; + arg = arg->next; + if (arg) { + if ((tfunc->flags & FUNC_FLAGS_2000) || ((tfunc->flags & FUNC_FLAGS_1000) && (TYPE_METHOD(tfunc)->theclass->flags & CLASS_FLAGS_20))) + arg = arg->next; + } + } + + while (arg) { + if (arg == &elipsis || arg == &oldstyle) { + CError_BufferAppendString(eb, "..."); + break; + } else { + CError_BufferAppendType(eb, arg->type, arg->qual); + } + + if (!arg->next) { + CError_BufferAppendString(eb, ", "); + break; + } + } + } + CError_BufferAppendChar(eb, ')'); + if (qual) + CError_BufferAppendQualifier(eb, qual); +} + +void CError_BufferAppendType(CErrorBuffer *eb, Type *ty, UInt32 qual) { + // not matching - register issues + char buf[16]; + Type *scan, *scan2; + + switch (ty->type) { + case TYPEVOID: + CError_BufferAppendQualifier(eb, qual); + CError_BufferAppendString(eb, "void"); + break; + case TYPEINT: + case TYPEFLOAT: + CError_BufferAppendQualifier(eb, qual); + switch (TYPE_INTEGRAL(ty)->integral) { + case IT_BOOL: + CError_BufferAppendString(eb, "bool"); + break; + case IT_CHAR: + CError_BufferAppendString(eb, "char"); + break; + case IT_UCHAR: + CError_BufferAppendString(eb, "unsigned char"); + break; + case IT_SCHAR: + CError_BufferAppendString(eb, "signed char"); + break; + case IT_WCHAR_T: + CError_BufferAppendString(eb, "wchar_t"); + break; + case IT_SHORT: + CError_BufferAppendString(eb, "short"); + break; + case IT_USHORT: + CError_BufferAppendString(eb, "unsigned short"); + break; + case IT_INT: + CError_BufferAppendString(eb, "int"); + break; + case IT_UINT: + CError_BufferAppendString(eb, "unsigned int"); + break; + case IT_LONG: + CError_BufferAppendString(eb, "long"); + break; + case IT_ULONG: + CError_BufferAppendString(eb, "unsigned long"); + break; + case IT_LONGLONG: + CError_BufferAppendString(eb, "long long"); + break; + case IT_ULONGLONG: + CError_BufferAppendString(eb, "unsigned long long"); + break; + case IT_FLOAT: + CError_BufferAppendString(eb, "float"); + break; + case IT_SHORTDOUBLE: + CError_BufferAppendString(eb, "short double"); + break; + case IT_DOUBLE: + CError_BufferAppendString(eb, "double"); + break; + case IT_LONGDOUBLE: + CError_BufferAppendString(eb, "long double"); + break; + default: +#line 584 + CError_FATAL(); + } + break; + case TYPEENUM: + CError_BufferAppendQualifier(eb, qual); + CError_BufferAppendNameSpace(eb, TYPE_ENUM(ty)->nspace); + if (TYPE_ENUM(ty)->enumname) + CError_BufferAppendString(eb, TYPE_ENUM(ty)->enumname->name); + else + CError_BufferAppendString(eb, "{unnamed-enum}"); + break; + case TYPESTRUCT: + CError_BufferAppendQualifier(eb, qual); + switch (TYPE_STRUCT(ty)->stype) { + case STRUCT_TYPE_STRUCT: + CError_BufferAppendString(eb, "struct "); + break; + case STRUCT_TYPE_UNION: + CError_BufferAppendString(eb, "struct "); + break; + case STRUCT_TYPE_4: + case STRUCT_TYPE_5: + case STRUCT_TYPE_6: + case STRUCT_TYPE_7: + case STRUCT_TYPE_8: + case STRUCT_TYPE_9: + case STRUCT_TYPE_A: + case STRUCT_TYPE_B: + case STRUCT_TYPE_C: + case STRUCT_TYPE_D: + case STRUCT_TYPE_E: + break; + default: +#line 618 + CError_FATAL(); + } + if (TYPE_STRUCT(ty)->name) + CError_BufferAppendString(eb, TYPE_STRUCT(ty)->name->name); + break; + case TYPECLASS: + CError_BufferAppendQualifier(eb, qual); + CError_BufferAppendNameSpace(eb, TYPE_CLASS(ty)->nspace->parent); + if (TYPE_CLASS(ty)->classname) { + CError_BufferAppendString(eb, TYPE_CLASS(ty)->classname->name); + if (TYPE_CLASS(ty)->flags & CLASS_FLAGS_800) + CError_BufferAppendTemplArgs( + eb, + TEMPL_CLASS_INST(ty)->oargs ? TEMPL_CLASS_INST(ty)->oargs : TEMPL_CLASS_INST(ty)->inst_args + ); + } else { + CError_BufferAppendString(eb, "{unnamed-class}"); + } + break; + case TYPEPOINTER: + case TYPEMEMBERPOINTER: + scan = ty; + next_ptr: + switch (scan->type) { + case TYPEPOINTER: + scan = TYPE_POINTER(scan)->target; + goto next_ptr; + case TYPEMEMBERPOINTER: + scan = TYPE_MEMBER_POINTER(scan)->ty1; + goto next_ptr; + } + + CError_BufferAppendQualifier(eb, qual); + switch (scan->type) { + case TYPEFUNC: + if (TYPE_FUNC(scan)->flags & FUNC_FLAGS_PASCAL) + CError_BufferAppendString(eb, "pascal "); + CError_BufferAppendType(eb, TYPE_FUNC(scan)->functype, 0); + CError_BufferAppendString(eb, " ("); + CError_BufferAppendPType(eb, ty); + CError_BufferAppendChar(eb, ')'); + CError_BufferAppendFuncArgs(eb, TYPE_FUNC(scan), ty->type == TYPEMEMBERPOINTER); + break; + case TYPEARRAY: + scan2 = scan; + while (scan->type == TYPEARRAY) + scan = TYPE_POINTER(scan)->target; + CError_BufferAppendType(eb, scan, 0); + CError_BufferAppendString(eb, " ("); + CError_BufferAppendPType(eb, ty); + CError_BufferAppendChar(eb, ')'); + ty = scan2; + goto append_array_lengths; + default: + CError_BufferAppendType(eb, scan, 0); + CError_BufferAppendChar(eb, ' '); + CError_BufferAppendPType(eb, ty); + break; + } + break; + case TYPEFUNC: + if (TYPE_FUNC(ty)->flags & FUNC_FLAGS_PASCAL) + CError_BufferAppendString(eb, "pascal "); + CError_BufferAppendQualifier(eb, qual); + CError_BufferAppendType(eb, TYPE_FUNC(ty)->functype, 0); + CError_BufferAppendChar(eb, ' '); + CError_BufferAppendFuncArgs(eb, TYPE_FUNC(ty), 0); + break; + case TYPEARRAY: + CError_BufferAppendQualifier(eb, qual); + scan = ty; + while (scan->type == TYPEARRAY) + scan = TYPE_POINTER(scan)->target; + CError_BufferAppendType(eb, scan, 0); + append_array_lengths: + while (ty->type == TYPEARRAY) { + CError_BufferAppendChar(eb, '['); + if (ty->size && TYPE_POINTER(ty)->target->size) { + sprintf(buf, "%ld", ty->size / TYPE_POINTER(ty)->target->size); + CError_BufferAppendString(eb, buf); + } + CError_BufferAppendChar(eb, ']'); + ty = TYPE_POINTER(ty)->target; + } + break; + case TYPETEMPLATE: + CError_BufferAppendQualifier(eb, qual); + CError_BufferAppendTemplDepType(eb, TYPE_TEMPLATE(ty)); + break; + case TYPETEMPLDEPEXPR: + CError_BufferAppendString(eb, "T"); + break; + case TYPEBITFIELD: + sprintf(buf, "bitfield:%ld", TYPE_BITFIELD(ty)->unkB); + CError_BufferAppendString(eb, buf); + break; + default: +#line 752 + CError_FATAL(); + } +} + +char *CError_GetTypeName(Type *ty, UInt32 qual, Boolean useGlobalHeap) { + CErrorBuffer eb; + char buf[256]; + char *ptr; + + CError_BufferInit(&eb, buf, sizeof(buf)); + CError_BufferAppendType(&eb, ty, qual); + CError_BufferTerminate(&eb); + + if (useGlobalHeap) + ptr = galloc(eb.size + 1); + else + ptr = lalloc(eb.size + 1); + + return strcpy(ptr, eb.start); +} + +void CError_AppendUnqualFunctionName(CErrorBuffer *eb, NameSpace *nspace, HashNameNode *name, TypeFunc *tfunc) { + Boolean flag = 0; + char *opname; + + if (nspace && nspace->theclass) { + if (name == constructor_name_node) { + CError_BufferAppendString(eb, nspace->theclass->classname->name); + flag = 1; + } else if (name == destructor_name_node) { + CError_BufferAppendChar(eb, '~'); + CError_BufferAppendString(eb, nspace->theclass->classname->name); + flag = 1; + } + } + + if (!flag) { + opname = CMangler_GetOperator(name); + if (!opname) { + if (tfunc && (tfunc->flags & FUNC_FLAGS_40)) { + CError_BufferAppendString(eb, "operator "); + CError_BufferAppendType(eb, tfunc->functype, tfunc->qual); + } else { + CError_BufferAppendString(eb, name->name); + } + } else { + CError_BufferAppendString(eb, opname); + } + } +} + +void CError_AppendFunctionName(CErrorBuffer *eb, NameSpace *nspace, HashNameNode *name, TemplArg *templargs, TypeFunc *tfunc) { + while (nspace->is_templ && nspace->parent) + nspace = nspace->parent; + + CError_BufferAppendNameSpace(eb, nspace); + CError_AppendUnqualFunctionName(eb, nspace, name, tfunc); + CError_BufferAppendTemplArgs(eb, templargs); + if (tfunc) { + if (!templargs && (tfunc->flags & FUNC_FLAGS_100000)) + CError_BufferAppendString(eb, "<...>"); + CError_BufferAppendFuncArgs(eb, tfunc, 0); + } else { + CError_BufferAppendString(eb, "()"); + } +} + +void CError_AppendObjectName(CErrorBuffer *eb, Object *obj) { + if (obj->type->type == TYPEFUNC) { + CError_AppendFunctionName(eb, obj->nspace, obj->name, obj->u.func.inst ? obj->u.func.inst->args : NULL, TYPE_FUNC(obj->type)); + } else { + CError_BufferAppendNameSpace(eb, obj->nspace); + CError_BufferAppendString(eb, obj->name->name); + } +} + +void CError_AppendMethodName(CErrorBuffer *eb, ObjCMethod *meth) { + ObjCMethodArg *arg; + + CError_BufferAppendChar(eb, meth->is_class_method ? '+' : '-'); + CError_BufferAppendChar(eb, '('); + CError_BufferAppendType(eb, meth->return_type, meth->return_qual); + CError_BufferAppendChar(eb, ')'); + for (arg = meth->selector_args; arg; arg = arg->next) { + if (arg->selector) + CError_BufferAppendString(eb, arg->selector->name); + if (arg->type) { + CError_BufferAppendString(eb, ":("); + CError_BufferAppendType(eb, arg->type, arg->qual); + CError_BufferAppendChar(eb, ')'); + } + } + if (meth->has_valist) + CError_BufferAppendString(eb, ",..."); +} + +char *CError_GetQualifiedName(NameSpace *nspace, HashNameNode *name) { + CErrorBuffer eb; + char buf[256]; + char *ptr; + + CError_BufferInit(&eb, buf, sizeof(buf)); + CError_BufferAppendNameSpace(&eb, nspace); + CError_BufferAppendString(&eb, name->name); + CError_BufferTerminate(&eb); + + ptr = lalloc(eb.size + 1); + return strcpy(ptr, eb.start); +} + +char *CError_GetFunctionName(NameSpace *nspace, HashNameNode *name, TypeFunc *tfunc) { + CErrorBuffer eb; + char buf[256]; + char *ptr; + + CError_BufferInit(&eb, buf, sizeof(buf)); + CError_AppendFunctionName(&eb, nspace, name, 0, tfunc); + CError_BufferTerminate(&eb); + + ptr = lalloc(eb.size + 1); + return strcpy(ptr, eb.start); +} + +char *CError_GetObjectName(Object *obj) { + CErrorBuffer eb; + char buf[256]; + char *ptr; + + CError_BufferInit(&eb, buf, sizeof(buf)); + CError_AppendObjectName(&eb, obj); + CError_BufferTerminate(&eb); + + ptr = lalloc(eb.size + 1); + return strcpy(ptr, eb.start); +} + +char *CError_GetNameString(NameSpace *nspace, HashNameNode *operatorName) { + CErrorBuffer eb; + char buf[256]; + char *ptr; + char *opStr; + +#line 973 + CError_ASSERT(operatorName); + + opStr = CMangler_GetOperator(operatorName); + if (!opStr) + opStr = operatorName->name; + + if (nspace && nspace->name) { + CError_BufferInit(&eb, buf, sizeof(buf)); + CError_BufferAppendNameSpace(&eb, nspace); + CError_BufferAppendString(&eb, opStr); + CError_BufferTerminate(&eb); + ptr = lalloc(eb.size + 1); + return strcpy(ptr, eb.start); + } else { + return opStr; + } +} + +void CError_ErrorMessage(int errTable, char *str, Boolean flag1, Boolean flag2) { + TStreamElement *token; + short tokensize; + CPrepFileInfo *tokenfile; + char buf[128]; + CWMessageRef myref; + CWMessageRef *ref; + unsigned char messagetype; + + if (CWDisplayLines(cparamblkptr->context, lines) != cwNoErr) + CError_UserBreak(); + + if (!in_assembler && !flag1 && cerror_lasterrorline == lines) { + if (cerror_errorcount++ >= 50) { + if (cerror_errorcount > 60) + longjmp(errorreturn, 1); + tk = lex(); + cerror_errorcount = 0; + if (tk == 0) { + CompilerGetCString(1, buf); + CWReportMessage(cparamblkptr->context, NULL, buf, NULL, messagetypeError, errTable); + longjmp(errorreturn, 1); + } + } + } else { + if (!flag2) { + cerror_lasterrorline = lines; + cerror_errorcount = 0; + } + if (copts.warningerrors) + flag2 = 0; + + if (cerror_token) + token = cerror_token; + else if (cerror_locktoken) + token = cerror_locktoken; + else + token = NULL; + //token = cerror_token ? cerror_token : cerror_locktoken ? cerror_locktoken : NULL; + if ((SInt32) token == -1) { + ref = NULL; + } else { + CPrep_GetTokenContext(token, &tokenfile, &myref.selectionoffset, &tokensize, &myref.linenumber, buf, &myref.tokenoffset, &myref.tokenlength, cerror_synchdata, &cerror_synchoffset); + myref.selectionlength = tokensize; + myref.sourcefile = tokenfile->textfile; + ref = &myref; + } + messagetype = flag2 ? messagetypeWarning : messagetypeError; + if (!flag2) { + anyerrors = 1; + fatalerrors = 1; + } + if (CWReportMessage(cparamblkptr->context, ref, str, buf, messagetype, errTable) != cwNoErr) + longjmp(errorreturn, 1); + } + + cerror_token = NULL; +} + +void CError_BufferAppendTemplateStack(CErrorBuffer *eb) { + TemplStack *stack[64]; + TemplStack *scan; + int index; + int indent; + int count; + + scan = ctempl_curinstance; + for (count = 0; scan && count < 64; count++) { + stack[count] = scan; + scan = scan->next; + } + + for (index = count - 1; index >= 0; index--) { + CError_BufferAppendChar(eb, '\n'); + for (indent = index; indent < count; indent++) + CError_BufferAppendChar(eb, ' '); + CError_BufferAppendString(eb, "(instantiating: '"); + if (stack[index]->is_func) + CError_AppendObjectName(eb, stack[index]->u.func); + else + CError_BufferAppendType(eb, (Type *) stack[index]->u.theclass, 0); + CError_BufferAppendString(eb, "')"); + } + + CError_BufferTerminate(eb); +} + +void CError_ErrorMessageVA(int code, const char *format, va_list list, Boolean flag1, Boolean flag2) { + // register allocation is fucked, matches otherwise + CErrorBuffer eb; + char buf[256]; + char unmangleBuf[256]; + SInt32 moddate; + Type *type; + UInt32 qual; + CError_BufferInit(&eb, buf, sizeof(buf)); + + do { + switch (format[0]) { + case 0: + break; + case '%': + switch (format[1]) { + case 'n': + MWUnmangle(va_arg(list, const char *), unmangleBuf, sizeof(unmangleBuf)); + CError_BufferAppendString(&eb, unmangleBuf); + format += 2; + continue; + case 'u': + CError_BufferAppendString(&eb, va_arg(list, const char *)); + format += 2; + continue; + case 'o': + CError_AppendObjectName(&eb, va_arg(list, Object *)); + format += 2; + continue; + case 'm': + CError_AppendMethodName(&eb, va_arg(list, ObjCMethod *)); + format += 2; + continue; + case 't': + type = va_arg(list, Type *); + qual = va_arg(list, UInt32); + CError_BufferAppendType(&eb, type, qual); + format += 2; + continue; + case '%': + CError_BufferAppendChar(&eb, '%'); + format += 2; + continue; + case 'i': + sprintf(unmangleBuf, "%ld", va_arg(list, SInt32)); + CError_BufferAppendString(&eb, unmangleBuf); + format += 2; + continue; + case 'f': + CError_BufferAppendString(&eb, CTool_GetPathName(va_arg(list, FSSpec *), &moddate)->name); + format += 2; + continue; + default: +#line 1174 + CError_FATAL(); + } + break; + default: + CError_BufferAppendChar(&eb, *(format++)); + continue; + } + break; + } while (1); + + CError_BufferAppendTemplateStack(&eb); + CError_ErrorMessage(code, eb.start, flag1, flag2); +} + +void CError_VAErrorMessage(int code, va_list list, Boolean flag1, Boolean flag2) { + char buf[256]; + + CError_GetErrorString(buf, code); + CError_ErrorMessageVA(code + 10000, buf, list, flag1, flag2); +} + +void CError_Error(int code, ...) { + va_list va; + + if (trychain) + longjmp(trychain->jmpbuf, 1); + + va_start(va, code); + CError_VAErrorMessage(code, va, 0, 0); + va_end(va); + + if (in_assembler && !preprocessing_only) + AssemblerError(); +} + +void CError_ErrorTerm(short code) { + CError_GetErrorString(string, code); + CError_ErrorMessage(code + 10000, string, 0, 0); + longjmp(errorreturn, 1); +} + +void CError_ErrorSkip(int code, ...) { + va_list va; + + if (trychain) + longjmp(trychain->jmpbuf, 1); + + va_start(va, code); + CError_VAErrorMessage(code, va, 0, 0); + va_end(va); + + if (tk != ';' && tk != ')' && tk != '}' && tk != ',' && tk != ']') + tk = lex(); +} + +void CError_ErrorFuncCall(short code, NameSpaceObjectList *args, ENodeList *argNodes) { + // does not match - one branch has loop weirdness + CErrorBuffer eb; + char buf[256]; + char *p; + ENodeList *argscan; + + if (trychain) + longjmp(trychain->jmpbuf, 1); + + CError_GetErrorString(string, code); + CError_BufferInit(&eb, buf, sizeof(buf)); + + while (args && args->object->otype != OT_OBJECT) + args = args->next; +#line 1268 + CError_ASSERT(args); + + p = string; + do { + switch (*p) { + case 0: + goto exit_main_loop; + case '*': + if (OBJECT(args->object)->type->type == TYPEFUNC) { + CError_AppendUnqualFunctionName( + &eb, + OBJECT(args->object)->nspace, + OBJECT(args->object)->name, + TYPE_FUNC(OBJECT(args->object)->type)); + if (TYPE_FUNC(OBJECT(args->object)->type)->flags & FUNC_FLAGS_METHOD) + if (TYPE_FUNC(OBJECT(args->object)->type)->flags & FUNC_FLAGS_1000) + if (TYPE_METHOD(OBJECT(args->object)->type)->theclass->flags & CLASS_FLAGS_20) + if (argNodes) + argNodes = argNodes->next; + } else { + CError_BufferAppendString(&eb, OBJECT(args->object)->name->name); + } + CError_BufferAppendChar(&eb, '('); + argscan = argNodes; + while (argscan) { + CError_BufferAppendType(&eb, argscan->node->rtype, argscan->node->flags & ENODE_FLAG_QUALS); + if ((argscan = argscan->next)) + CError_BufferAppendString(&eb, ", "); + } + CError_BufferAppendChar(&eb, ')'); + break; + default: + CError_BufferAppendChar(&eb, *p); + } + p++; + } while (1); + +exit_main_loop: + while (args) { + if (args->object->otype == OT_OBJECT) { + CError_BufferAppendChar(&eb, '\n'); + CError_BufferAppendChar(&eb, '\''); + CError_AppendObjectName(&eb, (Object *) args->object); + CError_BufferAppendChar(&eb, '\''); + } + args = args->next; + } + + CError_BufferAppendTemplateStack(&eb); + CError_ErrorMessage(10000 + code, eb.start, 0, 0); +} + +void CError_OverloadedFunctionError2(Object *obj, ObjectList *olst, ENodeList *argNodes) { + // not sure if the arg is actually ObjectList since it's never called lmao + NameSpaceObjectList first; + NameSpaceObjectList *current; + + first.object = (ObjBase *) obj; + current = &first; + while (olst) { + current->next = lalloc(sizeof(NameSpaceObjectList)); + current = current->next; + current->object = (ObjBase *) olst->object; + olst = olst->next; + } + current->next = NULL; + + CError_ErrorFuncCall(392, &first, argNodes); +} + +void CError_OverloadedFunctionError(Object *obj, ObjectList *olst) { + // not sure if this arg is ObjectList or NameSpaceObjectList + CErrorBuffer eb; + char buf[256]; + + if (trychain) + longjmp(trychain->jmpbuf, 1); + + CError_GetErrorString(string, 199); + CError_BufferInit(&eb, buf, sizeof(buf)); + CError_BufferAppendString(&eb, string); + + if (obj) { + CError_BufferAppendChar(&eb, '\n'); + CError_BufferAppendChar(&eb, '\''); + CError_AppendObjectName(&eb, obj); + CError_BufferAppendChar(&eb, '\''); + } + while (olst) { + CError_BufferAppendChar(&eb, '\n'); + CError_BufferAppendChar(&eb, '\''); + CError_AppendObjectName(&eb, olst->object); + CError_BufferAppendChar(&eb, '\''); + olst = olst->next; + } + CError_BufferAppendTemplateStack(&eb); + CError_ErrorMessage(10199, eb.start, 0, 0); +} + +void CError_AbstractClassError(TypeClass *tclass) { + int result = CClass_CheckPures(tclass); + if (!result) + CError_Error(372, tclass, 0); + else + CError_Error(194, result); +} + +void CError_Warning(int code, ...) { + va_list va; + if (trychain) + return; + + if (copts.supress_warnings) { + va_start(va, code); + } else { + va_start(va, code); + CError_VAErrorMessage(code, va, 0, 1); + } + va_end(va); +} + +void CError_BreakPoint(const char *a, const char *b) { + if (!a || !strcmp(a, b)) + CError_BreakPointcount++; +} + +void CError_Internal(char *filename, int line) { + char tmp[128]; + CompilerGetCString(5, tmp); + sprintf(string, tmp, filename, line); + CError_ErrorMessage(10001, string, 1, 0); + longjmp(errorreturn, 1); + CError_BreakPoint(0, 0); +} + +void CError_ExpressionTooComplex() { + CompilerGetCString(6, string); + CError_ErrorMessage(10002, string, 1, 0); + longjmp(errorreturn, 1); +} + +void CError_NoMem() { + cprep_nomem_exit = 1; + longjmp(errorreturn, 1); +} + +void CError_UserBreak() { + CompilerGetCString(8, string); + longjmp(errorreturn, 1); +} + +void CError_CannotOpen() { + CompilerGetCString(9, string); + CWReportMessage(cparamblkptr->context, NULL, string, NULL, messagetypeError, 0); + longjmp(errorreturn, 1); +} + +void CError_QualifierCheck(UInt32 qual) { + if (qual) { + Boolean anything = 0; + + if (qual & Q_CONST) { + CError_Error(CErrorStr313, "const"); + anything = 1; + } + if (qual & Q_VOLATILE) { + CError_Error(CErrorStr313, "volatile"); + anything = 1; + } + if (qual & Q_RESTRICT) { + CError_Error(CErrorStr313, "restrict"); + anything = 1; + } + if (qual & Q_ASM) { + CError_Error(CErrorStr313, "asm"); + anything = 1; + } + if (qual & Q_PASCAL) { + CError_Error(CErrorStr313, "pascal"); + anything = 1; + } + if (qual & Q_INLINE) { + CError_Error(CErrorStr313, "inline"); + anything = 1; + } + if (qual & Q_REFERENCE) { + CError_Error(CErrorStr313, "& reference type"); + anything = 1; + } + if (qual & Q_EXPLICIT) { + CError_Error(CErrorStr313, "explicit"); + anything = 1; + } + if (qual & Q_MUTABLE) { + CError_Error(CErrorStr313, "mutable"); + anything = 1; + } + if (qual & Q_VIRTUAL) { + CError_Error(CErrorStr313, "virtual"); + anything = 1; + } + if (qual & Q_FRIEND) { + CError_Error(CErrorStr313, "friend"); + anything = 1; + } + if (qual & Q_IN) { + CError_Error(CErrorStr313, "in"); + anything = 1; + } + if (qual & Q_OUT) { + CError_Error(CErrorStr313, "out"); + anything = 1; + } + if (qual & Q_INOUT) { + CError_Error(CErrorStr313, "inout"); + anything = 1; + } + if (qual & Q_BYCOPY) { + CError_Error(CErrorStr313, "bycopy"); + anything = 1; + } + if (qual & Q_BYREF) { + CError_Error(CErrorStr313, "byref"); + anything = 1; + } + if (qual & Q_ONEWAY) { + CError_Error(CErrorStr313, "oneway"); + anything = 1; + } + if (qual & Q_ALIGNED_MASK) { + CError_Error(CErrorStr313, "__attribute__((aligned(?)))"); + anything = 1; + } + + if (!anything) + CError_Error(CErrorStr176); + } +} diff --git a/CInt64.c b/compiler_and_linker/unsorted/CInt64.c similarity index 69% rename from CInt64.c rename to compiler_and_linker/unsorted/CInt64.c index 9b793bd..ce2c45c 100644 --- a/CInt64.c +++ b/compiler_and_linker/unsorted/CInt64.c @@ -1,5 +1,4 @@ -#include -#include "CInt64.h" +#include "compiler/CInt64.h" const CInt64 cint64_negone = {0xFFFFFFFF, 0xFFFFFFFF}; const CInt64 cint64_zero = {0, 0}; @@ -14,9 +13,9 @@ void CInt64_Init() { CInt64 CInt64_Not(CInt64 input) { CInt64 output; - unsigned char c; + Boolean c; - c = (input.a == 0 && input.b == 0); + c = (input.hi == 0 && input.lo == 0); CInt64_SetLong(&output, c); return output; @@ -24,31 +23,31 @@ CInt64 CInt64_Not(CInt64 input) { CInt64 CInt64_Inv(CInt64 input) { CInt64 output; - output.a = ~input.a; - output.b = ~input.b; + output.hi = ~input.hi; + output.lo = ~input.lo; return output; } CInt64 CInt64_Add(CInt64 lhs, CInt64 rhs) { - if (lhs.b & 0x80000000) { - if (rhs.b & 0x80000000) { - lhs.b += rhs.b; - lhs.a += 1; + if (lhs.lo & 0x80000000) { + if (rhs.lo & 0x80000000) { + lhs.lo += rhs.lo; + lhs.hi += 1; } else { - lhs.b += rhs.b; - if (!(lhs.b & 0x80000000)) - lhs.a += 1; + lhs.lo += rhs.lo; + if (!(lhs.lo & 0x80000000)) + lhs.hi += 1; } } else { - if (rhs.b & 0x80000000) { - lhs.b += rhs.b; - if (!(lhs.b & 0x80000000)) - lhs.a += 1; + if (rhs.lo & 0x80000000) { + lhs.lo += rhs.lo; + if (!(lhs.lo & 0x80000000)) + lhs.hi += 1; } else { - lhs.b += rhs.b; + lhs.lo += rhs.lo; } } - lhs.a += rhs.a; + lhs.hi += rhs.hi; return lhs; } @@ -66,22 +65,22 @@ CInt64 CInt64_Sub(CInt64 lhs, CInt64 rhs) { CInt64 CInt64_MulU(CInt64 lhs, CInt64 rhs) { CInt64 result; CInt64 work1; - unsigned long aaaa; - unsigned long bbbb; - unsigned long cccc; - unsigned long dddd; - unsigned long eeee; + UInt32 aaaa; + UInt32 bbbb; + UInt32 cccc; + UInt32 dddd; + UInt32 eeee; - aaaa = rhs.b; - result.a = result.b = 0; - bbbb = lhs.b; - cccc = rhs.a; - dddd = rhs.b; + aaaa = rhs.lo; + result.hi = result.lo = 0; + bbbb = lhs.lo; + cccc = rhs.hi; + dddd = rhs.lo; while (bbbb != 0) { if (bbbb & 1) { - work1.a = cccc; - work1.b = dddd; + work1.hi = cccc; + work1.lo = dddd; result = CInt64_Add(result, work1); } cccc <<= 1; @@ -91,10 +90,10 @@ CInt64 CInt64_MulU(CInt64 lhs, CInt64 rhs) { bbbb >>= 1; } - eeee = lhs.a; + eeee = lhs.hi; while (eeee != 0 && aaaa != 0) { if (eeee & 1) - result.a += aaaa; + result.hi += aaaa; aaaa <<= 1; eeee >>= 1; } @@ -116,26 +115,26 @@ CInt64 CInt64_Mul(CInt64 lhs, CInt64 rhs) { } void CInt64_DivMod(const CInt64 *lhs, const CInt64 *rhs, CInt64 *pDiv, CInt64 *pMod) { - unsigned char bad; - unsigned long workA; - unsigned long workB; - unsigned long leftA; - unsigned long leftB; - unsigned long rightA; - unsigned long rightB; - unsigned long outA; - unsigned long outB; + Boolean bad; + UInt32 workA; + UInt32 workB; + UInt32 leftA; + UInt32 leftB; + UInt32 rightA; + UInt32 rightB; + UInt32 outA; + UInt32 outB; CInt64 work; int counter; - bad = (rhs->a == 0) && (rhs->b == 0); + bad = (rhs->hi == 0) && (rhs->lo == 0); if (!bad) { workA = 0; workB = 0; - leftA = lhs->a; - leftB = lhs->b; - rightA = rhs->a; - rightB = rhs->b; + leftA = lhs->hi; + leftB = lhs->lo; + rightA = rhs->hi; + rightB = rhs->lo; outA = 0; outB = 0; counter = 0; @@ -166,20 +165,20 @@ void CInt64_DivMod(const CInt64 *lhs, const CInt64 *rhs, CInt64 *pDiv, CInt64 *p outB |= 1; - work.a = workA; - work.b = workB; + work.hi = workA; + work.lo = workB; work = CInt64_Sub(work, *rhs); - workA = work.a; - workB = work.b; + workA = work.hi; + workB = work.lo; } while (++counter < 64); if (pDiv) { - pDiv->a = outA; - pDiv->b = outB; + pDiv->hi = outA; + pDiv->lo = outB; } if (pMod) { - pMod->a = workA; - pMod->b = workB; + pMod->hi = workA; + pMod->lo = workB; } } } @@ -238,50 +237,50 @@ CInt64 CInt64_ModU(CInt64 lhs, CInt64 rhs) { CInt64 CInt64_Shl(CInt64 lhs, CInt64 rhs) { int counter; - unsigned long a; - unsigned long b; + UInt32 a; + UInt32 b; - if (rhs.a == 0 && rhs.b < 64) { - a = lhs.a; - b = lhs.b; - for (counter = rhs.b; counter != 0; --counter) { + if (rhs.hi == 0 && rhs.lo < 64) { + a = lhs.hi; + b = lhs.lo; + for (counter = rhs.lo; counter != 0; --counter) { a <<= 1; if (b & 0x80000000) a |= 1; b <<= 1; } - lhs.a = a; - lhs.b = b; + lhs.hi = a; + lhs.lo = b; } else { - lhs.a = 0; - lhs.b = 0; + lhs.hi = 0; + lhs.lo = 0; } return lhs; } CInt64 CInt64_Shr(CInt64 lhs, CInt64 rhs) { int counter; - long a; - unsigned long b; + SInt32 a; + UInt32 b; - if (rhs.a == 0 && rhs.b < 64) { - a = lhs.a; - b = lhs.b; - for (counter = rhs.b; counter != 0; --counter) { + if (rhs.hi == 0 && rhs.lo < 64) { + a = lhs.hi; + b = lhs.lo; + for (counter = rhs.lo; counter != 0; --counter) { b >>= 1; if (a & 1) b |= 0x80000000; a >>= 1; } - lhs.a = a; - lhs.b = b; + lhs.hi = a; + lhs.lo = b; } else { - if (lhs.a & 0x80000000) { - lhs.a = 0xFFFFFFFF; - lhs.b = 0xFFFFFFFF; + if (lhs.hi & 0x80000000) { + lhs.hi = 0xFFFFFFFF; + lhs.lo = 0xFFFFFFFF; } else { - lhs.a = 0; - lhs.b = 0; + lhs.hi = 0; + lhs.lo = 0; } } return lhs; @@ -289,35 +288,35 @@ CInt64 CInt64_Shr(CInt64 lhs, CInt64 rhs) { CInt64 CInt64_ShrU(CInt64 lhs, CInt64 rhs) { int counter; - unsigned long a; - unsigned long b; + UInt32 a; + UInt32 b; - if (rhs.a == 0 && rhs.b < 64) { - a = lhs.a; - b = lhs.b; - for (counter = rhs.b; counter != 0; --counter) { + if (rhs.hi == 0 && rhs.lo < 64) { + a = lhs.hi; + b = lhs.lo; + for (counter = rhs.lo; counter != 0; --counter) { b >>= 1; if (a & 1) b |= 0x80000000; a >>= 1; } - lhs.a = a; - lhs.b = b; + lhs.hi = a; + lhs.lo = b; } else { - lhs.a = 0; - lhs.b = 0; + lhs.hi = 0; + lhs.lo = 0; } return lhs; } int CInt64_UnsignedCompare(const CInt64 *lhs, const CInt64 *rhs) { - if (lhs->a == rhs->a) { - if (lhs->b < rhs->b) + if (lhs->hi == rhs->hi) { + if (lhs->lo < rhs->lo) return -1; else - return lhs->b > rhs->b; + return lhs->lo > rhs->lo; } else { - return ((unsigned long) lhs->a < rhs->a) ? -1 : 1; + return ((UInt32) lhs->hi < rhs->hi) ? -1 : 1; } } @@ -330,62 +329,62 @@ int CInt64_SignedCompare(const CInt64 *lhs, const CInt64 *rhs) { return CInt64_UnsignedCompare(&lhs_, &rhs_); } -unsigned char CInt64_Less(CInt64 lhs, CInt64 rhs) { +Boolean CInt64_Less(CInt64 lhs, CInt64 rhs) { return CInt64_SignedCompare(&lhs, &rhs) < 0; } -unsigned char CInt64_LessU(CInt64 lhs, CInt64 rhs) { +Boolean CInt64_LessU(CInt64 lhs, CInt64 rhs) { return CInt64_UnsignedCompare(&lhs, &rhs) < 0; } -unsigned char CInt64_Greater(CInt64 lhs, CInt64 rhs) { +Boolean CInt64_Greater(CInt64 lhs, CInt64 rhs) { return CInt64_SignedCompare(&lhs, &rhs) > 0; } -unsigned char CInt64_GreaterU(CInt64 lhs, CInt64 rhs) { +Boolean CInt64_GreaterU(CInt64 lhs, CInt64 rhs) { return CInt64_UnsignedCompare(&lhs, &rhs) > 0; } -unsigned char CInt64_LessEqual(CInt64 lhs, CInt64 rhs) { +Boolean CInt64_LessEqual(CInt64 lhs, CInt64 rhs) { return CInt64_SignedCompare(&lhs, &rhs) <= 0; } -unsigned char CInt64_LessEqualU(CInt64 lhs, CInt64 rhs) { +Boolean CInt64_LessEqualU(CInt64 lhs, CInt64 rhs) { return CInt64_UnsignedCompare(&lhs, &rhs) <= 0; } -unsigned char CInt64_GreaterEqual(CInt64 lhs, CInt64 rhs) { +Boolean CInt64_GreaterEqual(CInt64 lhs, CInt64 rhs) { return CInt64_SignedCompare(&lhs, &rhs) >= 0; } -unsigned char CInt64_GreaterEqualU(CInt64 lhs, CInt64 rhs) { +Boolean CInt64_GreaterEqualU(CInt64 lhs, CInt64 rhs) { return CInt64_UnsignedCompare(&lhs, &rhs) >= 0; } -unsigned char CInt64_Equal(CInt64 lhs, CInt64 rhs) { - return lhs.a == rhs.a && lhs.b == rhs.b; +Boolean CInt64_Equal(CInt64 lhs, CInt64 rhs) { + return lhs.hi == rhs.hi && lhs.lo == rhs.lo; } -unsigned char CInt64_NotEqual(CInt64 lhs, CInt64 rhs) { - return lhs.a != rhs.a || lhs.b != rhs.b; +Boolean CInt64_NotEqual(CInt64 lhs, CInt64 rhs) { + return lhs.hi != rhs.hi || lhs.lo != rhs.lo; } -unsigned char CInt64_IsInRange(CInt64 value, short len) { +Boolean CInt64_IsInRange(CInt64 value, short len) { CInt64 bound; - if (value.a & 0x80000000) { + if (value.hi & 0x80000000) { switch (len) { case 1: - bound.b = 0xFFFFFF80; - bound.a = 0xFFFFFFFF; + bound.lo = 0xFFFFFF80; + bound.hi = 0xFFFFFFFF; break; case 2: - bound.b = 0xFFFF8000; - bound.a = 0xFFFFFFFF; + bound.lo = 0xFFFF8000; + bound.hi = 0xFFFFFFFF; break; case 4: - bound.b = 0x80000000; - bound.a = 0xFFFFFFFF; + bound.lo = 0x80000000; + bound.hi = 0xFFFFFFFF; break; case 8: return 1; @@ -396,16 +395,16 @@ unsigned char CInt64_IsInRange(CInt64 value, short len) { } else { switch (len) { case 1: - bound.b = 0x7F; - bound.a = 0; + bound.lo = 0x7F; + bound.hi = 0; break; case 2: - bound.b = 0x7FFF; - bound.a = 0; + bound.lo = 0x7FFF; + bound.hi = 0; break; case 4: - bound.b = 0x7FFFFFFF; - bound.a = 0; + bound.lo = 0x7FFFFFFF; + bound.hi = 0; break; case 8: return 1; @@ -416,14 +415,14 @@ unsigned char CInt64_IsInRange(CInt64 value, short len) { } } -unsigned char CInt64_IsInURange(CInt64 value, short len) { +Boolean CInt64_IsInURange(CInt64 value, short len) { switch (len) { case 1: - return value.a == 0 && (value.b & 0xFFFFFF00) == 0; + return value.hi == 0 && (value.lo & 0xFFFFFF00) == 0; case 2: - return value.a == 0 && (value.b & 0xFFFF0000) == 0; + return value.hi == 0 && (value.lo & 0xFFFF0000) == 0; case 4: - return value.a == 0; + return value.hi == 0; case 8: return 1; default: @@ -432,20 +431,20 @@ unsigned char CInt64_IsInURange(CInt64 value, short len) { } CInt64 CInt64_And(CInt64 lhs, CInt64 rhs) { - lhs.a &= rhs.a; - lhs.b &= rhs.b; + lhs.hi &= rhs.hi; + lhs.lo &= rhs.lo; return lhs; } CInt64 CInt64_Xor(CInt64 lhs, CInt64 rhs) { - lhs.a ^= rhs.a; - lhs.b ^= rhs.b; + lhs.hi ^= rhs.hi; + lhs.lo ^= rhs.lo; return lhs; } CInt64 CInt64_Or(CInt64 lhs, CInt64 rhs) { - lhs.a |= rhs.a; - lhs.b |= rhs.b; + lhs.hi |= rhs.hi; + lhs.lo |= rhs.lo; return lhs; } @@ -454,43 +453,43 @@ void CInt64_ConvertInt32(CInt64 *i) { } void CInt64_ConvertUInt32(CInt64 *i) { - CInt64_SetULong(i, (unsigned long) i->b); + CInt64_SetULong(i, (UInt32) i->lo); } void CInt64_ConvertInt16(CInt64 *i) { - i->b = (short) i->b; + i->lo = (SInt32) i->lo; CInt64_Extend32(i); } void CInt64_ConvertUInt16(CInt64 *i) { - CInt64_SetULong(i, (unsigned short) i->b); + CInt64_SetULong(i, (UInt16) i->lo); } void CInt64_ConvertInt8(CInt64 *i) { - i->b = (char) i->b; + i->lo = (SInt8) i->lo; CInt64_Extend32(i); } void CInt64_ConvertUInt8(CInt64 *i) { - CInt64_SetULong(i, (unsigned char) i->b); + CInt64_SetULong(i, (UInt8) i->lo); } void CInt64_ConvertUFromLongDouble(CInt64 *pResult, double value) { - union { float f; unsigned long l; } cvt; - unsigned long a, b; + union { float f; UInt32 l; } cvt; + UInt32 a, b; float threshold; int bits; if (value <= 0.0) { - pResult->a = 0; - pResult->b = 0; + pResult->hi = 0; + pResult->lo = 0; return; } cvt.l = 0x5F800000; if (value >= cvt.f) { - pResult->a = 0xFFFFFFFF; - pResult->b = 0xFFFFFFFF; + pResult->hi = 0xFFFFFFFF; + pResult->lo = 0xFFFFFFFF; return; } @@ -514,8 +513,8 @@ void CInt64_ConvertUFromLongDouble(CInt64 *pResult, double value) { } } - pResult->a = a; - pResult->b = b; + pResult->hi = a; + pResult->lo = b; } void CInt64_ConvertFromLongDouble(CInt64 *pResult, double value) { @@ -528,18 +527,18 @@ void CInt64_ConvertFromLongDouble(CInt64 *pResult, double value) { } double CInt64_ConvertUToLongDouble(const CInt64 *value) { - unsigned char bad; - unsigned long work; + Boolean bad; + UInt32 work; int counter; double result; - bad = (value->a == 0) && (value->b == 0); + bad = (value->hi == 0) && (value->lo == 0); if (bad) { return 0.0; } else { result = 0.0; - work = value->a; + work = value->hi; if (work != 0) { for (counter = 0; counter < 32; counter++) { result += result; @@ -550,7 +549,7 @@ double CInt64_ConvertUToLongDouble(const CInt64 *value) { } counter = 0; - work = value->b; + work = value->lo; for (; counter < 32; counter++) { result += result; if (work & 0x80000000) @@ -564,7 +563,7 @@ double CInt64_ConvertUToLongDouble(const CInt64 *value) { double CInt64_ConvertToLongDouble(const CInt64 *value) { CInt64 tmp; - if (value->a & 0x80000000) { + if (value->hi & 0x80000000) { tmp = CInt64_Neg(*value); return -CInt64_ConvertUToLongDouble(&tmp); } else { @@ -572,18 +571,18 @@ double CInt64_ConvertToLongDouble(const CInt64 *value) { } } -char *CInt64_ScanOctString(CInt64 *pResult, char *str, unsigned char *pFail) { +char *CInt64_ScanOctString(CInt64 *pResult, char *str, Boolean *pFail) { int ch; CInt64 tmp; - unsigned long a; - unsigned long b; + UInt32 a; + UInt32 b; *pFail = 0; - pResult->a = pResult->b = 0; + pResult->hi = pResult->lo = 0; while ((ch = *str) >= '0' && *str <= '7') { - a = pResult->a; - b = pResult->b; + a = pResult->hi; + b = pResult->lo; if (a & 0xE0000000) *pFail = 1; @@ -591,8 +590,8 @@ char *CInt64_ScanOctString(CInt64 *pResult, char *str, unsigned char *pFail) { SHIFT_LEFT_ONE(a, b); SHIFT_LEFT_ONE(a, b); - pResult->a = a; - pResult->b = b; + pResult->hi = a; + pResult->lo = b; CInt64_SetLong(&tmp, ch - '0'); *pResult = CInt64_Add(*pResult, tmp); @@ -602,28 +601,28 @@ char *CInt64_ScanOctString(CInt64 *pResult, char *str, unsigned char *pFail) { return str; } -char *CInt64_ScanDecString(CInt64 *pResult, char *str, unsigned char *pFail) { +char *CInt64_ScanDecString(CInt64 *pResult, char *str, Boolean *pFail) { int ch; CInt64 tmp; - unsigned long a; - unsigned long b; + UInt32 a; + UInt32 b; *pFail = 0; - pResult->a = pResult->b = 0; + pResult->hi = pResult->lo = 0; while ((ch = *str) >= '0' && *str <= '9') { - a = pResult->a; - b = pResult->b; + a = pResult->hi; + b = pResult->lo; if (a & 0xE0000000) *pFail = 1; SHIFT_LEFT_ONE(a, b); - tmp.a = a; - tmp.b = b; + tmp.hi = a; + tmp.lo = b; SHIFT_LEFT_ONE(a, b); SHIFT_LEFT_ONE(a, b); - pResult->a = a; - pResult->b = b; + pResult->hi = a; + pResult->lo = b; if (CInt64_IsNegative(pResult)) { *pResult = CInt64_Add(*pResult, tmp); @@ -648,15 +647,15 @@ char *CInt64_ScanDecString(CInt64 *pResult, char *str, unsigned char *pFail) { return str; } -char *CInt64_ScanHexString(CInt64 *pResult, char *str, unsigned char *pFail) { +char *CInt64_ScanHexString(CInt64 *pResult, char *str, Boolean *pFail) { /* NOT MATCHING */ int digit; CInt64 tmp; - unsigned long a; - unsigned long b; + UInt32 a; + UInt32 b; *pFail = 0; - pResult->a = pResult->b = 0; + pResult->hi = pResult->lo = 0; for (;;) { if ((digit = str[0]) >= '0' && digit <= '9') @@ -668,8 +667,8 @@ char *CInt64_ScanHexString(CInt64 *pResult, char *str, unsigned char *pFail) { else break; - a = pResult->a; - b = pResult->b; + a = pResult->hi; + b = pResult->lo; ++str; if (a & 0xF0000000) @@ -680,8 +679,8 @@ char *CInt64_ScanHexString(CInt64 *pResult, char *str, unsigned char *pFail) { SHIFT_LEFT_ONE(a, b); SHIFT_LEFT_ONE(a, b); - pResult->a = a; - pResult->b = b; + pResult->hi = a; + pResult->lo = b; CInt64_SetLong(&tmp, (char) digit); *pResult = CInt64_Add(*pResult, tmp); @@ -690,13 +689,13 @@ char *CInt64_ScanHexString(CInt64 *pResult, char *str, unsigned char *pFail) { return str; } -char *CInt64_ScanBinString(CInt64 *pResult, char *str, unsigned char *pFail) { +char *CInt64_ScanBinString(CInt64 *pResult, char *str, Boolean *pFail) { char digit; - unsigned long a; - unsigned long b; + UInt32 a; + UInt32 b; *pFail = 0; - pResult->a = pResult->b = 0; + pResult->hi = pResult->lo = 0; for (;;) { if (*str == '0') @@ -706,8 +705,8 @@ char *CInt64_ScanBinString(CInt64 *pResult, char *str, unsigned char *pFail) { else break; - a = pResult->a; - b = pResult->b; + a = pResult->hi; + b = pResult->lo; ++str; if (a & 0x80000000) @@ -715,8 +714,8 @@ char *CInt64_ScanBinString(CInt64 *pResult, char *str, unsigned char *pFail) { SHIFT_LEFT_ONE(a, b); - pResult->a = a; - pResult->b = b; + pResult->hi = a; + pResult->lo = b; if (digit == 1) *pResult = CInt64_Add(*pResult, cint64_one); @@ -725,11 +724,11 @@ char *CInt64_ScanBinString(CInt64 *pResult, char *str, unsigned char *pFail) { return str; } -char *CInt64_ScanAsmNumber(CInt64 *pResult, char *str, unsigned char *pFail) { - unsigned char isMaybeBin; - unsigned char isOct; - unsigned char isMaybeDec; - unsigned char isBin; +char *CInt64_ScanAsmNumber(CInt64 *pResult, char *str, Boolean *pFail) { + Boolean isMaybeBin; + Boolean isOct; + Boolean isMaybeDec; + Boolean isBin; char *p; isMaybeBin = 1; @@ -794,13 +793,13 @@ int CInt64_PrintDec(char *output, CInt64 value) { } if (!CInt64_IsZero(&value)) { - divisor.b = 10; - divisor.a = 0; + divisor.lo = 10; + divisor.hi = 0; bufp = buf; for (;;) { rem = CInt64_ModU(value, divisor); - *(bufp++) = rem.b + '0'; + *(bufp++) = rem.lo + '0'; value = CInt64_DivU(value, divisor); if (CInt64_IsZero(&value) != 0) break; @@ -829,18 +828,18 @@ int CInt64_PrintHex(char *output, CInt64 value) { length = 0; if (!CInt64_IsZero(&value)) { - shift.b = 4; - shift.a = 0; - mask.b = 0xF; - mask.a = 0; + shift.lo = 4; + shift.hi = 0; + mask.lo = 0xF; + mask.hi = 0; bufp = buf; for (;;) { rem = CInt64_And(value, mask); - if ((long) rem.b >= 10) - *(bufp++) = rem.b + 'A'; + if ((SInt32) rem.lo >= 10) + *(bufp++) = rem.lo + 'A'; else - *(bufp++) = rem.b + '0'; + *(bufp++) = rem.lo + '0'; value = CInt64_ShrU(value, shift); if (CInt64_IsZero(&value) != 0) break; diff --git a/compiler_and_linker/unsorted/CMachine.c b/compiler_and_linker/unsorted/CMachine.c new file mode 100644 index 0000000..f34ec88 --- /dev/null +++ b/compiler_and_linker/unsorted/CMachine.c @@ -0,0 +1,1499 @@ +#include "compiler.h" +#include "compiler/CError.h" +#include "compiler/CInt64.h" +#include "compiler/objects.h" +#include "compiler/types.h" + +TypeIntegral stbool = {TYPEINT, 0, IT_BOOL}; +TypeIntegral stchar = {TYPEINT, 1, IT_CHAR}; +TypeIntegral stsignedchar = {TYPEINT, 0, IT_SCHAR}; +TypeIntegral stunsignedchar = {TYPEINT, 0, IT_UCHAR}; +TypeIntegral stwchar = {TYPEINT, 4, IT_WCHAR_T}; +TypeIntegral stsignedshort = {TYPEINT, 2, IT_SHORT}; +TypeIntegral stunsignedshort = {TYPEINT, 2, IT_USHORT}; +TypeIntegral stsignedint = {TYPEINT, 4, IT_INT}; +TypeIntegral stunsignedint = {TYPEINT, 4, IT_UINT}; +TypeIntegral stsignedlong = {TYPEINT, 4, IT_LONG}; +TypeIntegral stunsignedlong = {TYPEINT, 4, IT_ULONG}; +TypeIntegral stsignedlonglong = {TYPEINT, 8, IT_LONGLONG}; +TypeIntegral stunsignedlonglong = {TYPEINT, 8, IT_ULONGLONG}; +TypeIntegral stfloat = {TYPEFLOAT, 4, IT_FLOAT}; +TypeIntegral stshortdouble = {TYPEINT, 8, IT_SHORTDOUBLE}; +TypeIntegral stdouble = {TYPEINT, 8, IT_DOUBLE}; +TypeIntegral stlongdouble = {TYPEINT, 8, IT_LONGDOUBLE}; + +static StructMember stVUC_unsignedchar15 = {NULL, (Type *) &stunsignedchar, NULL, 15, 0}; +static StructMember stVUC_unsignedchar14 = {&stVUC_unsignedchar15, (Type *) &stunsignedchar, NULL, 14, 0}; +static StructMember stVUC_unsignedchar13 = {&stVUC_unsignedchar14, (Type *) &stunsignedchar, NULL, 13, 0}; +static StructMember stVUC_unsignedchar12 = {&stVUC_unsignedchar13, (Type *) &stunsignedchar, NULL, 12, 0}; +static StructMember stVUC_unsignedchar11 = {&stVUC_unsignedchar12, (Type *) &stunsignedchar, NULL, 11, 0}; +static StructMember stVUC_unsignedchar10 = {&stVUC_unsignedchar11, (Type *) &stunsignedchar, NULL, 10, 0}; +static StructMember stVUC_unsignedchar9 = {&stVUC_unsignedchar10, (Type *) &stunsignedchar, NULL, 9, 0}; +static StructMember stVUC_unsignedchar8 = {&stVUC_unsignedchar9, (Type *) &stunsignedchar, NULL, 8, 0}; +static StructMember stVUC_unsignedchar7 = {&stVUC_unsignedchar7, (Type *) &stunsignedchar, NULL, 7, 0}; +static StructMember stVUC_unsignedchar6 = {&stVUC_unsignedchar7, (Type *) &stunsignedchar, NULL, 6, 0}; +static StructMember stVUC_unsignedchar5 = {&stVUC_unsignedchar6, (Type *) &stunsignedchar, NULL, 5, 0}; +static StructMember stVUC_unsignedchar4 = {&stVUC_unsignedchar5, (Type *) &stunsignedchar, NULL, 4, 0}; +static StructMember stVUC_unsignedchar3 = {&stVUC_unsignedchar4, (Type *) &stunsignedchar, NULL, 3, 0}; +static StructMember stVUC_unsignedchar2 = {&stVUC_unsignedchar3, (Type *) &stunsignedchar, NULL, 2, 0}; +static StructMember stVUC_unsignedchar1 = {&stVUC_unsignedchar2, (Type *) &stunsignedchar, NULL, 1, 0}; +static StructMember stVUC_unsignedchar0 = {&stVUC_unsignedchar1, (Type *) &stunsignedchar, NULL, 0, 0}; + +static StructMember stVSC_signedchar15 = {NULL, (Type *) &stsignedchar, NULL, 15, 0}; +static StructMember stVSC_signedchar14 = {&stVSC_signedchar15, (Type *) &stsignedchar, NULL, 14, 0}; +static StructMember stVSC_signedchar13 = {&stVSC_signedchar14, (Type *) &stsignedchar, NULL, 13, 0}; +static StructMember stVSC_signedchar12 = {&stVSC_signedchar13, (Type *) &stsignedchar, NULL, 12, 0}; +static StructMember stVSC_signedchar11 = {&stVSC_signedchar12, (Type *) &stsignedchar, NULL, 11, 0}; +static StructMember stVSC_signedchar10 = {&stVSC_signedchar11, (Type *) &stsignedchar, NULL, 10, 0}; +static StructMember stVSC_signedchar9 = {&stVSC_signedchar10, (Type *) &stsignedchar, NULL, 9, 0}; +static StructMember stVSC_signedchar8 = {&stVSC_signedchar9, (Type *) &stsignedchar, NULL, 8, 0}; +static StructMember stVSC_signedchar7 = {&stVSC_signedchar7, (Type *) &stsignedchar, NULL, 7, 0}; +static StructMember stVSC_signedchar6 = {&stVSC_signedchar7, (Type *) &stsignedchar, NULL, 6, 0}; +static StructMember stVSC_signedchar5 = {&stVSC_signedchar6, (Type *) &stsignedchar, NULL, 5, 0}; +static StructMember stVSC_signedchar4 = {&stVSC_signedchar5, (Type *) &stsignedchar, NULL, 4, 0}; +static StructMember stVSC_signedchar3 = {&stVSC_signedchar4, (Type *) &stsignedchar, NULL, 3, 0}; +static StructMember stVSC_signedchar2 = {&stVSC_signedchar3, (Type *) &stsignedchar, NULL, 2, 0}; +static StructMember stVSC_signedchar1 = {&stVSC_signedchar2, (Type *) &stsignedchar, NULL, 1, 0}; +static StructMember stVSC_signedchar0 = {&stVSC_signedchar1, (Type *) &stsignedchar, NULL, 0, 0}; + +static StructMember stVUS_unsignedshort7 = {NULL, (Type *) &stunsignedshort, NULL, 14, 0}; +static StructMember stVUS_unsignedshort6 = {&stVUS_unsignedshort7, (Type *) &stunsignedshort, NULL, 12, 0}; +static StructMember stVUS_unsignedshort5 = {&stVUS_unsignedshort7, (Type *) &stunsignedshort, NULL, 10, 0}; +static StructMember stVUS_unsignedshort4 = {&stVUS_unsignedshort5, (Type *) &stunsignedshort, NULL, 8, 0}; +static StructMember stVUS_unsignedshort3 = {&stVUS_unsignedshort4, (Type *) &stunsignedshort, NULL, 6, 0}; +static StructMember stVUS_unsignedshort2 = {&stVUS_unsignedshort3, (Type *) &stunsignedshort, NULL, 4, 0}; +static StructMember stVUS_unsignedshort1 = {&stVUS_unsignedshort2, (Type *) &stunsignedshort, NULL, 2, 0}; +static StructMember stVUS_unsignedshort0 = {&stVUS_unsignedshort1, (Type *) &stunsignedshort, NULL, 0, 0}; + +static StructMember stVSS_signedshort7 = {NULL, (Type *) &stsignedshort, NULL, 14, 0}; +static StructMember stVSS_signedshort6 = {&stVSS_signedshort7, (Type *) &stsignedshort, NULL, 12, 0}; +static StructMember stVSS_signedshort5 = {&stVSS_signedshort7, (Type *) &stsignedshort, NULL, 10, 0}; +static StructMember stVSS_signedshort4 = {&stVSS_signedshort5, (Type *) &stsignedshort, NULL, 8, 0}; +static StructMember stVSS_signedshort3 = {&stVSS_signedshort4, (Type *) &stsignedshort, NULL, 6, 0}; +static StructMember stVSS_signedshort2 = {&stVSS_signedshort3, (Type *) &stsignedshort, NULL, 4, 0}; +static StructMember stVSS_signedshort1 = {&stVSS_signedshort2, (Type *) &stsignedshort, NULL, 2, 0}; +static StructMember stVSS_signedshort0 = {&stVSS_signedshort1, (Type *) &stsignedshort, NULL, 0, 0}; + +static StructMember stVUL_unsignedlong3 = {NULL, (Type *) &stunsignedlong, NULL, 12, 0}; +static StructMember stVUL_unsignedlong2 = {&stVUL_unsignedlong3, (Type *) &stunsignedlong, NULL, 8, 0}; +static StructMember stVUL_unsignedlong1 = {&stVUL_unsignedlong2, (Type *) &stunsignedlong, NULL, 4, 0}; +static StructMember stVUL_unsignedlong0 = {&stVUL_unsignedlong1, (Type *) &stunsignedlong, NULL, 0, 0}; + +static StructMember stVSL_signedlong3 = {NULL, (Type *) &stsignedlong, NULL, 12, 0}; +static StructMember stVSL_signedlong2 = {&stVSL_signedlong3, (Type *) &stsignedlong, NULL, 8, 0}; +static StructMember stVSL_signedlong1 = {&stVSL_signedlong2, (Type *) &stsignedlong, NULL, 4, 0}; +static StructMember stVSL_signedlong0 = {&stVSL_signedlong1, (Type *) &stsignedlong, NULL, 0, 0}; + +static StructMember stVF_float3 = {NULL, (Type *) &stfloat, NULL, 12, 0}; +static StructMember stVF_float2 = {&stVF_float3, (Type *) &stfloat, NULL, 8, 0}; +static StructMember stVF_float1 = {&stVF_float2, (Type *) &stfloat, NULL, 4, 0}; +static StructMember stVF_float0 = {&stVF_float1, (Type *) &stfloat, NULL, 0, 0}; + +TypeStruct stvectorunsignedchar = {TYPESTRUCT, 16, NULL, &stVUC_unsignedchar0, STRUCT_TYPE_4, 16}; +TypeStruct stvectorsignedchar = {TYPESTRUCT, 16, NULL, &stVSC_signedchar0, STRUCT_TYPE_5, 16}; +TypeStruct stvectorboolchar = {TYPESTRUCT, 16, NULL, &stVSC_signedchar0, STRUCT_TYPE_6, 16}; + +TypeStruct stvectorunsignedshort = {TYPESTRUCT, 16, NULL, &stVUS_unsignedshort0, STRUCT_TYPE_7, 16}; +TypeStruct stvectorsignedshort = {TYPESTRUCT, 16, NULL, &stVSS_signedshort0, STRUCT_TYPE_8, 16}; +TypeStruct stvectorboolshort = {TYPESTRUCT, 16, NULL, &stVSS_signedshort0, STRUCT_TYPE_9, 16}; + +TypeStruct stvectorunsignedlong = {TYPESTRUCT, 16, NULL, &stVUL_unsignedlong0, STRUCT_TYPE_A, 16}; +TypeStruct stvectorsignedlong = {TYPESTRUCT, 16, NULL, &stVSL_signedlong0, STRUCT_TYPE_B, 16}; +TypeStruct stvectorboollong = {TYPESTRUCT, 16, NULL, &stVSL_signedlong0, STRUCT_TYPE_C, 16}; + +TypeStruct stvectorfloat = {TYPESTRUCT, 16, NULL, &stVF_float0, STRUCT_TYPE_D, 16}; + +TypeStruct stvectorpixel = {TYPESTRUCT, 16, NULL, &stVUS_unsignedshort0, STRUCT_TYPE_E, 16}; + +TypeStruct stvector = {TYPESTRUCT, 16, NULL, NULL, STRUCT_TYPE_A, 16}; + +static SInt32 cmach_structoffset; +static UInt8 cmach_structalign; +static short cmach_curbfsize; +static short cmach_curbfbasesize; +static int cmach_curbfoffset; + +static short cmach_packsize[] = { + 1, 2, 4, 8, 16 +}; + +// forward declarations +static SInt16 CMach_GetQualifiedTypeAlign(Type *type, Boolean flag); +static SInt16 CMach_GetMemberAlignment(Type *type, SInt32 align, Boolean flag); + +void CMach_Configure() { +} + +SInt32 CMach_GetQUALalign(UInt32 qual) { + SInt32 result = 0; + SInt32 chk; + + if ((chk = (qual & Q_ALIGNED_MASK))) { + if (chk == Q_ALIGNED_1) + result = 1; + else if (chk == Q_ALIGNED_2) + result = 2; + else if (chk == Q_ALIGNED_4) + result = 4; + else if (chk == Q_ALIGNED_8) + result = 8; + else if (chk == Q_ALIGNED_16) + result = 16; + else if (chk == Q_ALIGNED_32) + result = 32; + else if (chk == Q_ALIGNED_64) + result = 64; + else if (chk == Q_ALIGNED_128) + result = 128; + else if (chk == Q_ALIGNED_256) + result = 256; + else if (chk == Q_ALIGNED_512) + result = 512; + else if (chk == Q_ALIGNED_1024) + result = 1024; + else if (chk == Q_ALIGNED_2048) + result = 2048; + else if (chk == Q_ALIGNED_4096) + result = 4096; + else if (chk == Q_ALIGNED_8192) + result = 8192; + else { +#line 226 + CError_FATAL(); + } + } + + return result; +} + +SInt32 CMach_ArgumentAlignment(Type *type) { + // does not match - registers + UInt8 save_align_mode; + UInt8 save_oldalignment; + SInt32 align; + + save_align_mode = copts.align_mode; + save_oldalignment = copts.oldalignment; + copts.align_mode = AlignMode2_PPC; + copts.oldalignment = 0; + align = CMach_GetQualifiedTypeAlign(type, 0); + copts.align_mode = save_align_mode; + copts.oldalignment = save_oldalignment; + + if (type->type == TYPESTRUCT && !TYPE_STRUCT(type)->members && TYPE_STRUCT(type)->align > align) + align = TYPE_STRUCT(type)->align; + + return align; +} + +SInt32 CMach_AllocationAlignment(Type *type, UInt32 qual) { + SInt32 align; + SInt32 qualalign; + SInt32 argalign; + SInt32 anotheralign; + + qualalign = CMach_GetQUALalign(qual); + align = CMach_GetQualifiedTypeAlign(type, 1); + if (qualalign > align) + align = qualalign; + argalign = CMach_ArgumentAlignment(type); + if (argalign > align) + align = argalign; + + switch (type->type) { + case TYPEVOID: + case TYPEMEMBERPOINTER: + case TYPEPOINTER: + anotheralign = 4; + break; + default: + anotheralign = 1; + } + if (anotheralign > align) + align = anotheralign; + + if (copts.optimizationlevel > 0) { + if (type->type == TYPEARRAY || (type->type == TYPESTRUCT && (TYPE_STRUCT(type)->stype < STRUCT_TYPE_4 || TYPE_STRUCT(type)->stype > STRUCT_TYPE_E)) || type->type == TYPECLASS || (type->type == TYPEMEMBERPOINTER && (UInt32) type->size == 12)) { + return (copts.some_alignment > align) ? copts.some_alignment : align; + } + } + + return align; +} + +CInt64 CMach_CalcIntDiadic(Type *type, CInt64 left, short op, CInt64 right) { + if (is_unsigned(type)) { + switch (type->size) { + case 1: + CInt64_ConvertUInt8(&left); + CInt64_ConvertUInt8(&right); + break; + case 2: + CInt64_ConvertUInt16(&left); + CInt64_ConvertUInt16(&right); + break; + case 4: + CInt64_ConvertUInt32(&left); + CInt64_ConvertUInt32(&right); + break; + case 8: + break; + default: +#line 327 + CError_FATAL(); + } + + switch (op) { + case '*': + left = CInt64_MulU(left, right); + break; + case '/': + if (CInt64_IsZero(&right)) + CError_Warning(139); + else + left = CInt64_DivU(left, right); + break; + case '%': + if (CInt64_IsZero(&right)) + CError_Warning(139); + else + left = CInt64_ModU(left, right); + break; + case '+': + left = CInt64_Add(left, right); + break; + case '-': + left = CInt64_Sub(left, right); + break; + case TK_SHL: + left = CInt64_Shl(left, right); + break; + case TK_SHR: + left = CInt64_ShrU(left, right); + break; + case '<': + CInt64_SetLong(&left, CInt64_LessU(left, right)); + break; + case '>': + CInt64_SetLong(&left, CInt64_GreaterU(left, right)); + break; + case TK_LESS_EQUAL: + CInt64_SetLong(&left, CInt64_LessEqualU(left, right)); + break; + case TK_GREATER_EQUAL: + CInt64_SetLong(&left, CInt64_GreaterEqualU(left, right)); + break; + case TK_LOGICAL_EQ: + CInt64_SetLong(&left, CInt64_Equal(left, right)); + break; + case TK_LOGICAL_NE: + CInt64_SetLong(&left, CInt64_NotEqual(left, right)); + break; + case '&': + left = CInt64_And(left, right); + break; + case '^': + left = CInt64_Xor(left, right); + break; + case '|': + left = CInt64_Or(left, right); + break; + case TK_LOGICAL_AND: + CInt64_SetLong(&left, (CInt64_IsZero(&left) == 0 && CInt64_IsZero(&right) == 0)); + break; + case TK_LOGICAL_OR: + CInt64_SetLong(&left, (CInt64_IsZero(&left) == 0 || CInt64_IsZero(&right) == 0)); + break; + default: + CError_Error(120); + } + + switch (type->size) { + case 1: + CInt64_ConvertUInt8(&left); + break; + case 2: + CInt64_ConvertUInt16(&left); + break; + case 4: + CInt64_ConvertUInt32(&left); + break; + case 8: + break; + } + } else { + switch (type->size) { + case 1: + CInt64_ConvertInt8(&left); + CInt64_ConvertInt8(&right); + break; + case 2: + CInt64_ConvertInt16(&left); + CInt64_ConvertInt16(&right); + break; + case 4: + CInt64_ConvertInt32(&left); + CInt64_ConvertInt32(&right); + break; + case 8: + break; + default: +#line 389 + CError_FATAL(); + } + + switch (op) { + case '*': + left = CInt64_Mul(left, right); + break; + case '/': + if (CInt64_IsZero(&right)) + CError_Warning(139); + else + left = CInt64_Div(left, right); + break; + case '%': + if (CInt64_IsZero(&right)) + CError_Warning(139); + else + left = CInt64_Mod(left, right); + break; + case '+': + left = CInt64_Add(left, right); + break; + case '-': + left = CInt64_Sub(left, right); + break; + case TK_SHL: + left = CInt64_Shl(left, right); + break; + case TK_SHR: + left = CInt64_Shr(left, right); + break; + case '<': + CInt64_SetLong(&left, CInt64_Less(left, right)); + break; + case '>': + CInt64_SetLong(&left, CInt64_Greater(left, right)); + break; + case TK_LESS_EQUAL: + CInt64_SetLong(&left, CInt64_LessEqual(left, right)); + break; + case TK_GREATER_EQUAL: + CInt64_SetLong(&left, CInt64_GreaterEqual(left, right)); + break; + case TK_LOGICAL_EQ: + CInt64_SetLong(&left, CInt64_Equal(left, right)); + break; + case TK_LOGICAL_NE: + CInt64_SetLong(&left, CInt64_NotEqual(left, right)); + break; + case '&': + left = CInt64_And(left, right); + break; + case '^': + left = CInt64_Xor(left, right); + break; + case '|': + left = CInt64_Or(left, right); + break; + case TK_LOGICAL_AND: + CInt64_SetLong(&left, (CInt64_IsZero(&left) == 0 && CInt64_IsZero(&right) == 0)); + break; + case TK_LOGICAL_OR: + CInt64_SetLong(&left, (CInt64_IsZero(&left) == 0 || CInt64_IsZero(&right) == 0)); + break; + default: + CError_Error(120); + } + + switch (type->size) { + case 1: + CInt64_ConvertInt8(&left); + break; + case 2: + CInt64_ConvertInt16(&left); + break; + case 4: + CInt64_ConvertInt32(&left); + break; + case 8: + break; + } + } + + return left; +} + +CInt64 CMach_CalcIntMonadic(Type *type, short op, CInt64 val) { + if (is_unsigned(type)) { + switch (type->size) { + case 1: + CInt64_ConvertUInt8(&val); + break; + case 2: + CInt64_ConvertUInt16(&val); + break; + case 4: + CInt64_ConvertUInt32(&val); + break; + case 8: + break; + default: +#line 448 + CError_FATAL(); + } + + switch (op) { + case '-': + val = CInt64_Neg(val); + break; + case '~': + val = CInt64_Inv(val); + break; + case '!': + val = CInt64_Not(val); + break; + default: + CError_Error(120); + } + + switch (type->size) { + case 1: + CInt64_ConvertUInt8(&val); + break; + case 2: + CInt64_ConvertUInt16(&val); + break; + case 4: + CInt64_ConvertUInt32(&val); + break; + case 8: + break; + } + } else { + switch (type->size) { + case 1: + CInt64_ConvertInt8(&val); + break; + case 2: + CInt64_ConvertInt16(&val); + break; + case 4: + CInt64_ConvertInt32(&val); + break; + case 8: + break; + default: +#line 478 + CError_FATAL(); + } + + switch (op) { + case '-': + val = CInt64_Neg(val); + break; + case '~': + val = CInt64_Inv(val); + break; + case '!': + val = CInt64_Not(val); + break; + default: + CError_Error(120); + } + + switch (type->size) { + case 1: + CInt64_ConvertInt8(&val); + break; + case 2: + CInt64_ConvertInt16(&val); + break; + case 4: + CInt64_ConvertInt32(&val); + break; + case 8: + break; + } + } + + return val; +} + +CInt64 CMach_CalcIntConvertFromFloat(Type *type, Float fval) { + CInt64 result; + + if ((type->type == TYPEINT || type->type == TYPEENUM) && (type->size == 8)) { + if (is_unsigned(type)) + CInt64_ConvertUFromLongDouble(&result, fval.value); + else + CInt64_ConvertFromLongDouble(&result, fval.value); + } else { + if (is_unsigned(type)) + CInt64_SetULong(&result, fval.value); + else + CInt64_SetLong(&result, fval.value); + } + + return result; +} + +void CMach_InitIntMem(Type *type, CInt64 val, void *mem) { + UInt32 lg; + UInt16 sh; + UInt8 ch; + + switch (type->type) { + case TYPEINT: + switch (type->size) { + case 1: + ch = (UInt8) val.lo; + memcpy(mem, &ch, 1); + break; + case 2: + sh = (UInt16) val.lo; + memcpy(mem, &sh, 2); + break; + case 4: + lg = (UInt32) val.lo; + memcpy(mem, &lg, 4); + break; + case 8: + CTool_EndianConvertWord64(val, mem); + break; + default: +#line 566 + CError_FATAL(); + } + break; + default: +#line 570 + CError_FATAL(); + } +} + +void CMach_InitVectorMem(Type *type, MWVector128 val, void *mem) { + unsigned char uc[16]; + unsigned short us[8]; + unsigned int ul[4]; + float f[4]; + int i; + + switch (type->type) { + case TYPESTRUCT: + switch (TYPE_STRUCT(type)->stype) { + case STRUCT_TYPE_4: + case STRUCT_TYPE_5: + case STRUCT_TYPE_6: + for (i = 0; i < 16; i++) + uc[i] = val.uc[i]; + memcpy(mem, uc, 16); + break; + case STRUCT_TYPE_7: + case STRUCT_TYPE_8: + case STRUCT_TYPE_9: + case STRUCT_TYPE_E: + for (i = 0; i < 8; i++) + us[i] = val.us[i]; + memcpy(mem, us, 16); + break; + case STRUCT_TYPE_A: + case STRUCT_TYPE_B: + case STRUCT_TYPE_C: + for (i = 0; i < 4; i++) + ul[i] = val.ul[i]; + memcpy(mem, ul, 16); + break; + case STRUCT_TYPE_D: + for (i = 0; i < 4; i++) + f[i] = val.f[i]; + memcpy(mem, f, 16); + break; + default: +#line 655 + CError_FATAL(); + } + break; + default: +#line 659 + CError_FATAL(); + } +} + +Float CMach_CalcFloatDiadic(Type *type, Float left, short op, Float right) { + switch (op) { + case '+': + left.value += right.value; + break; + case '-': + left.value -= right.value; + break; + case '*': + left.value *= right.value; + break; + case '/': + left.value /= right.value; + break; + default: +#line 679 + CError_FATAL(); + } + + return CMach_CalcFloatConvert(type, left); +} + +Float CMach_CalcFloatMonadic(Type *type, short op, Float fval) { + if (op != '-') +#line 692 + CError_FATAL(); + + fval.value = -fval.value; + return CMach_CalcFloatConvert(type, fval); +} + +Boolean CMach_CalcFloatDiadicBool(Type *type, Float left, short op, Float right) { + switch (op) { + case TK_LOGICAL_EQ: + return left.value == right.value; + case TK_LOGICAL_NE: + return left.value != right.value; + case TK_LESS_EQUAL: + return left.value <= right.value; + case TK_GREATER_EQUAL: + return left.value >= right.value; + case '>': + return left.value > right.value; + case '<': + return left.value < right.value; + default: +#line 714 + CError_FATAL(); + return 0; + } +} + +Boolean CMach_CalcVectorDiadicBool(Type *type, MWVector128 *left, short op, MWVector128 *right) { + switch (op) { + case TK_LOGICAL_EQ: + return (left->ul[0] == right->ul[0]) && (left->ul[1] == right->ul[1]) && (left->ul[2] == right->ul[2]) && (left->ul[3] == right->ul[3]); + case TK_LOGICAL_NE: + return (left->ul[0] != right->ul[0]) && (left->ul[1] != right->ul[1]) && (left->ul[2] != right->ul[2]) && (left->ul[3] != right->ul[3]); + default: +#line 740 + CError_FATAL(); + return 0; + } +} + +char *CMach_FloatScan(char *input, Float *result, Boolean *fail) { + double resultval; + char *outpos; + + if (!(outpos = ScanFloat(input, &resultval, fail))) + CError_ErrorTerm(154); + + if (*fail) + result->value = 0.0; + else + result->value = resultval; + + return outpos; +} + +Float CMach_CalcFloatConvertFromInt(Type *type, CInt64 val) { + Float result; + + if ((type->type == TYPEINT || type->type == TYPEENUM) && (type->size == 8)) { + if (is_unsigned(type)) + result.value = CInt64_ConvertUToLongDouble(&val); + else + result.value = CInt64_ConvertToLongDouble(&val); + } else { + if (is_unsigned(type)) + result.value = val.lo; + else + result.value = (SInt32) val.lo; + } + + return result; +} + +Float CMach_CalcFloatConvert(Type *type, Float fval) { + switch (type->size) { + case 4: + fval.value = (float) fval.value; + break; + case 8: + fval.value = (double) fval.value; + break; + case 10: + case 12: + break; + default: +#line 801 + CError_FATAL(); + } + return fval; +} + +Boolean CMach_FloatIsZero(Float fval) { + return fval.value == 0.0; +} + +Boolean CMach_FloatIsOne(Float fval) { + return fval.value == 1.0; +} + +Boolean CMach_FloatIsNegOne(Float fval) { + return fval.value == -1.0; +} + +void CMach_InitFloatMem(Type *type, Float val, void *mem) { + float f; + double d; + + if (type->type == TYPEFLOAT) { + switch (type->size) { + case 4: + f = val.value; + memcpy(mem, &f, 4); + return; + case 8: + d = val.value; + memcpy(mem, &d, 8); + return; + } + } + +#line 866 + CError_FATAL(); +} + +void CMach_PrintFloat(char *buf, Float val) { + double f; + CMach_InitFloatMem((Type *) &stshortdouble, val, &f); + sprintf(buf, "%g", f); +} + +void CMach_PragmaParams() { + if (copts.warn_illpragma) + CError_Warning(186, 0); + + while (notendofline()) + lex(); +} + +void CMach_AdjustFuntionArgs() { + // not called so we will never know what the args should have been :( +} + +static SInt32 CMach_GetPPCTypeAlign(Type *type, Boolean flag1, Boolean flag2) { + ClassList *base; + ObjMemberVar *ivar; + StructMember *member; + SInt32 best; + SInt32 ivarAlign; + SInt32 qualAlign; + + SInt32 align = CMach_GetQualifiedTypeAlign(type, flag2); + if (align <= 8) { + while (type->type == TYPEARRAY) + type = TYPE_POINTER(type)->target; + + if (flag1) { + if (type->type == TYPEFLOAT && type->size > 4 && align < 8) + return 8; + } else if (align == 8) { + if (type->type == TYPECLASS) { + best = 4; + for (base = TYPE_CLASS(type)->bases; base; base = base->next) { + if (base->base->align > best) + best = base->base->align; + } + for (ivar = TYPE_CLASS(type)->ivars; ivar; ivar = ivar->next) { + ivarAlign = CMach_GetPPCTypeAlign(ivar->type, 0, flag2); + if (ivarAlign > best) + best = ivarAlign; + if (flag2) { + qualAlign = CMach_GetQUALalign(ivar->qual); + if (qualAlign > best) + best = qualAlign; + } + } + return best; + } + if (type->type == TYPESTRUCT) { + best = 4; + for (member = TYPE_STRUCT(type)->members; member; member = member->next) { + ivarAlign = CMach_GetPPCTypeAlign(member->type, 0, flag2); + if (ivarAlign > best) + best = ivarAlign; + if (flag2) { + qualAlign = CMach_GetQUALalign(member->qual); + if (qualAlign > best) + best = qualAlign; + } + } + return best; + } + } + } + + return align; +} + +static SInt16 CMach_GetQualifiedStructAlign(TypeStruct *tstruct, Boolean flag) { + StructMember *member; + SInt32 best; + SInt32 align; + Boolean isFirst; + + // very close to matching but tstruct->stype gets cached when it should not be + if (tstruct->stype >= STRUCT_TYPE_4 && tstruct->stype <= STRUCT_TYPE_E) { + return 16; + } else { + + switch (copts.align_mode) { + case AlignMode3_1Byte: + case AlignMode8: + return 1; + case AlignMode0_Mac68k: + return 2; + case AlignMode1_Mac68k4byte: + return (tstruct->size <= 2) ? 2 : 4; + } + + if (tstruct->size <= 1) + return 1; + best = 1; + switch (copts.align_mode) { + default: +#line 1026 + CError_FATAL(); + case AlignMode4_2Byte: + case AlignMode5_4Byte: + case AlignMode6_8Byte: + case AlignMode7_16Byte: + for (member = tstruct->members; member; member = member->next) { + align = CMach_GetQualifiedTypeAlign(member->type, flag); + if (align > best) + best = align; + if (flag) { + align = CMach_GetQUALalign(member->qual); + if (align > best) + best = align; + } + } + return best; + case AlignMode2_PPC: + if (copts.oldalignment) { + for (member = tstruct->members; member; member = member->next) { + align = CMach_GetQualifiedTypeAlign(member->type, flag); + if (align > best) + best = align; + if (flag) { + align = CMach_GetQUALalign(member->qual); + if (align > best) + best = align; + } + } + } else if (tstruct->stype == STRUCT_TYPE_UNION) { + for (member = tstruct->members; member; member = member->next) { + align = CMach_GetPPCTypeAlign(member->type, 1, flag); + if (align > best) + best = align; + if (flag) { + align = CMach_GetQUALalign(member->qual); + if (align > best) + best = align; + } + } + } else { + isFirst = 1; + for (member = tstruct->members; member; member = member->next) { + align = CMach_GetPPCTypeAlign(member->type, isFirst || (best >= 8), flag); + if (align > best) + best = align; + if (flag) { + align = CMach_GetQUALalign(member->qual); + if (align > best) + best = align; + } + isFirst = 0; + } + } + return best; + } + } +} + +SInt16 CMach_GetStructAlign(TypeStruct *tstruct) { + return CMach_GetQualifiedStructAlign(tstruct, 1); +} + +static SInt16 CMach_GetQualifiedClassAlign(TypeClass *tclass, Boolean flag) { + ClassList *base; + ObjMemberVar *ivar; + SInt32 best; + SInt32 align; + Boolean isFirst; + + switch (copts.align_mode) { + case AlignMode3_1Byte: + case AlignMode8: + return 1; + case AlignMode0_Mac68k: + return 2; + case AlignMode1_Mac68k4byte: + return (tclass->size <= 2) ? 2 : 4; + } + if (tclass->size <= 1) + return 1; + best = 1; + switch (copts.align_mode) { + default: +#line 1149 + CError_FATAL(); + case AlignMode4_2Byte: + case AlignMode5_4Byte: + case AlignMode6_8Byte: + case AlignMode7_16Byte: + for (base = tclass->bases; base; base = base->next) { + if ((align = base->base->align) > best) + best = align; + } + for (ivar = tclass->ivars; ivar; ivar = ivar->next) { + align = CMach_GetMemberAlignment(ivar->type, flag ? CMach_GetQUALalign(ivar->qual) : 0, flag); + if (align > best) + best = align; + } + return best; + case AlignMode2_PPC: + best = 1; + if (copts.oldalignment) { + for (base = tclass->bases; base; base = base->next) { + if ((align = base->base->align) > best) + best = align; + } + for (ivar = tclass->ivars; ivar; ivar = ivar->next) { + align = CMach_GetMemberAlignment(ivar->type, flag ? CMach_GetQUALalign(ivar->qual) : 0, flag); + if (align > best) + best = align; + } + } else { + isFirst = 1; + for (base = tclass->bases; base; base = base->next) { + if ((align = base->base->align) > best) + best = align; + isFirst = 0; + } + if (tclass->mode == 1) { + for (ivar = tclass->ivars; ivar; ivar = ivar->next) { + align = CMach_GetPPCTypeAlign(ivar->type, 1, flag); + if (align > best) + best = align; + if (flag) { + align = CMach_GetQUALalign(ivar->qual); + if (align > best) + best = align; + } + } + } else { + for (ivar = tclass->ivars; ivar; ivar = ivar->next) { + if (ivar->offset && align != 8) + isFirst = 0; + align = CMach_GetPPCTypeAlign(ivar->type, isFirst || (best >= 8), flag); + if (align > best) + best = align; + if (flag) { + align = CMach_GetQUALalign(ivar->qual); + if (align > best) + best = align; + } + } + } + } + return best; + } +} + +SInt16 CMach_GetClassAlign(TypeClass *tclass) { + return CMach_GetQualifiedClassAlign(tclass, 1); +} + +static SInt16 CMach_GetWinTypeAlign(Type *type) { + int packoffs = copts.align_mode - 3; + SInt32 align = cmach_packsize[packoffs]; + if (type->size < align) + align = type->size; + return align; +} + +static SInt16 CMach_GetWinMinimizeAlign(SInt16 align) { + int packoffs = copts.align_mode - 3; + SInt16 minimum = cmach_packsize[packoffs]; + if (minimum < align) + align = minimum; + return align; +} + +static SInt16 CMach_GetQualifiedTypeAlign(Type *type, Boolean flag) { + Boolean r31; + SInt16 align; + + if (type->type == TYPESTRUCT && TYPE_STRUCT(type)->stype >= STRUCT_TYPE_4 && TYPE_STRUCT(type)->stype <= STRUCT_TYPE_E) + return 16; + + switch (copts.align_mode) { + case AlignMode3_1Byte: + case AlignMode8: + return 1; + case AlignMode4_2Byte: + case AlignMode5_4Byte: + case AlignMode6_8Byte: + case AlignMode7_16Byte: + r31 = 1; + break; + default: + r31 = 0; + break; + } + +restart: + switch (type->type) { + case TYPEVOID: + return 0; + case TYPEFUNC: + return 0; + case TYPEENUM: + type = TYPE_ENUM(type)->enumtype; + case TYPEINT: + if (r31) + return CMach_GetWinTypeAlign(type); + if (type->size == 1) + return 1; + if (copts.oldalignment && type->size == 8) + return 8; + if (copts.align_mode != AlignMode0_Mac68k && type->size >= 4) + return 4; + return 2; + case TYPEFLOAT: + if (r31) + return CMach_GetWinTypeAlign(type); + switch (copts.align_mode) { + case AlignMode0_Mac68k: + return 2; + case AlignMode1_Mac68k4byte: + return 4; + case AlignMode2_PPC: + if (copts.oldalignment && type->size > 4) + return 8; + return 4; + default: +#line 1346 + CError_FATAL(); + } + case TYPEMEMBERPOINTER: + case TYPEPOINTER: + if (r31) + return CMach_GetWinTypeAlign(type); + if (copts.align_mode == AlignMode0_Mac68k) + return 2; + else + return 4; + case TYPEARRAY: + if (copts.align_array_members) { + if (r31) + return CMach_GetWinTypeAlign(type); + if (type->size == 1) + return 1; + if (copts.align_mode == AlignMode0_Mac68k || type->size <= 2) + return 2; + if (copts.align_mode == AlignMode1_Mac68k4byte || type->size < 8) + return 4; + align = CMach_GetQualifiedTypeAlign(TYPE_POINTER(type)->target, flag); + if (align > 4) + return align; + else + return 4; + } else { + type = TYPE_POINTER(type)->target; + goto restart; + } + case TYPESTRUCT: + if (flag) + align = TYPE_STRUCT(type)->align; + else + align = CMach_GetQualifiedStructAlign(TYPE_STRUCT(type), flag); + if (r31) + return CMach_GetWinMinimizeAlign(align); + else + return align; + case TYPECLASS: + if (flag) + align = TYPE_CLASS(type)->align; + else + align = CMach_GetQualifiedClassAlign(TYPE_CLASS(type), flag); + if (r31) + return CMach_GetWinMinimizeAlign(align); + else + return align; + case TYPEBITFIELD: + type = TYPE_BITFIELD(type)->bitfieldtype; + goto restart; + case TYPETEMPLATE: + return 1; + default: +#line 1392 + CError_FATAL(); + return 0; + } +} + +SInt16 CMach_GetTypeAlign(Type *type) { + return CMach_GetQualifiedTypeAlign(type, 1); +} + +static SInt16 CMach_GetMemberAlignment(Type *type, SInt32 var, Boolean flag) { + SInt32 align; + + align = CMach_GetQualifiedTypeAlign(type, flag); + if (align < 1) + align = 1; + + if (type->type == TYPESTRUCT && TYPE_STRUCT(type)->stype >= STRUCT_TYPE_4 && TYPE_STRUCT(type)->stype <= STRUCT_TYPE_E && align < 16) + align = 16; + + switch (copts.align_mode) { + case AlignMode8: + align = 1; + break; + case AlignMode0_Mac68k: + if (align > 2) + align = 2; + break; + case AlignMode1_Mac68k4byte: + if (align > 4) + align = 4; + break; + case AlignMode2_PPC: + if (!copts.oldalignment) + align = CMach_GetPPCTypeAlign(type, !cmach_structoffset || (cmach_structalign >= 8), flag); + if (var > align) + align = var; + break; + } + + if (align > cmach_structalign) + cmach_structalign = align; + return align; +} + +SInt16 CMach_MemberAlignValue(Type *type, SInt32 var) { + SInt16 align = CMach_GetMemberAlignment(type, 0, 1); + if (align <= 1) + return 0; + + return (align - 1) & (align - (var & (align - 1))); +} + +static SInt16 MemberAlignValue(Type *type, SInt32 var1, SInt32 var2) { + SInt16 align = CMach_GetMemberAlignment(type, var2, 1); + return (align - 1) & (align - (var1 & (align - 1))); +} + +void CMach_StructLayoutInitOffset(SInt32 offset) { + cmach_structoffset = offset; + cmach_structalign = 4; + cmach_curbfsize = 0; +} + +SInt32 CMach_StructLayoutGetCurSize() { + return cmach_structoffset; +} + +SInt32 CMach_StructLayoutGetOffset(Type *type, UInt32 qual) { + SInt32 align; + SInt32 offset; + + qual = CParser_GetTypeQualifiers(type, qual); + + cmach_curbfsize = 0; + align = MemberAlignValue(type, cmach_structoffset, CMach_GetQUALalign(qual)); + offset = cmach_structoffset + align; + cmach_structoffset = offset + type->size; + return offset; +} + +SInt32 CMach_StructLayoutBitfield(TypeBitfield *tbitfield, UInt32 qual) { + SInt16 align; + SInt16 padding_at_start; + SInt16 basesize; + SInt16 basesize_bits; + SInt16 required_alignment; + SInt16 r4; + + padding_at_start = 0; + required_alignment = 0; + align = CMach_GetQUALalign(qual); + if (align <= tbitfield->bitfieldtype->size) + align = 0; + + switch (tbitfield->bitfieldtype->size) { + case 1: + basesize = 1; + basesize_bits = 8; + required_alignment = 0; + break; + case 2: + basesize = 2; + basesize_bits = 16; + required_alignment = 2; + break; + case 4: + if (copts.align_mode != AlignMode0_Mac68k && copts.align_mode != AlignMode4_2Byte) + required_alignment = 4; + else + required_alignment = 2; + basesize = 4; + basesize_bits = 32; + break; + default: +#line 1620 + CError_FATAL(); + } + + switch (copts.align_mode) { + case AlignMode3_1Byte: + case AlignMode8: + required_alignment = 0; + break; + } + + r4 = required_alignment; + if (align > required_alignment) + r4 = align; + if (r4 && (cmach_structoffset & (r4 - 1))) + padding_at_start = r4 - (cmach_structoffset & (r4 - 1)); + + if (!cmach_curbfsize) { + cmach_structoffset += padding_at_start; + if (!tbitfield->unkB) + return cmach_structoffset; + cmach_curbfsize = tbitfield->unkB; + cmach_curbfbasesize = basesize; + cmach_curbfoffset = cmach_structoffset; + cmach_structoffset += basesize; + tbitfield->unkA = 0; + return cmach_curbfoffset; + } else { + if (!tbitfield->unkB || (cmach_curbfsize + tbitfield->unkB) > basesize_bits || cmach_curbfbasesize != basesize) { + cmach_structoffset += padding_at_start; + cmach_curbfsize = 0; + cmach_curbfbasesize = basesize; + if (!tbitfield->unkB) + return cmach_structoffset; + cmach_curbfoffset = cmach_structoffset; + cmach_structoffset += basesize; + } + tbitfield->unkA = cmach_curbfsize; + cmach_curbfsize += tbitfield->unkB; + return cmach_curbfoffset; + } +} + +static Boolean CMach_IsTrivialClass(TypeClass *tclass) { + return !CClass_Constructor(tclass); +} + +UInt8 CMach_GetFunctionResultClass(TypeFunc *tfunc) { + switch (tfunc->functype->type) { + case TYPESTRUCT: + if (tfunc->functype->type == TYPESTRUCT && TYPE_STRUCT(tfunc->functype)->stype >= STRUCT_TYPE_4 && TYPE_STRUCT(tfunc->functype)->stype <= STRUCT_TYPE_E) + return 0; + case TYPECLASS: + case TYPEMEMBERPOINTER: + return CMach_PassResultInHiddenArg(tfunc->functype) ? 1 : 0; + default: + return 0; + } +} + +Boolean CMach_PassResultInHiddenArg(Type *type) { + switch (type->type) { + case TYPESTRUCT: + if (TYPE_STRUCT(type)->stype >= STRUCT_TYPE_4 && TYPE_STRUCT(type)->stype <= STRUCT_TYPE_E) + return 0; + else + return 1; + case TYPECLASS: + return 1; + case TYPEMEMBERPOINTER: + return (type->size == 4) ? 0 : 1; + default: + return 0; + } +} + +const char *CMach_GetCPU() { + switch (copts.cpu) { + case CPU_PPC401: return "__PPC401__"; + case CPU_PPC403: return "__PPC403__"; + case CPU_PPC505: return "__PPC505__"; + case CPU_PPC509: return "__PPC509__"; + case CPU_PPC555: return "__PPC555__"; + case CPU_PPC556: return "__PPC556__"; + case CPU_PPC565: return "__PPC565__"; + case CPU_PPC601: return "__PPC601__"; + case CPU_PPC602: return "__PPC602__"; + case CPU_PPC603: return "__PPC603__"; + case CPU_PPC603e: return "__PPC603e__"; + case CPU_PPC604: return "__PPC604__"; + case CPU_PPC604e: return "__PPC604e__"; + case CPU_PPC740: return "__PPC740__"; + case CPU_PPC750: return "__PPC750__"; + case CPU_PPC801: return "__PPC801__"; + case CPU_PPC821: return "__PPC821__"; + case CPU_PPC823: return "__PPC823__"; + case CPU_PPC850: return "__PPC850__"; + case CPU_PPC860: return "__PPC860__"; + case CPU_PPC7400: return "__PPC7400__"; + case CPU_PPC7450: return "__PPC7450__"; + case CPU_PPC8240: return "__PPC8240__"; + case CPU_PPC8260: return "__PPC8260__"; + case CPU_PPCGEKKO: return "__PPCGEKKO__"; + case CPU_PPCELF: return "__PPCELF__"; + default: return NULL; + } +} + +Boolean CMach_FloatIsPowerOf2(Float flt) { + return (flt.value == 2.0) || + (flt.value == 4.0) || + (flt.value == 8.0) || + (flt.value == 16.0) || + (flt.value == 32.0) || + (flt.value == 64.0) || + (flt.value == 128.0) || + (flt.value == 256.0) || + (flt.value == 512.0) || + (flt.value == 1024.0); +} + +Float CMach_FloatReciprocal(Float flt) { + flt.value = 1.0 / flt.value; + return flt; +} + +SInt32 CMach_RoundedSizeOf(Object *object) { + SInt32 size = object->type->size; + SInt32 align = CMach_GetTypeAlign(object->type) - 1; + return (size + align) & ~align; +} + +void CMach_ReInitRuntimeObjects() { + HashNameNode *e0 = GetHashNameNodeExport("[0]"); + HashNameNode *e1 = GetHashNameNodeExport("[1]"); + HashNameNode *e2 = GetHashNameNodeExport("[2]"); + HashNameNode *e3 = GetHashNameNodeExport("[3]"); + HashNameNode *e4 = GetHashNameNodeExport("[4]"); + HashNameNode *e5 = GetHashNameNodeExport("[5]"); + HashNameNode *e6 = GetHashNameNodeExport("[6]"); + HashNameNode *e7 = GetHashNameNodeExport("[7]"); + HashNameNode *e8 = GetHashNameNodeExport("[8]"); + HashNameNode *e9 = GetHashNameNodeExport("[9]"); + HashNameNode *e10 = GetHashNameNodeExport("[10]"); + HashNameNode *e11 = GetHashNameNodeExport("[11]"); + HashNameNode *e12 = GetHashNameNodeExport("[12]"); + HashNameNode *e13 = GetHashNameNodeExport("[13]"); + HashNameNode *e14 = GetHashNameNodeExport("[14]"); + HashNameNode *e15 = GetHashNameNodeExport("[15]"); + HashNameNode *vuc = GetHashNameNodeExport("vector unsigned char"); + HashNameNode *vus = GetHashNameNodeExport("vector unsigned short"); + HashNameNode *vui = GetHashNameNodeExport("vector unsigned int"); + HashNameNode *vsc = GetHashNameNodeExport("vector signed char"); + HashNameNode *vss = GetHashNameNodeExport("vector signed short"); + HashNameNode *vsi = GetHashNameNodeExport("vector signed int"); + HashNameNode *vbc = GetHashNameNodeExport("vector bool char"); + HashNameNode *vbs = GetHashNameNodeExport("vector bool short"); + HashNameNode *vbi = GetHashNameNodeExport("vector bool int"); + HashNameNode *vf = GetHashNameNodeExport("vector float"); + HashNameNode *vp = GetHashNameNodeExport("vector pixel"); + + stvectorunsignedchar.name = vuc; + stvectorunsignedshort.name = vus; + stvectorunsignedlong.name = vui; + stvectorsignedchar.name = vsc; + stvectorsignedshort.name = vss; + stvectorsignedlong.name = vsi; + stvectorboolchar.name = vbc; + stvectorboolshort.name = vbs; + stvectorboollong.name = vbi; + stvectorfloat.name = vf; + stvectorpixel.name = vp; + + stVUC_unsignedchar0.name = e0; + stVUC_unsignedchar1.name = e1; + stVUC_unsignedchar2.name = e2; + stVUC_unsignedchar3.name = e3; + stVUC_unsignedchar4.name = e4; + stVUC_unsignedchar5.name = e5; + stVUC_unsignedchar6.name = e6; + stVUC_unsignedchar7.name = e7; + stVUC_unsignedchar8.name = e8; + stVUC_unsignedchar9.name = e9; + stVUC_unsignedchar10.name = e10; + stVUC_unsignedchar11.name = e11; + stVUC_unsignedchar12.name = e12; + stVUC_unsignedchar13.name = e13; + stVUC_unsignedchar14.name = e14; + stVUC_unsignedchar15.name = e15; + stVSC_signedchar0.name = e0; + stVSC_signedchar1.name = e1; + stVSC_signedchar2.name = e2; + stVSC_signedchar3.name = e3; + stVSC_signedchar4.name = e4; + stVSC_signedchar5.name = e5; + stVSC_signedchar6.name = e6; + stVSC_signedchar7.name = e7; + stVSC_signedchar8.name = e8; + stVSC_signedchar9.name = e9; + stVSC_signedchar10.name = e10; + stVSC_signedchar11.name = e11; + stVSC_signedchar12.name = e12; + stVSC_signedchar13.name = e13; + stVSC_signedchar14.name = e14; + stVSC_signedchar15.name = e15; + + stVUS_unsignedshort0.name = e0; + stVUS_unsignedshort1.name = e1; + stVUS_unsignedshort2.name = e2; + stVUS_unsignedshort3.name = e3; + stVUS_unsignedshort4.name = e4; + stVUS_unsignedshort5.name = e5; + stVUS_unsignedshort6.name = e6; + stVUS_unsignedshort7.name = e7; + stVSS_signedshort0.name = e0; + stVSS_signedshort1.name = e1; + stVSS_signedshort2.name = e2; + stVSS_signedshort3.name = e3; + stVSS_signedshort4.name = e4; + stVSS_signedshort5.name = e5; + stVSS_signedshort6.name = e6; + stVSS_signedshort7.name = e7; + + stVUL_unsignedlong0.name = e0; + stVUL_unsignedlong1.name = e1; + stVUL_unsignedlong2.name = e2; + stVUL_unsignedlong3.name = e3; + stVSL_signedlong0.name = e0; + stVSL_signedlong1.name = e1; + stVSL_signedlong2.name = e2; + stVSL_signedlong3.name = e3; + + stVF_float0.name = e0; + stVF_float1.name = e1; + stVF_float2.name = e2; + stVF_float3.name = e3; +} diff --git a/compiler_and_linker/unsorted/CPrec.c b/compiler_and_linker/unsorted/CPrec.c new file mode 100644 index 0000000..a879df6 --- /dev/null +++ b/compiler_and_linker/unsorted/CPrec.c @@ -0,0 +1,2142 @@ +#include "compiler.h" +#include "compiler/CompilerTools.h" +#include "compiler/CError.h" +#include "compiler/enode.h" +#include "compiler/objc.h" +#include "compiler/objects.h" +#include "compiler/scopes.h" +#include "compiler/som.h" +#include "compiler/templates.h" +#include "compiler/types.h" +#include "cos.h" + +// HACKS +extern Type stvoid; +extern Type stbool; +extern Type stchar; +extern Type stsignedchar; +extern Type stunsignedchar; +extern Type stwchar; +extern Type stsignedshort; +extern Type stunsignedshort; +extern Type stsignedint; +extern Type stunsignedint; +extern Type stsignedlong; +extern Type stunsignedlong; +extern Type stsignedlonglong; +extern Type stunsignedlonglong; +extern Type stfloat; +extern Type stshortdouble; +extern Type stdouble; +extern Type stlongdouble; +extern Type elipsis; +extern Type oldstyle; +extern Type stillegal; +extern Type sttemplexpr; +extern Type stvoid; +extern Type void_ptr; +extern Type rt_func; +extern Type catchinfostruct; +extern void * newh_func; +extern void * delh_func; +extern void * copy_func; +extern void * clear_func; +extern void * Rgtid_func; +extern void * Rdync_func; +extern void * rt_ptmf_cast; +extern void * rt_ptmf_cmpr; +extern void * rt_ptmf_test; +extern void * rt_ptmf_call; +extern void * rt_ptmf_scall; +extern void * rt_ptmf_null; +extern void * rt_som_glue1; +extern void * rt_som_glue2; +extern void * rt_som_glue3; +extern void * rt_som_check; +extern void * rt_som_new; +extern void * rt_som_newcheck; +extern void * rt_ptmf_call4; +extern void * rt_ptmf_scall4; +extern void * carr_func; +extern void * cnar_func; +extern void * darr_func; +extern void * dnar_func; +extern void * dnar3_func; +extern void * Xgreg_func; +extern void * Xthrw_func; +extern void * Xicth_func; +extern void * Xecth_func; +extern void * Xunex_func; +extern Type stvectorunsignedchar; +extern Type stvectorsignedchar; +extern Type stvectorboolchar; +extern Type stvectorunsignedshort; +extern Type stvectorsignedshort; +extern Type stvectorboolshort; +extern Type stvectorunsignedlong; +extern Type stvectorsignedlong; +extern Type stvectorboollong; +extern Type stvectorfloat; +extern Type stvectorpixel; +// HACKS + +// PUBLIC FUNCTIONS +extern void SetupPrecompiler(); +extern void CleanupPrecompiler(); +extern void PreComp_StaticData(Object *obj, const void *data, void *unk1, void *unk2); +extern void PrecompilerWrite(); +extern void PrecompilerRead(short refnum, void *buffer); +// END PUBLIC FUNCTIONS + +typedef struct Patch { + struct Patch *next; + SInt32 offset; +} Patch; + +typedef struct AddrPatch { + struct AddrPatch *next; + void *addr; + void *value; +} AddrPatch; + +typedef struct BuiltIn { + void *target; + SInt32 idx; + Patch *patches; +} BuiltIn; + +static Boolean cprec_exportargnames; +static Boolean cprec_dowrite; +static OSErr cprec_ioerror; +static void *cprec_rawbuffer; +static void *cprec_buffer; +static SInt32 cprec_zero_offset; +static SInt32 cprec_offset; +static int cprec_builtins; +static void **cprec_builtin_array; + +typedef struct TokenPatch { + struct TokenPatch *next; + TStreamElement *tokens; + SInt32 count; +} TokenPatch; +static TokenPatch *cprec_tokenpatches; + +static void *cprec_staticdata; +static void *cprec_pointerhash; +static BuiltIn *cprec_builtin; +static Patch *cprec_patch_list; +static AddrPatch **cprec_addrhash; +static void *cprec_header; +static GList cprec_glist; +static short cprec_refnum; +char *precomp_target_str; + +// Assorted forward declarations +static NameSpace *CPrec_GetNameSpacePatch(NameSpace *nspace); +static ObjEnumConst *CPrec_GetObjEnumConstPatch(ObjEnumConst *obj); +static Object *CPrec_GetObjectPatch(Object *obj); +static ObjBase *CPrec_GetObjBasePatch(ObjBase *obj); +static ObjMemberVar *CPrec_GetObjMemberVarPatch(ObjMemberVar *obj); +static Type *CPrec_GetTypePatch(Type *type); +static ENode *CPrec_GetExpressionPatch(ENode *enode); +static ObjCMethod *CPrec_GetObjCMethodPatch(ObjCMethod *meth); +static ObjCProtocolList *CPrec_GetObjCProtocolListPatch(ObjCProtocolList *lst); +static TemplArg *CPrec_GetTemplateArgPatch(TemplArg *arg); +static OSErr CPrec_FlushBufferCheck(); + +void SetupPrecompiler() { + cprec_refnum = 0; + cprec_glist.data = NULL; + cprec_header = NULL; + cprec_staticdata = NULL; + cprec_ioerror = noErr; +} + +void CleanupPrecompiler() { + if (cprec_refnum) { + COS_FileClose(cprec_refnum); + cprec_refnum = 0; + } + + if (cprec_glist.data) + FreeGList(&cprec_glist); +} + +static void CPrec_OLinkListCopy() {} + +void PreComp_StaticData(Object *obj, const void *data, void *unk1, void *unk2) { + +} + +static void CPrec_InitAddressHashTable() { + cprec_addrhash = lalloc(0x4000 * sizeof(AddrPatch *)); + memclrw(cprec_addrhash, 0x4000 * sizeof(AddrPatch *)); +} + +static void CPrec_InitPointerHashTable() { + cprec_pointerhash = lalloc(0x1000); + memclrw(cprec_pointerhash, 0x1000); +} + +static int CPrec_AddressHashVal(void *addr) { + UInt32 v = (UInt32) addr; + return ( + v + + ((unsigned char *) &v)[0] + + ((unsigned char *) &v)[1] + + ((unsigned char *) &v)[2] + + ((unsigned char *) &v)[3] + ) & 0x3FFF; +} + +static AddrPatch *CPrec_FindAddrPatch(void *addr) { + AddrPatch *scan; + + for (scan = cprec_addrhash[CPrec_AddressHashVal(addr)]; scan; scan = scan->next) { + if (scan->addr == addr) + return scan; + } + + return NULL; +} + +static AddrPatch *CPrec_NewAddrPatch(void *addr, void *value) { + AddrPatch **loc; + AddrPatch *patch; + + loc = cprec_addrhash + CPrec_AddressHashVal(addr); + patch = lalloc(sizeof(AddrPatch)); + patch->addr = addr; + patch->value = value; + patch->next = *loc; + *loc = patch; + return patch; +} + +static void CPrec_SetupBuiltInArray() { + int count1, count2; + Boolean flag; + void **array; + +#define REG_BUILTIN(a) \ + if (!flag) { array[count2++] = (a); } else { count1++; } + + for (count2 = count1 = 0, flag = 1; ;) { + REG_BUILTIN(cscope_root); + REG_BUILTIN(&stvoid); + REG_BUILTIN(&stbool); + REG_BUILTIN(&stchar); + REG_BUILTIN(&stsignedchar); + REG_BUILTIN(&stunsignedchar); + REG_BUILTIN(&stwchar); + REG_BUILTIN(&stsignedshort); + REG_BUILTIN(&stunsignedshort); + REG_BUILTIN(&stsignedint); + REG_BUILTIN(&stunsignedint); + REG_BUILTIN(&stsignedlong); + REG_BUILTIN(&stunsignedlong); + REG_BUILTIN(&stsignedlonglong); + REG_BUILTIN(&stunsignedlonglong); + REG_BUILTIN(&stfloat); + REG_BUILTIN(&stshortdouble); + REG_BUILTIN(&stdouble); + REG_BUILTIN(&stlongdouble); + REG_BUILTIN(&elipsis); + REG_BUILTIN(&oldstyle); + REG_BUILTIN(&stillegal); + REG_BUILTIN(&sttemplexpr); + REG_BUILTIN(&stvoid); + REG_BUILTIN(&void_ptr); + REG_BUILTIN(&rt_func); + REG_BUILTIN(&catchinfostruct); + REG_BUILTIN(newh_func); + REG_BUILTIN(delh_func); + REG_BUILTIN(copy_func); + REG_BUILTIN(clear_func); + REG_BUILTIN(Rgtid_func); + REG_BUILTIN(Rdync_func); + REG_BUILTIN(rt_ptmf_cast); + REG_BUILTIN(rt_ptmf_cmpr); + REG_BUILTIN(rt_ptmf_test); + REG_BUILTIN(rt_ptmf_call); + REG_BUILTIN(rt_ptmf_scall); + REG_BUILTIN(rt_ptmf_null); + REG_BUILTIN(rt_som_glue1); + REG_BUILTIN(rt_som_glue2); + REG_BUILTIN(rt_som_glue3); + REG_BUILTIN(rt_som_check); + REG_BUILTIN(rt_som_new); + REG_BUILTIN(rt_som_newcheck); + REG_BUILTIN(rt_ptmf_call4); + REG_BUILTIN(rt_ptmf_scall4); + REG_BUILTIN(carr_func); + REG_BUILTIN(cnar_func); + REG_BUILTIN(darr_func); + REG_BUILTIN(dnar_func); + REG_BUILTIN(dnar3_func); + REG_BUILTIN(Xgreg_func); + REG_BUILTIN(Xthrw_func); + REG_BUILTIN(Xicth_func); + REG_BUILTIN(Xecth_func); + REG_BUILTIN(Xunex_func); + REG_BUILTIN(&stvectorunsignedchar); + REG_BUILTIN(&stvectorsignedchar); + REG_BUILTIN(&stvectorboolchar); + REG_BUILTIN(&stvectorunsignedshort); + REG_BUILTIN(&stvectorsignedshort); + REG_BUILTIN(&stvectorboolshort); + REG_BUILTIN(&stvectorunsignedlong); + REG_BUILTIN(&stvectorsignedlong); + REG_BUILTIN(&stvectorboollong); + REG_BUILTIN(&stvectorfloat); + REG_BUILTIN(&stvectorpixel); + + if (flag) { + array = lalloc(sizeof(void *) * count1); + cprec_builtin_array = array; + cprec_builtins = count1; + flag = 0; + } else { + return; + } + } +} + +static void CPrec_SetupBuiltIn() { + int x; + + CPrec_SetupBuiltInArray(); + cprec_builtin = lalloc(sizeof(BuiltIn) * cprec_builtins); + memclrw(cprec_builtin, sizeof(BuiltIn) * cprec_builtins); + + for (x = 0; x < cprec_builtins; x++) { + cprec_builtin[x].target = cprec_builtin_array[x]; + cprec_builtin[x].idx = ~x; + CPrec_NewAddrPatch(cprec_builtin[x].target, (void *) cprec_builtin[x].idx); + } +} + +static void CPrec_NewPointerPatch(void *src, void *ptr) { + if (cprec_dowrite) { + Patch *patch = lalloc(sizeof(Patch)); + patch->offset = (SInt32) src; +#line 507 + CError_ASSERT((patch->offset & 0x80000001) == 0); + + if ((SInt32) ptr < 0) { + ptr = (void *) ~((SInt32) ptr); +#line 513 + CError_ASSERT((SInt32) ptr < cprec_builtins); + + patch->next = cprec_builtin[(SInt32) ptr].patches; + cprec_builtin[(SInt32) ptr].patches = patch; + ptr = NULL; + } else { + patch->next = cprec_patch_list; + cprec_patch_list = patch; + } + + src = (void *)((char *) src - cprec_zero_offset); +#line 525 + CError_ASSERT((SInt32) src >= 0 && (SInt32) src <= cprec_glist.size); + *((void **) (*cprec_glist.data + (SInt32) src)) = ptr; + } +} + +static void CPrec_ExistingPointerPatch(void *src, void *ptr) { + if (cprec_dowrite) { + AddrPatch *addrPatch; + Patch *patch; + + addrPatch = CPrec_FindAddrPatch(ptr); +#line 543 + CError_ASSERT(addrPatch); + + patch = lalloc(sizeof(Patch)); + patch->offset = (SInt32) src; + patch->next = cprec_patch_list; + cprec_patch_list = patch; + +#line 548 + CError_ASSERT((patch->offset & 0x80000001) == 0); + + src = (void *)((char *) src - cprec_zero_offset); +#line 552 + CError_ASSERT((SInt32) src >= 0 && (SInt32) src <= cprec_glist.size); + *((void **) (*cprec_glist.data + (SInt32) src)) = addrPatch->value; + } +} + +static void CPrec_NamePatch(void *src, HashNameNode *name) { + name->id = 1; + CPrec_ExistingPointerPatch(src, name); +} + +static void *CPrec_AppendAlign() { + if (cprec_dowrite) { + while (cprec_offset & 3) { + AppendGListByte(&cprec_glist, 0); + ++cprec_offset; + } + } + + return (void *) cprec_offset; +} + +static UInt32 CPrec_AppendByte(UInt8 v) { + if (cprec_dowrite) + AppendGListByte(&cprec_glist, v); + return cprec_offset++; +} + +static UInt32 CPrec_AppendWord16(UInt16 v) { + UInt32 offset; + if (cprec_dowrite) + AppendGListWord(&cprec_glist, v); + offset = cprec_offset; + cprec_offset += 2; + return offset; +} + +static UInt32 CPrec_AppendWord32(UInt32 v) { + UInt32 offset; + if (cprec_dowrite) + AppendGListLong(&cprec_glist, v); + offset = cprec_offset; + cprec_offset += 4; + return offset; +} + +static UInt32 CPrec_AppendPointer(void *v) { + UInt32 offset; + if (cprec_dowrite) + AppendGListLong(&cprec_glist, (SInt32) v); + offset = cprec_offset; + cprec_offset += 4; + return offset; +} + +static UInt32 CPrec_AppendPointerPatch(void *v) { + AddrPatch *addrPatch; + + if (v) { + addrPatch = CPrec_FindAddrPatch(v); +#line 644 + CError_ASSERT(addrPatch); + + if (cprec_dowrite) { + Patch *patch = lalloc(sizeof(Patch)); + patch->offset = cprec_offset; + patch->next = cprec_patch_list; + cprec_patch_list = patch; +#line 651 + CError_ASSERT((patch->offset & 0x80000001) == 0); + } + + return CPrec_AppendPointer(addrPatch->value); + } else { + return CPrec_AppendPointer(NULL); + } +} + +static void CPrec_AppendNamePatch(HashNameNode *name) { + if (name) { + CPrec_AppendPointerPatch(name); + name->id = 1; + } +} + +static void CPrec_AppendString(const char *str) { + int len = strlen(str) + 1; + if (cprec_dowrite) + AppendGListData(&cprec_glist, str, len); + cprec_offset += len; +} + +static void CPrec_AppendData(const void *data, int len) { + if (cprec_dowrite) + AppendGListData(&cprec_glist, data, len); + cprec_offset += len; +} + +static void CPrec_RawMemPatch(void *source, const void *data, int len) { + void *ptr = CPrec_AppendAlign(); + CPrec_AppendData(data, len); + CPrec_NewPointerPatch(source, ptr); +} + +static void CPrec_DumpNameTable() {} +static void CPrec_DumpMacroTable() {} +static void CPrec_GetClassAccessPatch() {} + +static int CPrec_PointerHash(TypePointer *type) { + Type *target; + int work; + FuncArg *arg; + + work = type->qual; + target = type->target; + +restart: + switch (target->type) { + case TYPECLASS: + if (TYPE_CLASS(target)->classname) + work += TYPE_CLASS(target)->classname->hashval; + break; + case TYPEENUM: + if (TYPE_ENUM(target)->enumname) + work += TYPE_ENUM(target)->enumname->hashval; + target = TYPE_ENUM(target)->enumtype; + work += 3; + case TYPEINT: + case TYPEFLOAT: + work += TYPE_INTEGRAL(target)->integral; + break; + case TYPEPOINTER: + work += TYPE_POINTER(target)->qual; + target = TYPE_POINTER(target)->target; + goto restart; + case TYPEARRAY: + work += target->size; + target = TYPE_POINTER(target)->target; + goto restart; + case TYPEFUNC: + work += TYPE_FUNC(target)->functype->type; + work += TYPE_FUNC(target)->functype->size; + for (arg = TYPE_FUNC(target)->args; arg; arg = arg->next) { + if (arg->type) { + work += arg->type->type; + work += arg->type->size; + } + } + break; + } + + work += target->type + target->size; + return (work + (work >> 24) + (work >> 16) + (work >> 8)) & 0x3FF; +} + +static TypePointer *CPrec_GetTypePointerPatch(TypePointer *type) { + // requires copts +} + +static TypeEnum *CPrec_GetTypeEnumPatch(TypeEnum *type) { + TypeEnum *p = CPrec_AppendAlign(); + + CPrec_NewAddrPatch(type, p); + CPrec_AppendData(type, sizeof(TypeEnum)); + + if (type->nspace) + CPrec_NewPointerPatch(&p->nspace, CPrec_GetNameSpacePatch(type->nspace)); + if (type->enumlist) + CPrec_NewPointerPatch(&p->enumlist, CPrec_GetObjEnumConstPatch(type->enumlist)); + + CPrec_NewPointerPatch(&p->enumtype, CPrec_GetTypePatch(type->enumtype)); + if (type->enumname) + CPrec_NamePatch(&p->enumname, type->enumname); + + return p; +} + +static TypeBitfield *CPrec_GetTypeBitfieldPatch(TypeBitfield *type) { + TypeBitfield *p = CPrec_AppendAlign(); + CPrec_NewAddrPatch(type, p); + CPrec_AppendData(type, sizeof(TypeBitfield)); + + CPrec_NewPointerPatch(&p->bitfieldtype, type->bitfieldtype); + + return p; +} + +static TypeStruct *CPrec_GetTypeStructPatch(TypeStruct *type) {} + +static ExceptSpecList *CPrec_GetExceptSpecPatch(ExceptSpecList *exspec) { + ExceptSpecList *first, *current, *next; + + first = current = CPrec_AppendAlign(); + while (exspec) { + CPrec_AppendData(exspec, sizeof(ExceptSpecList)); + if (exspec->type) + CPrec_NewPointerPatch(¤t->type, CPrec_GetTypePatch(exspec->type)); + + if (!exspec->next) + break; + next = CPrec_AppendAlign(); + CPrec_NewPointerPatch(¤t->next, next); + current = next; + exspec = exspec->next; + } + + return first; +} + +static FuncArg *CPrec_GetArgListPatch(FuncArg *lst, Boolean includeNames) { + // too many register swaps + AddrPatch *addrPatch; + FuncArg *first, *current, *next; + + if ((addrPatch = CPrec_FindAddrPatch(lst))) + return addrPatch->value; + + first = current = CPrec_AppendAlign(); +restart: + if (!includeNames) + lst->name = NULL; + CPrec_AppendData(lst, sizeof(FuncArg)); + if (includeNames && lst->name) + CPrec_NamePatch(¤t->name, lst->name); + + if (lst->dexpr) + CPrec_NewPointerPatch(¤t->dexpr, CPrec_GetExpressionPatch(lst->dexpr)); + if (lst->type) + CPrec_NewPointerPatch(¤t->type, CPrec_GetTypePatch(lst->type)); + else +#line 1167 + CError_FATAL(); + + if (lst->next) { + if ((addrPatch = CPrec_FindAddrPatch(lst->next))) { + CPrec_NewPointerPatch(¤t->next, addrPatch->value); + } else { + next = CPrec_AppendAlign(); + CPrec_NewPointerPatch(¤t->next, next); + current = next; + lst = lst->next; + CPrec_NewAddrPatch(lst, next); + goto restart; + } + } + + return first; +} + +static TypeFunc *CPrec_GetTypeFuncPatch(TypeFunc *type) { + TypeFunc *p = CPrec_AppendAlign(); + CPrec_NewAddrPatch(type, p); + + CPrec_AppendData(type, (type->flags & FUNC_FLAGS_METHOD) ? sizeof(TypeMethod) : sizeof(TypeFunc)); + + CPrec_NewPointerPatch(&p->functype, CPrec_GetTypePatch(type->functype)); + if (type->args) + CPrec_NewPointerPatch(&p->args, CPrec_GetArgListPatch(type->args, (type->flags & FUNC_FLAGS_900000) != 0)); + if (type->exspecs) + CPrec_NewPointerPatch(&p->exspecs, CPrec_GetExceptSpecPatch(type->exspecs)); + if (type->flags & FUNC_FLAGS_METHOD) + CPrec_NewPointerPatch(&TYPE_METHOD(p)->theclass, CPrec_GetTypePatch((Type *) TYPE_METHOD(type)->theclass)); + + return p; +} + +static TypeMemberPointer *CPrec_GetTypeMemberPointerPatch(TypeMemberPointer *type) { + TypeMemberPointer *p = CPrec_AppendAlign(); + CPrec_NewAddrPatch(type, p); + + CPrec_AppendData(type, sizeof(TypeMemberPointer)); + + CPrec_NewPointerPatch(&p->ty1, CPrec_GetTypePatch(type->ty1)); + CPrec_NewPointerPatch(&p->ty2, CPrec_GetTypePatch(type->ty2)); + + return p; +} + +static TypeTemplDep *CPrec_GetTypeTemplDepPatch(TypeTemplDep *type) { + TypeTemplDep *p = CPrec_AppendAlign(); + CPrec_NewAddrPatch(type, p); + + CPrec_AppendData(type, sizeof(TypeTemplDep)); + + switch (type->dtype) { + case TEMPLDEP_ARGUMENT: + break; + case TEMPLDEP_QUALNAME: + CPrec_NewPointerPatch(&p->u.qual.type, CPrec_GetTypeTemplDepPatch(type->u.qual.type)); + CPrec_NamePatch(&p->u.qual.name, type->u.qual.name); + break; + case TEMPLDEP_TEMPLATE: + CPrec_NewPointerPatch(&p->u.templ.templ, CPrec_GetTypePatch((Type *) type->u.templ.templ)); + CPrec_NewPointerPatch(&p->u.templ.args, CPrec_GetTemplateArgPatch(type->u.templ.args)); + break; + case TEMPLDEP_ARRAY: + CPrec_NewPointerPatch(&p->u.array.type, CPrec_GetTypePatch(type->u.array.type)); + CPrec_NewPointerPatch(&p->u.array.index, CPrec_GetExpressionPatch(type->u.array.index)); + break; + case TEMPLDEP_QUALTEMPL: + CPrec_NewPointerPatch(&p->u.qualtempl.type, CPrec_GetTypeTemplDepPatch(type->u.qualtempl.type)); + CPrec_NewPointerPatch(&p->u.qualtempl.args, CPrec_GetTemplateArgPatch(type->u.qualtempl.args)); + break; + case TEMPLDEP_BITFIELD: + CPrec_NewPointerPatch(&p->u.bitfield.type, CPrec_GetTypePatch(type->u.bitfield.type)); + CPrec_NewPointerPatch(&p->u.bitfield.size, CPrec_GetExpressionPatch(type->u.bitfield.size)); + break; + default: +#line 1295 + CError_FATAL(); + } + + return p; +} + +static ClassList *CPrec_GetClassListPatch(ClassList *cl) { + AddrPatch *addrPatch; + ClassList *first, *current, *next; + + if ((addrPatch = CPrec_FindAddrPatch(cl))) + return addrPatch->value; + + first = current = CPrec_AppendAlign(); + CPrec_NewAddrPatch(cl, first); + + do { + CPrec_AppendData(cl, sizeof(ClassList)); + CPrec_NewPointerPatch(¤t->base, CPrec_GetTypePatch((Type *) cl->base)); + + if (!cl->next) + break; + + if ((addrPatch = CPrec_FindAddrPatch(cl->next))) { + CPrec_NewPointerPatch(¤t->next, addrPatch->value); + break; + } else { + next = CPrec_AppendAlign(); + CPrec_NewPointerPatch(¤t->next, next); + current = next; + cl = cl->next; + } + } while (1); + + return first; +} + +static VClassList *CPrec_GetVClassListPatch(VClassList *vcl) { + VClassList *first, *current, *next; + first = current = CPrec_AppendAlign(); + + do { + CPrec_AppendData(vcl, sizeof(VClassList)); + CPrec_NewPointerPatch(¤t->base, CPrec_GetTypePatch((Type *) vcl->base)); + + if (!vcl->next) + break; + next = CPrec_AppendAlign(); + CPrec_NewPointerPatch(¤t->next, next); + current = next; + vcl = vcl->next; + } while (1); + + return first; +} + +static ClassFriend *CPrec_GetClassFriendPatch(ClassFriend *cf) { + ClassFriend *first, *current, *next; + first = current = CPrec_AppendAlign(); + + do { + CPrec_AppendData(cf, sizeof(ClassFriend)); + if (cf->isclass) + CPrec_NewPointerPatch(¤t->u.theclass, CPrec_GetTypePatch((Type *) cf->u.theclass)); + else + CPrec_NewPointerPatch(¤t->u.theclass, CPrec_GetObjectPatch(cf->u.obj)); + + if (!cf->next) + break; + next = CPrec_AppendAlign(); + CPrec_NewPointerPatch(¤t->next, next); + current = next; + cf = cf->next; + } while (1); + + return first; +} + +static BClassList *CPrec_GetBClassListPatch(BClassList *bcl) { + BClassList *first, *current, *next; + first = current = CPrec_AppendAlign(); + + do { + CPrec_AppendData(bcl, sizeof(BClassList)); + CPrec_NewPointerPatch(¤t->type, CPrec_GetTypePatch((Type *) bcl->type)); + + if (!bcl->next) + break; + next = CPrec_AppendAlign(); + CPrec_NewPointerPatch(¤t->next, next); + current = next; + bcl = bcl->next; + } while (1); + + return first; +} + +static VTable *CPrec_GetVTablePatch(VTable *vtbl) { + VTable *p = CPrec_AppendAlign(); + CPrec_AppendData(vtbl, sizeof(VTable)); + + if (vtbl->object) + CPrec_NewPointerPatch(&p->object, CPrec_GetObjectPatch(vtbl->object)); + if (vtbl->owner) + CPrec_NewPointerPatch(&p->owner, CPrec_GetTypePatch((Type *) vtbl->owner)); + + return p; +} + +static SOMReleaseOrder *CPrec_GetSOMReleaseOrderPatch(SOMReleaseOrder *sro) { + SOMReleaseOrder *first, *current, *next; + first = current = CPrec_AppendAlign(); + + do { + CPrec_AppendData(sro, sizeof(SOMReleaseOrder)); + CPrec_NamePatch(¤t->name, sro->name); + if (!sro->next) + break; + next = CPrec_AppendAlign(); + CPrec_NewPointerPatch(¤t->next, next); + current = next; + sro = sro->next; + } while (1); + + return first; +} + +static SOMInfo *CPrec_GetSOMInfoPatch(SOMInfo *som) { + SOMInfo *p = CPrec_AppendAlign(); + CPrec_AppendData(som, sizeof(SOMInfo)); + + if (som->metaclass) + CPrec_NewPointerPatch(&p->metaclass, CPrec_GetTypePatch((Type *) som->metaclass)); + if (som->classdataobject) + CPrec_NewPointerPatch(&p->classdataobject, CPrec_GetObjectPatch(som->classdataobject)); + if (som->order) + CPrec_NewPointerPatch(&p->order, CPrec_GetSOMReleaseOrderPatch(som->order)); + + return p; +} + +static ObjCMethodArg *CPrec_GetObjCMethodArgPatch(ObjCMethodArg *arg) { + ObjCMethodArg *first, *current, *next; + first = current = CPrec_AppendAlign(); + + do { + CPrec_AppendData(arg, sizeof(ObjCMethodArg)); + if (arg->selector) + CPrec_NamePatch(¤t->selector, arg->selector); + if (arg->name) + CPrec_NamePatch(¤t->name, arg->name); + if (arg->type) + CPrec_NewPointerPatch(¤t->type, CPrec_GetTypePatch(arg->type)); + + if (!arg->next) + break; + next = CPrec_AppendAlign(); + CPrec_NewPointerPatch(¤t->next, next); + current = next; + arg = arg->next; + } while (1); + + return first; +} + +static ObjCMethodList *CPrec_GetObjCMethodListPatch(ObjCMethodList *lst) { + AddrPatch *addrPatch; + ObjCMethodList *first, *current, *next; + + if ((addrPatch = CPrec_FindAddrPatch(lst))) + return addrPatch->value; + + first = current = CPrec_AppendAlign(); + CPrec_NewAddrPatch(lst, first); + + do { + CPrec_AppendData(lst, sizeof(ObjCMethodList)); + if (lst->method) + CPrec_NewPointerPatch(¤t->method, CPrec_GetObjCMethodPatch(lst->method)); + + if (!lst->next) + break; + + if ((addrPatch = CPrec_FindAddrPatch(lst->next))) { + CPrec_NewPointerPatch(¤t->next, addrPatch->value); + break; + } else { + next = CPrec_AppendAlign(); + CPrec_NewPointerPatch(¤t->next, next); + current = next; + lst = lst->next; + CPrec_NewAddrPatch(lst, next); + } + } while (1); + + return first; +} + +static ObjCSelector *CPrec_GetObjCSelectorPatch(ObjCSelector *sel) { + AddrPatch *addrPatch; + ObjCSelector *current, *first, *next; + + if ((addrPatch = CPrec_FindAddrPatch(sel))) + return addrPatch->value; + + first = current = CPrec_AppendAlign(); + CPrec_NewAddrPatch(sel, first); + + do { + CPrec_AppendData(sel, sizeof(ObjCSelector)); + if (sel->selobject) + CPrec_NewPointerPatch(¤t->selobject, CPrec_GetObjectPatch(sel->selobject)); + CPrec_NamePatch(¤t->name, sel->name); + if (sel->methods) + CPrec_NewPointerPatch(¤t->methods, CPrec_GetObjCMethodListPatch(sel->methods)); + + if (!sel->next) + break; + + if ((addrPatch = CPrec_FindAddrPatch(sel->next))) { + CPrec_NewPointerPatch(¤t->next, addrPatch->value); + break; + } else { + next = CPrec_AppendAlign(); + CPrec_NewPointerPatch(¤t->next, next); + current = next; + sel = sel->next; + CPrec_NewAddrPatch(sel, next); + } + } while (1); + + return first; +} + +static ObjCMethod *CPrec_GetObjCMethodPatch(ObjCMethod *meth) { + // does not match - affected by weirdness where the arg goes into r31 instead of r28 + AddrPatch *addrPatch; + ObjCMethod *current, *first, *next; + + if ((addrPatch = CPrec_FindAddrPatch(meth))) + return addrPatch->value; + + first = current = CPrec_AppendAlign(); + CPrec_NewAddrPatch(meth, first); + + do { + CPrec_AppendData(meth, sizeof(ObjCMethod)); + if (meth->object) + CPrec_NewPointerPatch(¤t->object, CPrec_GetObjectPatch(meth->object)); + if (meth->functype) + CPrec_NewPointerPatch(¤t->functype, CPrec_GetTypePatch((Type *) meth->functype)); + if (meth->selector) + CPrec_NewPointerPatch(¤t->selector, CPrec_GetObjCSelectorPatch(meth->selector)); + if (meth->return_type) + CPrec_NewPointerPatch(¤t->return_type, CPrec_GetTypePatch(meth->return_type)); + if (meth->selector_args) + CPrec_NewPointerPatch(¤t->selector_args, CPrec_GetObjCMethodArgPatch(meth->selector_args)); + + if (!meth->next) + break; + + if ((addrPatch = CPrec_FindAddrPatch(meth->next))) { + CPrec_NewPointerPatch(¤t->next, addrPatch->value); + break; + } else { + next = CPrec_AppendAlign(); + CPrec_NewPointerPatch(¤t->next, next); + current = next; + meth = meth->next; + CPrec_NewAddrPatch(meth, next); + } + } while (1); + + return first; +} + +static ObjCProtocol *CPrec_GetObjCProtocolPatch(ObjCProtocol *prot) { + AddrPatch *addrPatch; + ObjCProtocol *current, *first, *next; + + if ((addrPatch = CPrec_FindAddrPatch(prot))) + return addrPatch->value; + + first = current = CPrec_AppendAlign(); + CPrec_NewAddrPatch(prot, first); + + do { + CPrec_AppendData(prot, sizeof(ObjCProtocol)); + CPrec_NamePatch(¤t->name, prot->name); + if (prot->protocols) + CPrec_NewPointerPatch(¤t->protocols, CPrec_GetObjCProtocolListPatch(prot->protocols)); + if (prot->methods) + CPrec_NewPointerPatch(¤t->methods, CPrec_GetObjCMethodPatch(prot->methods)); + if (prot->object) + CPrec_NewPointerPatch(¤t->object, CPrec_GetObjectPatch(prot->object)); + + if (!prot->next) + break; + + if ((addrPatch = CPrec_FindAddrPatch(prot->next))) { + CPrec_NewPointerPatch(¤t->next, addrPatch->value); + break; + } else { + next = CPrec_AppendAlign(); + CPrec_NewPointerPatch(¤t->next, next); + current = next; + prot = prot->next; + CPrec_NewAddrPatch(prot, next); + } + } while (1); + + return first; +} + +static ObjCProtocolList *CPrec_GetObjCProtocolListPatch(ObjCProtocolList *lst) { + AddrPatch *addrPatch; + ObjCProtocolList *first, *current, *next; + + if ((addrPatch = CPrec_FindAddrPatch(lst))) + return addrPatch->value; + + first = current = CPrec_AppendAlign(); + CPrec_NewAddrPatch(lst, first); + + do { + CPrec_AppendData(lst, sizeof(ObjCProtocolList)); + CPrec_NewPointerPatch(¤t->protocol, CPrec_GetObjCProtocolPatch(lst->protocol)); + + if (!lst->next) + break; + + next = CPrec_AppendAlign(); + CPrec_NewPointerPatch(¤t->next, next); + current = next; + lst = lst->next; + } while (1); + + return first; +} + +static ObjCCategory *CPrec_GetObjCCategoryPatch(ObjCCategory *cat) { + AddrPatch *addrPatch; + ObjCCategory *current, *first, *next; + + if ((addrPatch = CPrec_FindAddrPatch(cat))) + return addrPatch->value; + + first = current = CPrec_AppendAlign(); + CPrec_NewAddrPatch(cat, first); + + do { + CPrec_AppendData(cat, sizeof(ObjCCategory)); + CPrec_NamePatch(¤t->name, cat->name); + if (cat->protocols) + CPrec_NewPointerPatch(¤t->protocols, CPrec_GetObjCProtocolListPatch(cat->protocols)); + if (cat->methods) + CPrec_NewPointerPatch(¤t->methods, CPrec_GetObjCMethodPatch(cat->methods)); + + if (!cat->next) + break; + + if ((addrPatch = CPrec_FindAddrPatch(cat->next))) { + CPrec_NewPointerPatch(¤t->next, addrPatch->value); + break; + } else { + next = CPrec_AppendAlign(); + CPrec_NewPointerPatch(¤t->next, next); + current = next; + cat = cat->next; + CPrec_NewAddrPatch(cat, next); + } + } while (1); + + return first; +} + +static ObjCInfo *CPrec_GetObjCInfoPatch(ObjCInfo *info) { + ObjCInfo *p = CPrec_AppendAlign(); + CPrec_AppendData(info, sizeof(ObjCInfo)); + + if (info->classobject) + CPrec_NewPointerPatch(&p->classobject, CPrec_GetObjectPatch(info->classobject)); + if (info->metaobject) + CPrec_NewPointerPatch(&p->metaobject, CPrec_GetObjectPatch(info->metaobject)); + if (info->classrefobj) + CPrec_NewPointerPatch(&p->classrefobj, CPrec_GetObjectPatch(info->classrefobj)); + if (info->methods) + CPrec_NewPointerPatch(&p->methods, CPrec_GetObjCMethodPatch(info->methods)); + if (info->protocols) + CPrec_NewPointerPatch(&p->protocols, CPrec_GetObjCProtocolListPatch(info->protocols)); + if (info->categories) + CPrec_NewPointerPatch(&p->categories, CPrec_GetObjCCategoryPatch(info->categories)); + + return p; +} + +static TemplArg *CPrec_GetTemplateArgPatch(TemplArg *arg) { + TemplArg *first, *current, *next; + first = current = CPrec_AppendAlign(); + + do { + CPrec_AppendData(arg, sizeof(TemplArg)); + switch (arg->pid.type) { + case TPT_TYPE: + if (arg->data.typeparam.type) + CPrec_NewPointerPatch(¤t->data.typeparam.type, CPrec_GetTypePatch(arg->data.typeparam.type)); + break; + case TPT_NONTYPE: + if (arg->data.paramdecl.expr) + CPrec_NewPointerPatch(¤t->data.paramdecl.expr, CPrec_GetExpressionPatch(arg->data.paramdecl.expr)); + break; + case TPT_TEMPLATE: + if (arg->data.ttargtype) + CPrec_NewPointerPatch(¤t->data.ttargtype, CPrec_GetTypePatch(arg->data.ttargtype)); + break; + default: +#line 1879 + CError_FATAL(); + } + + if (!arg->next) + break; + next = CPrec_AppendAlign(); + CPrec_NewPointerPatch(¤t->next, next); + current = next; + arg = arg->next; + } while (1); + + return first; +} + +static TemplParam *CPrec_GetTemplateParamPatch(TemplParam *param) { + // register swap issues + TemplParam *first, *current, *next; + first = current = CPrec_AppendAlign(); + + do { + CPrec_AppendData(param, sizeof(TemplParam)); + if (param->name) + CPrec_NamePatch(¤t->name, param->name); + + switch (param->pid.type) { + case TPT_TYPE: + if (param->data.typeparam.type) + CPrec_NewPointerPatch(¤t->data.typeparam.type, CPrec_GetTypePatch(param->data.typeparam.type)); + break; + case TPT_NONTYPE: + CPrec_NewPointerPatch(¤t->data.paramdecl.type, CPrec_GetTypePatch(param->data.paramdecl.type)); + if (param->data.paramdecl.defaultarg) + CPrec_NewPointerPatch(¤t->data.paramdecl.defaultarg, CPrec_GetExpressionPatch(param->data.paramdecl.defaultarg)); + break; + case TPT_TEMPLATE: + if (param->data.templparam.plist) + CPrec_NewPointerPatch(¤t->data.templparam.plist, CPrec_GetTemplateParamPatch(param->data.templparam.plist)); +#line 1953 + CError_ASSERT(!param->data.templparam.defaultarg); + break; + default: +#line 1958 + CError_FATAL(); + } + + if (!param->next) + break; + next = CPrec_AppendAlign(); + CPrec_NewPointerPatch(¤t->next, next); + current = next; + param = param->next; + } while (1); + + return first; +} + +static TStreamElement *CPrec_GetTStreamPatch(TStreamElement *tokens, SInt32 count) { + TStreamElement elem; + TStreamElement *first, *current, *scan; + SInt32 x; + + scan = tokens; + x = 0; + while (x < count) { + elem = *scan; + memclrw(scan, sizeof(TStreamElement)); + + scan->tokentype = elem.tokentype; + switch (elem.tokentype) { + case TK_IDENTIFIER: + scan->data.tkidentifier = elem.data.tkidentifier; + break; + case TK_INTCONST: + scan->subtype = elem.subtype; + scan->data.tkintconst = elem.data.tkintconst; + break; + case TK_FLOATCONST: + scan->subtype = elem.subtype; + scan->data.tkfloatconst = elem.data.tkfloatconst; + break; + case TK_STRING: + case TK_STRING_WIDE: + scan->subtype = elem.subtype; + scan->data.tkstring = elem.data.tkstring; + break; + } + x++; + scan++; + } + + first = current = CPrec_AppendAlign(); + CPrec_AppendData(tokens, count * sizeof(TStreamElement)); + + if (cprec_dowrite) { + TokenPatch *tp = lalloc(sizeof(TokenPatch)); + tp->tokens = current; + tp->count = count; + tp->next = cprec_tokenpatches; + cprec_tokenpatches = tp; + } + + x = 0; + while (x < count) { + switch (tokens->tokentype) { + case TK_IDENTIFIER: + CPrec_NamePatch(¤t->data.tkidentifier, tokens->data.tkidentifier); + break; + case TK_INTCONST: + case TK_FLOATCONST: + break; + case TK_STRING: + case TK_STRING_WIDE: + CPrec_RawMemPatch(¤t->data.tkstring.data, tokens->data.tkstring.data, tokens->data.tkstring.size); + break; + case TK_NEG7: + break; + default: + if (tokens->tokentype < 0) +#line 2063 + CError_FATAL(); + } + x++; + tokens++; + current++; + } + + return first; +} + +static TemplFuncInstance *CPrec_GetTemplFuncInstancePatch(TemplFuncInstance *inst) { + AddrPatch *addrPatch; + TemplFuncInstance *first, *current, *next; + + if ((addrPatch = CPrec_FindAddrPatch(inst))) + return addrPatch->value; + + first = current = CPrec_AppendAlign(); + CPrec_NewAddrPatch(inst, first); + + do { + CPrec_AppendData(inst, sizeof(TemplFuncInstance)); + CPrec_NewPointerPatch(¤t->object, CPrec_GetObjectPatch(inst->object)); + CPrec_NewPointerPatch(¤t->args, CPrec_GetTemplateArgPatch(inst->args)); + + if (!inst->next) + break; + + if ((addrPatch = CPrec_FindAddrPatch(inst->next))) { + CPrec_NewPointerPatch(¤t->next, addrPatch->value); + break; + } else { + next = CPrec_AppendAlign(); + CPrec_NewPointerPatch(¤t->next, next); + current = next; + inst = inst->next; + CPrec_NewAddrPatch(inst, next); + } + } while (1); + + return first; +} + +static TemplateMember *CPrec_GetTemplateMemberPatch(TemplateMember *memb) { + TemplateMember *current, *first, *next; + first = current = CPrec_AppendAlign(); + + do { + memclrw(&memb->fileoffset, sizeof(FileOffsetInfo)); + memb->srcfile = NULL; + memb->startoffset = 0; + memb->endoffset = 0; + + CPrec_AppendData(memb, sizeof(TemplateMember)); + if (memb->params) + CPrec_NewPointerPatch(¤t->params, CPrec_GetTemplateParamPatch(memb->params)); + CPrec_NewPointerPatch(¤t->object, CPrec_GetObjectPatch(memb->object)); + if (memb->stream.firsttoken) + CPrec_NewPointerPatch(¤t->stream.firsttoken, CPrec_GetTStreamPatch(memb->stream.firsttoken, memb->stream.tokens)); + + if (!memb->next) + break; + next = CPrec_AppendAlign(); + CPrec_NewPointerPatch(¤t->next, next); + current = next; + memb = memb->next; + } while (1); + + return first; +} + +static TemplPartialSpec *CPrec_GetTemplPartialSpecPatch(TemplPartialSpec *pspec) { + TemplPartialSpec *first, *current, *next; + first = current = CPrec_AppendAlign(); + + do { + CPrec_AppendData(pspec, sizeof(TemplPartialSpec)); + if (pspec->templ) + CPrec_NewPointerPatch(¤t->templ, CPrec_GetTypePatch((Type *) pspec->templ)); + if (pspec->args) + CPrec_NewPointerPatch(¤t->args, CPrec_GetTemplateArgPatch(pspec->args)); + + if (!pspec->next) + break; + next = CPrec_AppendAlign(); + CPrec_NewPointerPatch(¤t->next, next); + current = next; + pspec = pspec->next; + } while (1); + + return first; +} + +static TemplateFriend *CPrec_GetTemplateFriendPatch(TemplateFriend *frnd) { + TemplateFriend *p; + + memclrw(&frnd->fileoffset, sizeof(FileOffsetInfo)); + p = CPrec_AppendAlign(); + CPrec_AppendData(frnd, sizeof(TemplateFriend)); + + if (frnd->decl.thetype) + CPrec_NewPointerPatch(&p->decl.thetype, CPrec_GetTypePatch(frnd->decl.thetype)); + if (frnd->decl.nspace) + CPrec_NewPointerPatch(&p->decl.nspace, CPrec_GetNameSpacePatch(frnd->decl.nspace)); + if (frnd->decl.name) + CPrec_NamePatch(&p->decl.name, frnd->decl.name); + if (frnd->decl.expltargs) + CPrec_NewPointerPatch(&p->decl.expltargs, CPrec_GetTemplateArgPatch(frnd->decl.expltargs)); + if (frnd->stream.firsttoken) + CPrec_NewPointerPatch(&p->stream.firsttoken, CPrec_GetTStreamPatch(frnd->stream.firsttoken, frnd->stream.tokens)); + + return p; +} + +static TemplateAction *CPrec_GetTemplateActionPatch(TemplateAction *act) { + // register swap issue + TemplateAction *current, *first, *next; + first = current = CPrec_AppendAlign(); + + do { + memclrw(&act->source_ref, sizeof(TStreamElement)); + CPrec_AppendData(act, sizeof(TemplateAction)); + + switch (act->type) { + case TAT_NESTEDCLASS: + CPrec_NewPointerPatch(¤t->u.tclasstype, CPrec_GetTypePatch((Type *) act->u.tclasstype)); + break; + case TAT_ENUMTYPE: + CPrec_NewPointerPatch(¤t->u.enumtype, CPrec_GetTypePatch((Type *) act->u.enumtype)); + break; + case TAT_FRIEND: + CPrec_NewPointerPatch(¤t->u.tfriend, CPrec_GetTemplateFriendPatch(act->u.tfriend)); + break; + case TAT_ENUMERATOR: + CPrec_NewPointerPatch(¤t->u.enumerator.objenumconst, CPrec_GetObjEnumConstPatch(act->u.enumerator.objenumconst)); + if (act->u.enumerator.initexpr) + CPrec_NewPointerPatch(¤t->u.enumerator.initexpr, CPrec_GetExpressionPatch(act->u.enumerator.initexpr)); + break; + case TAT_BASE: + CPrec_NewPointerPatch(¤t->u.base.type, CPrec_GetTypePatch(act->u.base.type)); + if (act->u.base.insert_after) + CPrec_NewPointerPatch(¤t->u.base.insert_after, CPrec_GetClassListPatch(act->u.base.insert_after)); + break; + case TAT_OBJECTINIT: + CPrec_NewPointerPatch(¤t->u.objectinit.object, CPrec_GetObjectPatch(act->u.objectinit.object)); + CPrec_NewPointerPatch(¤t->u.objectinit.initexpr, CPrec_GetExpressionPatch(act->u.objectinit.initexpr)); + break; + case TAT_USINGDECL: + CPrec_NewPointerPatch(¤t->u.usingdecl.type, CPrec_GetTypeTemplDepPatch(act->u.usingdecl.type)); + break; + case TAT_OBJECTDEF: + CPrec_NewPointerPatch(¤t->u.refobj, CPrec_GetObjBasePatch(act->u.refobj)); + break; + default: +#line 2410 + CError_FATAL(); + } + + if (!act->next) + break; + next = CPrec_AppendAlign(); + CPrec_NewPointerPatch(¤t->next, next); + current = next; + act = act->next; + } while (1); + + return first; +} + +static TemplateFunction *CPrec_GetTemplateFunctionPatch(TemplateFunction *tf) { + // the same cursed register swaps + AddrPatch *addrPatch; + TemplateFunction *first, *current, *next; + + if ((addrPatch = CPrec_FindAddrPatch(tf))) + return addrPatch->value; + + first = current = CPrec_AppendAlign(); + CPrec_NewAddrPatch(tf, first); + + do { + memclrw(&tf->deftoken, sizeof(TStreamElement)); + tf->srcfile = NULL; + tf->startoffset = 0; + tf->endoffset = 0; + + CPrec_AppendData(tf, sizeof(TemplateFunction)); + if (tf->unk4) + CPrec_NewPointerPatch(¤t->unk4, CPrec_GetTemplateFunctionPatch(tf->unk4)); + CPrec_NamePatch(¤t->name, tf->name); + if (tf->params) + CPrec_NewPointerPatch(¤t->params, CPrec_GetTemplateParamPatch(tf->params)); + if (tf->stream.firsttoken) + CPrec_NewPointerPatch(¤t->stream.firsttoken, CPrec_GetTStreamPatch(tf->stream.firsttoken, tf->stream.tokens)); + CPrec_NewPointerPatch(¤t->tfunc, CPrec_GetObjectPatch(tf->tfunc)); + if (tf->instances) + CPrec_NewPointerPatch(¤t->instances, CPrec_GetTemplFuncInstancePatch(tf->instances)); + + if (!tf->next) + break; + + if ((addrPatch = CPrec_FindAddrPatch(tf->next))) { + CPrec_NewPointerPatch(¤t->next, addrPatch->value); + break; + } else { + next = CPrec_AppendAlign(); + CPrec_NewPointerPatch(¤t->next, next); + current = next; + tf = tf->next; + CPrec_NewAddrPatch(tf, next); + } + } while (1); + + return first; +} + +static TypeClass *CPrec_GetTypeClassPatch(TypeClass *tclass) { + TypeClass *first, *current, *next; + Boolean hasNextTempl, hasNextTemplInst; + first = current = CPrec_AppendAlign(); + + do_over: + hasNextTempl = hasNextTemplInst = 0; + CPrec_NewAddrPatch(tclass, current); + + if (tclass->flags & CLASS_FLAGS_100) { + // template class + CPrec_AppendData(tclass, sizeof(TemplClass)); + if (TEMPL_CLASS(tclass)->next) + hasNextTempl = 1; + if (TEMPL_CLASS(tclass)->templ__parent) + CPrec_NewPointerPatch(&TEMPL_CLASS(current)->templ__parent, CPrec_GetTypePatch((Type *) TEMPL_CLASS(tclass)->templ__parent)); + if (TEMPL_CLASS(tclass)->x3A_maybe_parentinst) + CPrec_NewPointerPatch(&TEMPL_CLASS(current)->x3A_maybe_parentinst, CPrec_GetTypePatch((Type *) TEMPL_CLASS(tclass)->x3A_maybe_parentinst)); + if (TEMPL_CLASS(tclass)->templ__params) + CPrec_NewPointerPatch(&TEMPL_CLASS(current)->templ__params, CPrec_GetTemplateParamPatch(TEMPL_CLASS(tclass)->templ__params)); + if (TEMPL_CLASS(tclass)->members) + CPrec_NewPointerPatch(&TEMPL_CLASS(current)->members, CPrec_GetTemplateMemberPatch(TEMPL_CLASS(tclass)->members)); + if (TEMPL_CLASS(tclass)->instances) + CPrec_NewPointerPatch(&TEMPL_CLASS(current)->instances, CPrec_GetTypePatch((Type *) TEMPL_CLASS(tclass)->instances)); + if (TEMPL_CLASS(tclass)->pspec_owner) + CPrec_NewPointerPatch(&TEMPL_CLASS(current)->pspec_owner, CPrec_GetTypePatch((Type *) TEMPL_CLASS(tclass)->pspec_owner)); + if (TEMPL_CLASS(tclass)->pspecs) + CPrec_NewPointerPatch(&TEMPL_CLASS(current)->pspecs, CPrec_GetTemplPartialSpecPatch(TEMPL_CLASS(tclass)->pspecs)); + if (TEMPL_CLASS(tclass)->actions) + CPrec_NewPointerPatch(&TEMPL_CLASS(current)->actions, CPrec_GetTemplateActionPatch(TEMPL_CLASS(tclass)->actions)); + } else if (tclass->flags & CLASS_FLAGS_800) { + // template class instance + CPrec_AppendData(tclass, sizeof(TemplClassInst)); + if (TEMPL_CLASS_INST(tclass)->next) + hasNextTemplInst = 1; + if (TEMPL_CLASS_INST(tclass)->x36) + CPrec_NewPointerPatch(&TEMPL_CLASS_INST(current)->x36, CPrec_GetTypePatch((Type *) TEMPL_CLASS_INST(tclass)->x36)); + if (TEMPL_CLASS_INST(tclass)->templ) + CPrec_NewPointerPatch(&TEMPL_CLASS_INST(current)->templ, CPrec_GetTypePatch((Type *) TEMPL_CLASS_INST(tclass)->templ)); + if (TEMPL_CLASS_INST(tclass)->inst_args) + CPrec_NewPointerPatch(&TEMPL_CLASS_INST(current)->inst_args, CPrec_GetTemplateArgPatch(TEMPL_CLASS_INST(tclass)->inst_args)); + if (TEMPL_CLASS_INST(tclass)->oargs) + CPrec_NewPointerPatch(&TEMPL_CLASS_INST(current)->oargs, CPrec_GetTemplateArgPatch(TEMPL_CLASS_INST(tclass)->oargs)); + } else { + // base + CPrec_AppendData(tclass, sizeof(TypeClass)); + } + + if (tclass->nspace) + CPrec_NewPointerPatch(¤t->nspace, CPrec_GetNameSpacePatch(tclass->nspace)); + if (tclass->classname) + CPrec_NamePatch(¤t->classname, tclass->classname); + if (tclass->bases) + CPrec_NewPointerPatch(¤t->bases, CPrec_GetClassListPatch(tclass->bases)); + if (tclass->vbases) + CPrec_NewPointerPatch(¤t->vbases, CPrec_GetVClassListPatch(tclass->vbases)); + if (tclass->ivars) + CPrec_NewPointerPatch(¤t->ivars, CPrec_GetObjMemberVarPatch(tclass->ivars)); + if (tclass->friends) + CPrec_NewPointerPatch(¤t->friends, CPrec_GetClassFriendPatch(tclass->friends)); + if (tclass->vtable) + CPrec_NewPointerPatch(¤t->vtable, CPrec_GetVTablePatch(tclass->vtable)); + if (tclass->sominfo) + CPrec_NewPointerPatch(¤t->sominfo, CPrec_GetSOMInfoPatch(tclass->sominfo)); + if (tclass->objcinfo) + CPrec_NewPointerPatch(¤t->objcinfo, CPrec_GetObjCInfoPatch(tclass->objcinfo)); + + if (hasNextTempl) { + AddrPatch *addrPatch = CPrec_FindAddrPatch(TEMPL_CLASS(tclass)->next); + if (!addrPatch) { + next = CPrec_AppendAlign(); + CPrec_NewPointerPatch(&TEMPL_CLASS(current)->next, next); + current = next; + tclass = (TypeClass *) TEMPL_CLASS(tclass)->next; + goto do_over; + } else { + CPrec_NewPointerPatch(&TEMPL_CLASS(current)->next, addrPatch->value); + } + } + + if (hasNextTemplInst) { + AddrPatch *addrPatch = CPrec_FindAddrPatch(TEMPL_CLASS_INST(tclass)->next); + if (!addrPatch) { + next = CPrec_AppendAlign(); + CPrec_NewPointerPatch(&TEMPL_CLASS_INST(current)->next, next); + current = next; + tclass = (TypeClass *) TEMPL_CLASS_INST(tclass)->next; + goto do_over; + } else { + CPrec_NewPointerPatch(&TEMPL_CLASS_INST(current)->next, addrPatch->value); + } + } + + return first; +} + +static Type *CPrec_GetTypePatch(Type *type) { + AddrPatch *addrPatch = CPrec_FindAddrPatch(type); + if (addrPatch) + return addrPatch->value; + + switch (type->type) { + case TYPEPOINTER: + case TYPEARRAY: + return (Type *) CPrec_GetTypePointerPatch(TYPE_POINTER(type)); + case TYPEENUM: + return (Type *) CPrec_GetTypeEnumPatch(TYPE_ENUM(type)); + case TYPEBITFIELD: + return (Type *) CPrec_GetTypeBitfieldPatch(TYPE_BITFIELD(type)); + case TYPESTRUCT: + return (Type *) CPrec_GetTypeStructPatch(TYPE_STRUCT(type)); + case TYPEFUNC: + return (Type *) CPrec_GetTypeFuncPatch(TYPE_FUNC(type)); + case TYPEMEMBERPOINTER: + return (Type *) CPrec_GetTypeMemberPointerPatch(TYPE_MEMBER_POINTER(type)); + case TYPETEMPLATE: + return (Type *) CPrec_GetTypeTemplDepPatch(TYPE_TEMPLATE(type)); + case TYPECLASS: + return (Type *) CPrec_GetTypeClassPatch(TYPE_CLASS(type)); + case TYPEVOID: + case TYPEINT: + case TYPEFLOAT: + case TYPELABEL: + case TYPEOBJCID: + case TYPETEMPLDEPEXPR: + default: +#line 2796 + CError_FATAL(); + return NULL; + } +} + +static ExceptionAction *CPrec_GetExceptionPatch(ExceptionAction *exc) { + ExceptionAction *first, *current, *next; + + first = current = CPrec_AppendAlign(); +repeat: + CPrec_AppendData(exc, sizeof(ExceptionAction)); + switch (exc->type) { + case EAT_DESTROYLOCAL: + CPrec_NewPointerPatch(¤t->data.destroy_local.dtor, CPrec_GetObjectPatch(exc->data.destroy_local.dtor)); + break; + case EAT_DESTROYLOCALCOND: + CPrec_NewPointerPatch(¤t->data.destroy_local_cond.dtor, CPrec_GetObjectPatch(exc->data.destroy_local_cond.dtor)); + break; + case EAT_DESTROYLOCALOFFSET: + CPrec_NewPointerPatch(¤t->data.destroy_local_offset.dtor, CPrec_GetObjectPatch(exc->data.destroy_local_offset.dtor)); + break; + case EAT_DESTROYLOCALPOINTER: + CPrec_NewPointerPatch(¤t->data.destroy_local_pointer.dtor, CPrec_GetObjectPatch(exc->data.destroy_local_pointer.dtor)); + break; + case EAT_DESTROYLOCALARRAY: + CPrec_NewPointerPatch(¤t->data.destroy_local_array.dtor, CPrec_GetObjectPatch(exc->data.destroy_local_array.dtor)); + break; + case EAT_DESTROYPARTIALARRAY: + break; + case EAT_DESTROYMEMBER: + case EAT_DESTROYBASE: + CPrec_NewPointerPatch(¤t->data.destroy_member.dtor, CPrec_GetObjectPatch(exc->data.destroy_member.dtor)); + break; + case EAT_DESTROYMEMBERCOND: + CPrec_NewPointerPatch(¤t->data.destroy_member_cond.dtor, CPrec_GetObjectPatch(exc->data.destroy_member_cond.dtor)); + break; + case EAT_DESTROYMEMBERARRAY: + CPrec_NewPointerPatch(¤t->data.destroy_member_array.dtor, CPrec_GetObjectPatch(exc->data.destroy_member_array.dtor)); + break; + case EAT_DELETEPOINTER: + case EAT_DELETELOCALPOINTER: + CPrec_NewPointerPatch(¤t->data.delete_pointer.deletefunc, CPrec_GetObjectPatch(exc->data.delete_pointer.deletefunc)); + break; + case EAT_DELETEPOINTERCOND: + CPrec_NewPointerPatch(¤t->data.delete_pointer_cond.deletefunc, CPrec_GetObjectPatch(exc->data.delete_pointer_cond.deletefunc)); + break; + case EAT_CATCHBLOCK: + if (exc->data.catch_block.catch_typeid) { + CPrec_NewPointerPatch(¤t->data.catch_block.catch_typeid, CPrec_GetObjectPatch(exc->data.catch_block.catch_typeid)); + CPrec_NewPointerPatch(¤t->data.catch_block.catch_type, CPrec_GetTypePatch(exc->data.catch_block.catch_type)); + } + break; + case EAT_ACTIVECATCHBLOCK: + break; + case EAT_SPECIFICATION: + if (exc->data.specification.unexp_id) { + int x; + char *ptrs; + ptrs = CPrec_AppendAlign(); + CPrec_NewPointerPatch(¤t->data.specification.unexp_id, ptrs); + CPrec_AppendData(exc->data.specification.unexp_id, sizeof(Object *) * exc->data.specification.unexp_ids); + for (x = 0; x < exc->data.specification.unexp_ids; x++) { + CPrec_NewPointerPatch(ptrs + x * sizeof(Object *), CPrec_GetObjectPatch(exc->data.specification.unexp_id[x])); + } + } + break; + case EAT_TERMINATE: + break; + default: +#line 2905 + CError_FATAL(); + } + + if (exc->prev) { + next = CPrec_AppendAlign(); + CPrec_NewPointerPatch(¤t->prev, next); + current = next; + exc = exc->prev; + goto repeat; + } + return first; +} + +static ENodeList *CPrec_GetExpressionListPatch(ENodeList *lst) { + ENodeList *first, *current, *next; + first = current = CPrec_AppendAlign(); + + do { + CPrec_AppendData(lst, sizeof(ENodeList)); + CPrec_NewPointerPatch(¤t->node, CPrec_GetExpressionPatch(lst->node)); + + if (!lst->next) + break; + next = CPrec_AppendAlign(); + CPrec_NewPointerPatch(¤t->next, next); + current = next; + lst = lst->next; + } while (1); + + return first; +} + +static void CPrec_GetEMemberInfoPatch() {} + +static ENode *CPrec_GetExpressionPatch(ENode *enode) { + +} + +static void CPrec_GetSwitchInfoPatch() {} +static void CPrec_GetInlineAsmPatch() {} +static void CPrec_GetStatementPatch() {} +static void CPrec_GetLocObjectPatch() {} +static void CPrec_GetInlineFuncPatch() {} + +static ObjEnumConst *CPrec_GetObjEnumConstPatch(ObjEnumConst *obj) { + AddrPatch *addrPatch; + ObjEnumConst *first, *current, *next; + + if ((addrPatch = CPrec_FindAddrPatch(obj))) + return addrPatch->value; + + first = current = CPrec_AppendAlign(); + CPrec_NewAddrPatch(obj, first); + + do { + CPrec_AppendData(obj, sizeof(ObjEnumConst)); + if (cprec_dowrite) { +#line 3349 + CError_ASSERT(obj->access != 255); + obj->access = 255; + } + CPrec_NamePatch(¤t->name, obj->name); + CPrec_NewPointerPatch(¤t->type, CPrec_GetTypePatch( obj->type)); + + if (!obj->next) + break; + + if ((addrPatch = CPrec_FindAddrPatch(obj->next))) { + CPrec_NewPointerPatch(¤t->next, addrPatch->value); + break; + } else { + next = CPrec_AppendAlign(); + CPrec_NewPointerPatch(¤t->next, next); + current = next; + obj = obj->next; + CPrec_NewAddrPatch(obj, next); + } + } while (1); + + return first; +} + +static ObjType *CPrec_GetObjTypePatch(ObjType *obj) { + AddrPatch *addrPatch; + ObjType *p; + + if ((addrPatch = CPrec_FindAddrPatch(obj))) + return addrPatch->value; + + p = CPrec_AppendAlign(); + CPrec_NewAddrPatch(obj, p); + CPrec_AppendData(obj, sizeof(ObjType)); + CPrec_NewPointerPatch(&p->type, CPrec_GetTypePatch(obj->type)); + return p; +} + +static ObjTypeTag *CPrec_GetObjTypeTagPatch(ObjTypeTag *obj) { + AddrPatch *addrPatch; + ObjTypeTag *p; + + if ((addrPatch = CPrec_FindAddrPatch(obj))) + return addrPatch->value; + + p = CPrec_AppendAlign(); + CPrec_NewAddrPatch(obj, p); + CPrec_AppendData(obj, sizeof(ObjTypeTag)); + CPrec_NewPointerPatch(&p->type, CPrec_GetTypePatch(obj->type)); + return p; +} + +static ObjNameSpace *CPrec_GetObjNameSpacePatch(ObjNameSpace *obj) { + AddrPatch *addrPatch; + ObjNameSpace *p; + + if ((addrPatch = CPrec_FindAddrPatch(obj))) + return addrPatch->value; + + p = CPrec_AppendAlign(); + CPrec_NewAddrPatch(obj, p); + CPrec_AppendData(obj, sizeof(ObjNameSpace)); + CPrec_NewPointerPatch(&p->nspace, CPrec_GetNameSpacePatch(obj->nspace)); + return p; +} + +static ObjMemberVar *CPrec_GetObjMemberVarPatch(ObjMemberVar *obj) { + +} + +static DefArgCtorInfo *CPrec_GetDefArgCtorInfoPatch(DefArgCtorInfo *dac) { + DefArgCtorInfo *p = CPrec_AppendAlign(); + CPrec_AppendData(dac, sizeof(DefArgCtorInfo)); + CPrec_NewPointerPatch(&p->default_func, CPrec_GetObjectPatch(dac->default_func)); + CPrec_NewPointerPatch(&p->default_arg, CPrec_GetExpressionPatch(dac->default_arg)); + return p; +} + +static InlineXRef *CPrec_GetInlineXRefPatch(InlineXRef *ix) { + InlineXRef *first, *current, *next; + first = current = CPrec_AppendAlign(); + + do { + CPrec_AppendData(ix, sizeof(InlineXRef) + sizeof(XRefOffset) * (ix->numxrefs - 1)); + CPrec_NewPointerPatch(¤t->object, CPrec_GetObjectPatch(ix->object)); + + if (!ix->next) + break; + next = CPrec_AppendAlign(); + CPrec_NewPointerPatch(¤t->next, next); + current = next; + ix = ix->next; + } while (1); + + return first; +} + +static Object *CPrec_GetObjectPatch(Object *o) { + +} + +static ObjBase *CPrec_GetObjBasePatch(ObjBase *obj) { + switch (obj->otype) { + default: +#line 3694 + CError_FATAL(); + case OT_ENUMCONST: + return (ObjBase *) CPrec_GetObjEnumConstPatch((ObjEnumConst *) obj); + case OT_TYPE: + return (ObjBase *) CPrec_GetObjTypePatch((ObjType *) obj); + case OT_TYPETAG: + return (ObjBase *) CPrec_GetObjTypeTagPatch((ObjTypeTag *) obj); + case OT_NAMESPACE: + return (ObjBase *) CPrec_GetObjNameSpacePatch((ObjNameSpace *) obj); + case OT_MEMBERVAR: + return (ObjBase *) CPrec_GetObjMemberVarPatch((ObjMemberVar *) obj); + case OT_OBJECT: + return (ObjBase *) CPrec_GetObjectPatch((Object *) obj); + } +} + +static ObjectList *CPrec_GetObjectListPatch(ObjectList *ol) { + AddrPatch *addrPatch; + ObjectList *first, *current, *next; + + if ((addrPatch = CPrec_FindAddrPatch(ol))) + return addrPatch->value; + + first = current = CPrec_AppendAlign(); + CPrec_NewAddrPatch(ol, first); +restart: + CPrec_AppendData(ol, sizeof(ObjectList)); + CPrec_NewPointerPatch(¤t->object, CPrec_GetObjectPatch(ol->object)); + if (ol->next) { + next = CPrec_AppendAlign(); + CPrec_NewPointerPatch(¤t->next, next); + current = next; + ol = ol->next; + goto restart; + } + + return first; +} + +static NameSpaceObjectList *CPrec_GetNameSpaceObjectListPatch(NameSpaceObjectList *nsol) { + AddrPatch *addrPatch; + NameSpaceObjectList *first, *current, *next; + + if ((addrPatch = CPrec_FindAddrPatch(nsol))) + return addrPatch->value; + + first = current = CPrec_AppendAlign(); + CPrec_NewAddrPatch(nsol, first); + + do { + CPrec_AppendData(nsol, sizeof(NameSpaceObjectList)); + CPrec_NewPointerPatch(¤t->object, CPrec_GetObjBasePatch(nsol->object)); + + if (!nsol->next) + break; + + if ((addrPatch = CPrec_FindAddrPatch(nsol->next))) { + CPrec_NewPointerPatch(¤t->next, addrPatch->value); + break; + } else { + next = CPrec_AppendAlign(); + CPrec_NewPointerPatch(¤t->next, next); + current = next; + nsol = nsol->next; + CPrec_NewAddrPatch(nsol, next); + } + } while (1); + + return first; +} + +static NameSpaceName *CPrec_GetNameSpaceNamePatch(NameSpaceName *nsn, Boolean flag) { + AddrPatch *addrPatch; + NameSpaceName *first, *current, *next; + + if ((addrPatch = CPrec_FindAddrPatch(nsn))) + return addrPatch->value; + + first = current = CPrec_AppendAlign(); + CPrec_NewAddrPatch(nsn, first); + + do { + CPrec_AppendData(nsn, sizeof(NameSpaceName)); + CPrec_NamePatch(¤t->name, nsn->name); + CPrec_NewPointerPatch(¤t->first.object, CPrec_GetObjBasePatch(nsn->first.object)); + if (nsn->first.next) + CPrec_NewPointerPatch(¤t->first.next, CPrec_GetNameSpaceObjectListPatch(nsn->first.next)); + + if (!nsn->next) + break; + + if ((addrPatch = CPrec_FindAddrPatch(nsn->next))) { + CPrec_NewPointerPatch(¤t->next, addrPatch->value); + break; + } else { + next = CPrec_AppendAlign(); + CPrec_NewPointerPatch(¤t->next, next); + current = next; + nsn = nsn->next; + CPrec_NewAddrPatch(nsn, next); + } + } while (!flag || !cprec_dowrite || CPrec_FlushBufferCheck() == noErr); + + return first; +} + +static NameSpaceList *CPrec_GetNameSpaceListPatch(NameSpaceList *nsl) { + NameSpaceList *first, *current, *next; + first = current = CPrec_AppendAlign(); + + do { + CPrec_AppendData(nsl, sizeof(NameSpaceList)); + CPrec_NewPointerPatch(¤t->nspace, CPrec_GetNameSpacePatch(nsl->nspace)); + + if (!nsl->next) + break; + next = CPrec_AppendAlign(); + CPrec_NewPointerPatch(¤t->next, next); + current = next; + nsl = nsl->next; + } while (1); + + return first; +} + +static NameSpace *CPrec_GetNameSpacePatch(NameSpace *nspace) { + NameSpace *p; + AddrPatch *addrPatch; + + if ((addrPatch = CPrec_FindAddrPatch(nspace))) + return addrPatch->value; + + p = CPrec_AppendAlign(); + CPrec_NewAddrPatch(nspace, p); + CPrec_AppendData(nspace, sizeof(NameSpace)); + + if (nspace->parent) + CPrec_NewPointerPatch(&p->parent, CPrec_GetNameSpacePatch(nspace->parent)); + if (nspace->name) + CPrec_NamePatch(&p->name, nspace->name); + if (nspace->usings) + CPrec_NewPointerPatch(&p->usings, CPrec_GetNameSpaceListPatch(nspace->usings)); + if (nspace->theclass) + CPrec_NewPointerPatch(&p->theclass, CPrec_GetTypePatch((Type *) nspace->theclass)); + + if (nspace->is_hash) { + char *hash; + int i; + hash = CPrec_AppendAlign(); + CPrec_NewPointerPatch(&p->data.hash, hash); + CPrec_AppendData(nspace->data.hash, sizeof(NameSpaceName *) * 1024); + for (i = 0; i < 1024; i++) { + if (nspace->data.hash[i]) + CPrec_NewPointerPatch(hash + (i * sizeof(NameSpaceName *)), CPrec_GetNameSpaceNamePatch(nspace->data.hash[i], 0)); + } + } else if (nspace->data.list) { + CPrec_NewPointerPatch(&p->data.list, CPrec_GetNameSpaceNamePatch(nspace->data.list, 0)); + } + + return p; +} + +static void CPrec_DumpRootNameSpace() {} +static void CPrec_GetSOMPatch() {} +static void CPrec_GetOLinkPatch() {} +static void CPrec_GetStaticDataPatch() {} +static void CPrec_GetCallbackPatch() {} +static void CPrec_GetSelHashTablePatch() {} +static void CPrec_GetIExpressionPatch() {} +static void CPrec_GetInlineActionPatch() {} + +static void CPrec_GenerateBuiltinPatches() { + int x; + int y; + Patch *scan; + + for (x = 0; x < cprec_builtins; x++) { + y = 0; + for (scan = cprec_builtin[x].patches; scan; scan = scan->next) + ++y; + + if (y) { + CPrec_AppendWord32(y); + CPrec_AppendWord32(x); + for (scan = cprec_builtin[x].patches; scan; scan = scan->next) + CPrec_AppendWord32(scan->offset); + } + } + + CPrec_AppendWord32(0); +} + +static void CPrec_GenerateTokenStreamPatches() { + TokenPatch *scan; + + for (scan = cprec_tokenpatches; scan; scan = scan->next) { + CPrec_AppendWord32((UInt32) scan->tokens); + CPrec_AppendWord32((UInt32) scan->count); + } + CPrec_AppendWord32(0); +} + +static OSErr CPrec_CompressWrite(const char *data, SInt32 size) { + char buf[2048 + 256]; + OSErr err; + int bufpos = 0; + int blockstart; + int c; + const char *p = data; + const char *end = data + size; + + for (;;) { + if (p < end) { + if (!*p) { + c = 224; + while (!*p && p < end && c < 256) { + c++; + p++; + } + buf[bufpos++] = c - 1; + } else { + blockstart = bufpos++; + c = 0; + while (p < end && c < 224) { + if (!p[0] && !p[1]) { + break; + } else { + buf[bufpos++] = *(p++); + c++; + } + } + buf[blockstart] = c - 1; + } + } + + if (p >= end || bufpos > 2048) { + if ((err = COS_FileWrite(cprec_refnum, buf, bufpos))) + return err; + + if (p >= end) + break; + else + bufpos = 0; + } + } + + return noErr; +} + +static OSErr CPrec_FlushRawBuffer() { + OSErr err; + + if (cprec_dowrite) { + CPrec_AppendAlign(); + cprec_zero_offset += cprec_glist.size; + COS_LockHandle(cprec_glist.data); + err = CPrec_CompressWrite(*cprec_glist.data, cprec_glist.size); + COS_UnlockHandle(cprec_glist.data); + cprec_glist.size = 0; + + return err; + } else { + return noErr; + } +} + +static OSErr CPrec_FlushBufferCheck() { + static SInt32 flushmax; + OSErr err; + + if (cprec_glist.size > flushmax) + flushmax = cprec_glist.size; + + if (cprec_glist.size > 10000) { + err = CPrec_FlushRawBuffer(); + if (err) { + cprec_ioerror = err; + return err; + } + } + + return noErr; +} + +static int CPrec_CompressPatches() { + Patch *scan; + int count; + SInt32 last; + + cprec_glist.size = 0; + + scan = cprec_patch_list; + last = 0; + count = 0; + while (scan) { +#line 4339 + CError_ASSERT((scan->offset & 0x80000001) == 0); + + if ((scan->offset - last) >= -128 && (scan->offset - last) <= 126) + CPrec_AppendByte(((scan->offset - last) >> 1) | 0x80); + else + CPrec_AppendWord32(scan->offset); + + last = scan->offset; + scan = scan->next; + count++; + } + + return count; +} + +static void CPrec_DumpColorSymbolTable() {} + +static OSErr CPrec_FileAlign(short refnum, SInt32 *len) { + OSErr err; + SInt32 n; + char buf[8]; + + n = *len; + if ((n & 7) == 0) + return noErr; + + memclrw(buf, 8); + err = COS_FileWrite(refnum, buf, n = 8 - (n & 7)); + *len += n; + + return err; +} + +static void CPrec_WriteFile() {} + +void PrecompilerWrite() { +} + +static void CPrec_ReadData() {} +static void CPrec_ReadRawBuffer() {} +static void CPrec_RelocateRawBuffer() {} +static void CPrec_RelocateBuiltins() {} +static void CPrec_RelocateTokenStreams() {} +static void CPrec_RelocateMacroTable() {} +static void CPrec_RelocateTable() {} +static void CPrec_RelocateRootNameSpace() {} + +static void CPrec_FixNameIds() { + int i; + HashNameNode *node; + + for (i = 0; i < 2048; i++) { + for (node = name_hash_nodes[i]; node; node = node->next) + node->id = -1; + } +} + +static void CPrec_DefineStaticData() {} + +void PrecompilerRead(short refnum, void *buffer) { +} diff --git a/includes/cmdline.h b/includes/cmdline.h index 2861794..2c40cb1 100644 --- a/includes/cmdline.h +++ b/includes/cmdline.h @@ -1,4 +1,5 @@ -#pragma once +#ifndef CMDLINE_H +#define CMDLINE_H #include "cw_common.h" #include "pref_structs.h" @@ -747,3 +748,5 @@ extern OSErr GetMacFileType(const FSSpec *spec, OSType *mactype); #ifdef __cplusplus } #endif + +#endif diff --git a/includes/common.h b/includes/common.h index b1b5b61..a18f8f6 100644 --- a/includes/common.h +++ b/includes/common.h @@ -1,4 +1,5 @@ -#pragma once +#ifndef ROOT_COMMON_H +#define ROOT_COMMON_H /* * Common imports and Mac OS types @@ -113,7 +114,7 @@ typedef const unsigned char *ConstStr255Param; // XXX: MacTypes.h defines StrLength() which is an inline for C++ and a macro for C // This might be useful? -#ifdef __MWERKS__ +#ifdef __MWERKS__ #pragma options align=mac68k #endif typedef struct Point { @@ -302,3 +303,5 @@ typedef CInfoPBRec *CInfoPBPtr; #ifdef __MWERKS__ #pragma options align=reset #endif + +#endif diff --git a/includes/compiler.h b/includes/compiler.h new file mode 100644 index 0000000..319f95e --- /dev/null +++ b/includes/compiler.h @@ -0,0 +1,880 @@ +#include "compiler/common.h" + +// THESE TYPES ARE NOT YET SORTED +#include "compiler/tokens.h" +#include "compiler/CompilerTools.h" + +#ifdef __MWERKS__ +#pragma options align=mac68k +#endif + +enum { + AlignMode0_Mac68k, + AlignMode1_Mac68k4byte, + AlignMode2_PPC, + AlignMode3_1Byte, + AlignMode4_2Byte, + AlignMode5_4Byte, + AlignMode6_8Byte, + AlignMode7_16Byte, + AlignMode8 +}; + +// not sure how many of these are char and how many are unsigned char or Boolean +typedef struct COpts { + char little_endian; + char codegen_dynamic; + char codegen_pic; + char no_common; + char no_implicit_templates; + char absolutepath; // determines the path written to debug info + char x06; // linker/objgen related + short cpu; + char schedule_cpu; + unsigned char schedule_mode; // may be an enum?? + SInt32 debuglisting; + char profile; + char traceback; + char disable_registers; + char fp_contract; + char no_register_save_helpers; + char ppc_unroll_speculative; + short ppc_unroll_instructions_limit; + short ppc_unroll_factor_limit; + char altivec_model; + UInt8 x1B; // altivec/vrsave related + UInt8 code_alignment; + char x1D; + UInt8 x1E; // some register used in TOC_use_isel + UInt8 gen_fsel; + char ppc_opt_bclr_bcctr; + char use_lmw_stmw; + char report_heap_info; + char misaligned_mem_access; + char switch_tables; + char prepare_compress; + char some_alignment; // used in CMach_AllocationAlignment + char asmsemicolcomment; + char asmpoundcomment; + StringPtr oldprefixname; + short inlinelevel; + int inline_max_size; + int inline_max_total_size; + char inline_bottom_up; + Boolean cplusplus; + Boolean ecplusplus; + char objective_c; + char objc_strict; + char ARM_conform; + char ARM_scoping; + char require_prototypes; + char trigraphs; + char only_std_keywords; + char enumsalwaysint; + char ANSI_strict; + char mpwc_relax; + char mpwc_newline; + char ignore_oldstyle; + char cpp_extensions; + char pointercast_lvalue; + char useRTTI; + char delete_exception; + char _4B; + Boolean oldalignment; + char unsignedchars; + char multibyteaware; + char autoinline; + char defer_codegen; + Boolean direct_to_som; + char som_env_check; + char som_call_opt; + char booltruefalse; + char old_enum_mangler; + char longlong; + char longlong_enums; + char no_tfuncinline; + char _59; + char flat_include; + char syspath_once; + char always_import; + char simple_class_byval; + char wchar_type; + char vbase_ctor_offset; + char vbase_abi_v2; + char def_inherited; + char template_patch; + char template_friends; + char faster_pch_gen; + char array_new_delete; + Boolean dollar_identifiers; + char def_inline_tfuncs; + char arg_dep_lookup; + Boolean simple_prepdump; + char line_prepdump; + char fullpath_prepdump; + char old_mtemplparser; + char suppress_init_code; + char reverse_bitfields; + Boolean c9x; + char float_constants; + char no_static_dtors; + char longlong_prepeval; + char const_strings; + char dumpir; + char experimental; + char gcc_extensions; + char stdc_fp_contract; + char stdc_fenv_access; + char stdc_cx_limitedr; + char old_argmatch; + char optEH; + char optEH2; + char new_mangler; + char microsoft; + Boolean warningerrors; + char pedantic; + char check_header_flags; + Boolean supress_warnings; + Boolean warn_illpragma; + char warn_emptydecl; + char warn_possunwant; + char warn_unusedvar; + char warn_unusedarg; + char warn_extracomma; + char warn_hidevirtual; + char warn_largeargs; + char warn_implicitconv; + char warn_notinlined; + char warn_structclass; + char warn_padding; + char warn_no_side_effect; + char warn_resultnotused; + char warn_ptr_int_conv; + char align_mode; + Boolean align_array_members; + char dont_reuse_strings; + char pool_strings; + char explicit_zero_data; + char readonly_strings; + char exceptions; + char _99; + char dont_inline; + char always_inline; + char peephole; + char global_optimizer; + char side_effects; + char internal; + char import; + char export; + char lib_export; + char nosyminline; + char force_active; + char optimizationlevel; + char optimize_for_size; + char optimizewithasm; + char crippled; + char opt_common_subs; + char opt_loop_invariants; + char opt_propagation; + char opt_dead_assignments; + char opt_strength_reduction; + char opt_strength_reduction_strict; + char opt_dead_code; + char opt_lifetimes; + char _B1; // unused? + char opt_unroll_loops; + char opt_vectorize_loops; + char _B4; // amount of IRO passes? + char opt_pointer_analysis; + char opt_pointer_analysis_mode; + char loop_unroll_count; + char loop_unroll_size_threshold; + char isGeneratingDebugInfo; + CWDataType pchCreator; + CWDataType pchType; + CWDataType text; + HashNameNode *forcedSegment; // when set by #pragma segment +} COpts; + +typedef struct CParams { + CWPluginContext context; + CWObjectData objectdata; + Handle objectDataHandle; + Handle browseDataHandle; + SInt32 pluginRequest; + SInt32 apiVersion; + FSSpec projectFile; + SInt32 projectFileCount; + SInt32 mainFileNumber; + FSSpec mainFileSpec; + const char *mainFileText; + SInt32 mainFileTextLength; + Boolean isPrecompiling; + Boolean isAutoPrecompiling; + Boolean isPreprocessing; + Boolean isGeneratingDebugInfo; + Boolean isCachingPrecompiledHeaders; + CWBrowseOptions browseOptions; + Boolean field276; + SInt16 mainFileID; + CWDataType targetOS; + CWDataType targetCPU; + char *targetName; +} CParams; + + +typedef struct VarInfo { // OK! + Object *func; + SInt32 usage; + TStreamElement deftoken; + SInt16 varnumber; + Boolean noregister; + Boolean used; + UInt8 flags; + UInt8 rclass; + SInt16 reg; + SInt16 regHi; +} VarInfo; + + + +typedef struct DefArgCtorInfo { + Object *default_func; + ENode *default_arg; +} DefArgCtorInfo; + +typedef struct XRefOffset { + UInt32 xrefoffset; + SInt32 offset; +} XRefOffset; + +typedef struct InlineXRef { + struct InlineXRef *next; + Object *object; + UInt16 xrefmode; + UInt16 numxrefs; + XRefOffset xref[1]; +} InlineXRef; + + +typedef enum StatementType { + ST_NOP = 1, + ST_LABEL, + ST_GOTO, + ST_EXPRESSION, + ST_SWITCH, + ST_IFGOTO, + ST_IFNGOTO, + ST_RETURN, + ST_OVF, + ST_EXIT, + ST_ENTRY, + ST_BEGINCATCH, + ST_ENDCATCH, + ST_ENDCATCHDTOR, + ST_GOTOEXPR, + ST_ASM, + ST_BEGINLOOP, + ST_ENDLOOP, + ST_ILLEGAL +} StatementType; + +typedef enum ExceptionActionType { + EAT_NOP, + EAT_DESTROYLOCAL, + EAT_DESTROYLOCALCOND, + EAT_DESTROYLOCALOFFSET, + EAT_DESTROYLOCALPOINTER, + EAT_DESTROYLOCALARRAY, + EAT_DESTROYPARTIALARRAY, + EAT_DESTROYMEMBER, + EAT_DESTROYMEMBERCOND, + EAT_DESTROYMEMBERARRAY, + EAT_DELETEPOINTER, + EAT_DELETELOCALPOINTER, + EAT_DELETEPOINTERCOND, + EAT_CATCHBLOCK, + EAT_ACTIVECATCHBLOCK, + EAT_SPECIFICATION, + EAT_TERMINATE, + EAT_DESTROYBASE, + EAT_NACTIONS +} ExceptionActionType; + +typedef struct ExceptionAction { + struct ExceptionAction *prev; + union { + struct { + Object *local; + Object *dtor; + } destroy_local; + struct { + Object *local; + Object *cond; + Object *dtor; + } destroy_local_cond; + struct { + Object *local; + Object *dtor; + SInt32 offset; + } destroy_local_offset; + struct { + Object *pointer; + Object *dtor; + } destroy_local_pointer; + struct { + Object *localarray; + Object *dtor; + SInt32 elements; + SInt32 element_size; + } destroy_local_array; + struct { + Object *arraypointer; + Object *arraycounter; + Object *dtor; + Object *element_size; + } destroy_partial_array; + struct { + Object *objectptr; + Object *dtor; + SInt32 offset; + } destroy_member; + struct { + Object *objectptr; + Object *cond; + Object *dtor; + SInt32 offset; + } destroy_member_cond; + struct { + Object *objectptr; + Object *dtor; + SInt32 offset; + SInt32 elements; + SInt32 element_size; + } destroy_member_array; + struct { + Object *pointerobject; + Object *deletefunc; + } delete_pointer; + struct { + Object *pointerobject; + Object *deletefunc; + Object *cond; + } delete_pointer_cond; + struct { + Object *catch_object; + Object *catch_info_object; + CLabel *catch_label; + Object *catch_typeid; + Type *catch_type; + UInt32 catch_qual; + } catch_block; + struct { + Object *catch_info_object; + Boolean call_dtor; + } active_catch_block; + struct { + SInt32 unexp_ids; + Object **unexp_id; + CLabel *unexp_label; + Object *unexp_info_object; + } specification; + struct { + Object *object; + Boolean is_dep; + } local; + } data; + ExceptionActionType type; +} ExceptionAction; + +typedef struct Statement { + struct Statement *next; + StatementType type; + char marked; + UInt8 flags; + UInt16 value; + ENode *expr; + CLabel *label; + ExceptionAction *dobjstack; + SInt32 sourceoffset; + HashNameNode *sourcefilepath; +} Statement; + +typedef struct CLabel { + struct CLabel *next; + Statement *stmt; + HashNameNode *uniquename; + HashNameNode *name; + PCodeLabel *pclabel; + void *sicg_label; +} CLabel; + +typedef struct MemInitializer { + struct MemInitializer *next; + union { + ENodeList *nodes; + ENode *expr; + } e; + union { + ObjMemberVar *ivar; + Type *type; + } u; + Boolean is_ivar; + Boolean is_expr; +} MemInitializer; + + +typedef enum DepNameType { + DNT_NAME, + DNT_CONVERSION, + DNT_DTOR, + DNT_NAMESPACE, + DNT_QUALNAME, + DNT_TEMPLATE, + DNT_TYPENAME +} DepNameType; + +typedef struct DepName { + struct DepName *next; + union { + HashNameNode *name; + NameSpace *nspace; + struct { + Type *type; + UInt32 qual; + } conv; + struct { + HashNameNode *name; + TemplArg *args; + } templ; + struct { + HashNameNode *name; + Type *type; + } tname; + } u; + DepNameType type; +} DepName; + + + + + +typedef enum SubKind { + SUBKIND_NAMESPACE, + SUBKIND_TYPE, + SUBKIND_OBJECT +} SubKind; + +typedef struct Substitution { + struct Substitution *next; + union { + NameSpace *nspace; + struct { + Type *type; + UInt32 qual; + } type; + Object *obj; + } u; + int id; + SubKind kind; +} Substitution; + + +// CScope.c +extern Boolean cscope_is_member_func; +extern Object *cscope_currentfunc; +extern TypeClass *cscope_currentclass; +extern NameSpace *cscope_current; +extern NameSpace *cscope_root; + +typedef struct CScopeSave { + NameSpace *current; + TypeClass *currentclass; + Object *currentfunc; + Boolean is_member_func; +} CScopeSave; // assumed name + +typedef struct CScopeParseResult { + NameSpace *nspace_0; + HashNameNode *name_4; + Type *x8; + void *xC; + ObjBase *obj_10; + NameSpaceObjectList *nsol_14; + BClassList *bcl_18; + Boolean x1C; + Boolean x1D; + Boolean isambig; + Boolean x1F; + Boolean x20; + Boolean x21; +} CScopeParseResult; + +typedef struct CScopeNSIterator { + NameSpace *nspace; + NameSpaceLookupList *lookup; + CScopeParseResult *result; +} CScopeNSIterator; + +typedef struct CScopeObjectIterator { + NameSpace *nspace; + NameSpaceName *nextname; + NameSpaceObjectList *currlist; + int hashindex; +} CScopeObjectIterator; + +extern void CScope_Setup(); +extern void CScope_Cleanup(); +extern void CScope_GetScope(CScopeSave *save); +extern void CScope_SetNameSpaceScope(NameSpace *nspace, CScopeSave *save); +extern void CScope_SetClassScope(TypeClass *cls, CScopeSave *save); +extern void CScope_SetClassDefScope(TypeClass *cls, CScopeSave *save); +extern void CScope_SetFunctionScope(Object *function, CScopeSave *save); +extern void CScope_SetMethodScope(Object *function, TypeClass *cls, Boolean unknownFlag, CScopeSave *save); +extern void CScope_RestoreScope(CScopeSave *saved); +extern Boolean CScope_IsEmptySymTable(); +extern Boolean CScope_IsInLocalNameSpace(NameSpace *nspace); +extern NameSpaceObjectList *CScope_FindName(NameSpace *nspace, HashNameNode *name); +extern NameSpaceName *CScope_FindNameSpaceName(NameSpace *nspace, HashNameNode *name); +extern NameSpaceObjectList *CScope_InsertName(NameSpace *nspace, HashNameNode *name); +extern NameSpaceObjectList *CScope_ArgumentDependentNameLookup(NameSpaceObjectList *list, HashNameNode *name, ENodeList *argNodes, Boolean flag); +extern NameSpace *CScope_NewHashNameSpace(HashNameNode *name); +extern NameSpace *CScope_NewListNameSpace(HashNameNode *name, Boolean is_global); +extern NameSpace *CScope_FindNonClassNonFunctionNS(NameSpace *nspace); +extern NameSpace *CScope_FindGlobalNS(NameSpace *nspoce); +extern Boolean CScope_IsStdNameSpace(NameSpace *nspace); +extern Boolean CScope_IsEmptyNameSpace(NameSpace *nspace); +extern void CScope_MergeNameSpace(NameSpace *dst, NameSpace *src); +extern void CScope_AddObject(NameSpace *nspace, HashNameNode *name, ObjBase *obj); +extern void CScope_AddGlobalObject(Object *obj); +extern NameSpaceLookupList *CScope_BuildNameSpaceLookupList(NameSpace *nspace); +extern Boolean CScope_FindQualifiedClassMember(CScopeParseResult *result, TypeClass *tclass, HashNameNode *name); +extern Type *CScope_GetType(NameSpace *nspace, HashNameNode *name, void **unk6); +extern Type *CScope_GetTagType(NameSpace *nspace, HashNameNode *name); +extern Boolean CScope_ParseExprName(CScopeParseResult *result); +extern Boolean CScope_ParseDeclName(CScopeParseResult *result); +extern Boolean CScope_ParseQualifiedNameSpace(CScopeParseResult *result, Boolean flag1, Boolean flag2); +extern Boolean CScope_ParseElaborateName(CScopeParseResult *result); +extern Boolean CScope_FindObject(NameSpace *nspace, CScopeParseResult *result, HashNameNode *name); +extern Boolean CScope_FindNonClassObject(NameSpace *nspace, CScopeParseResult *result, HashNameNode *name); +extern NameSpaceObjectList *CScope_FindObjectList(CScopeParseResult *result, HashNameNode *name); +extern Boolean CScope_PossibleTypeName(HashNameNode *name); +extern Boolean CScope_FindClassMemberObject(TypeClass *tclass, CScopeParseResult *result, HashNameNode *name); +extern void CScope_InitObjectIterator(CScopeObjectIterator *iterator, NameSpace *nspace); +extern ObjBase *CScope_NextObjectIteratorObject(CScopeObjectIterator *iterator); +extern NameSpaceObjectList *CScope_NextObjectIteratorObjectList(CScopeObjectIterator *iterator); +extern void CScope_DefineTypeTag(NameSpace *nspace, HashNameNode *name, Type *type); +extern Type *CScope_GetLocalTagType(NameSpace *nspace, HashNameNode *name); +extern Boolean CScope_FindTypeName(NameSpace *nspace, HashNameNode *name, CScopeParseResult *result); +extern NameSpaceObjectList *CScope_GetLocalObject(NameSpace *nspace, HashNameNode *name); +extern BClassList *CScope_GetClassAccessPath(BClassList *list, TypeClass *tclass); +extern Boolean CScope_ParseMemberName(TypeClass *tclass, CScopeParseResult *result, Boolean flag); +extern void CScope_AddClassUsingDeclaration(TypeClass *tclass, TypeClass *tclass2, HashNameNode *name, AccessType access); +extern void CScope_ParseUsingDeclaration(NameSpace *nspace, AccessType access); +extern void CScope_ParseNameSpaceAlias(HashNameNode *name); +extern void CScope_ParseUsingDirective(NameSpace *nspace); + +// CMachine.c +extern TypeIntegral stbool; +extern TypeIntegral stchar; +extern TypeIntegral stsignedchar; +extern TypeIntegral stunsignedchar; +extern TypeIntegral stwchar; +extern TypeIntegral stsignedshort; +extern TypeIntegral stunsignedshort; +extern TypeIntegral stsignedint; +extern TypeIntegral stunsignedint; +extern TypeIntegral stsignedlong; +extern TypeIntegral stunsignedlong; +extern TypeIntegral stsignedlonglong; +extern TypeIntegral stunsignedlonglong; +extern TypeIntegral stfloat; +extern TypeIntegral stshortdouble; +extern TypeIntegral stdouble; +extern TypeIntegral stlongdouble; + +extern TypeStruct stvectorunsignedchar; +extern TypeStruct stvectorsignedchar; +extern TypeStruct stvectorboolchar; +extern TypeStruct stvectorunsignedshort; +extern TypeStruct stvectorsignedshort; +extern TypeStruct stvectorboolshort; +extern TypeStruct stvectorunsignedlong; +extern TypeStruct stvectorsignedlong; +extern TypeStruct stvectorboollong; +extern TypeStruct stvectorfloat; +extern TypeStruct stvectorpixel; +extern TypeStruct stvector; + +extern void CMach_Configure(); +extern SInt32 CMach_GetQUALalign(UInt32 qual); +extern SInt32 CMach_ArgumentAlignment(Type *type); +extern SInt32 CMach_AllocationAlignment(Type *type, UInt32 qual); +extern CInt64 CMach_CalcIntDiadic(Type *type, CInt64 left, short op, CInt64 right); +extern CInt64 CMach_CalcIntMonadic(Type *type, short op, CInt64 val); +extern CInt64 CMach_CalcIntConvertFromFloat(Type *type, Float fval); +extern void CMach_InitIntMem(Type *type, CInt64 val, void *mem); +extern void CMach_InitVectorMem(Type *type, MWVector128 val, void *mem); +extern Float CMach_CalcFloatDiadic(Type *type, Float left, short op, Float right); +extern Float CMach_CalcFloatMonadic(Type *type, short op, Float fval); +extern Boolean CMach_CalcFloatDiadicBool(Type *type, Float left, short op, Float right); +extern Boolean CMach_CalcVectorDiadicBool(Type *type, MWVector128 *left, short op, MWVector128 *right); +extern char *CMach_FloatScan(char *input, Float *result, Boolean *fail); +extern Float CMach_CalcFloatConvertFromInt(Type *type, CInt64 val); +extern Float CMach_CalcFloatConvert(Type *type, Float fval); +extern Boolean CMach_FloatIsZero(Float fval); +extern Boolean CMach_FloatIsOne(Float fval); +extern Boolean CMach_FloatIsNegOne(Float fval); +extern void CMach_InitFloatMem(Type *type, Float val, void *mem); +extern void CMach_PrintFloat(char *buf, Float val); +extern void CMach_PragmaParams(); +extern void CMach_AdjustFuntionArgs(); +extern SInt16 CMach_GetStructAlign(TypeStruct *tstruct); +extern SInt16 CMach_GetClassAlign(TypeClass *tclass); +extern SInt16 CMach_GetTypeAlign(Type *type); +extern SInt16 CMach_MemberAlignValue(Type *type, SInt32 var); +extern void CMach_StructLayoutInitOffset(SInt32 offset); +extern SInt32 CMach_StructLayoutGetCurSize(); +extern SInt32 CMach_StructLayoutGetOffset(Type *type, UInt32 qual); +extern SInt32 CMach_StructLayoutBitfield(TypeBitfield *tbitfield, UInt32 qual); +extern UInt8 CMach_GetFunctionResultClass(TypeFunc *tfunc); +extern Boolean CMach_PassResultInHiddenArg(Type *type); +extern const char *CMach_GetCPU(); +extern Boolean CMach_FloatIsPowerOf2(Float flt); +extern Float CMach_FloatReciprocal(Float flt); +extern SInt32 CMach_RoundedSizeOf(Object *object); +extern void CMach_ReInitRuntimeObjects(); + +// CPrep.c +typedef struct Macro { + struct Macro *next; + HashNameNode *name; + void *c; + Boolean xC; + Boolean xD; + Boolean is_special; + Boolean xF; + void *e; +} Macro; +typedef struct TokenStack { + char *pos; + char *macrostart; + Macro *macro; + Boolean macrocheck; +} TokenStack; + +extern CParams *cparamblkptr; +extern short tk; +extern CInt64 tkintconst; +extern Float tkfloatconst; +extern char *tkstring; +extern HashNameNode *tkidentifier; +extern SInt32 tksize; +extern short ispascalstring; +extern short nlflag; +extern SInt32 lines; +extern Boolean spaceskip; +extern struct Macro **macrohashtable; +extern Boolean cprep_nomem_exit; +extern Boolean cprep_nostring; +extern Boolean cprep_eoltokens; +extern TokenStack tokenstack[128]; +extern short tokenstacklevel; +extern SInt32 cprep_cursymfile; // might be a ptr? +extern char *pos; +extern char *macropos; +extern char *nextcharpos; +extern char CPrep_SkipNewCommentChar; +extern Boolean preprocessing_only; +extern Handle stringmem; +extern SInt32 maxstringsize; +extern char cprep_idarray[256]; +extern Boolean was_escchar; +extern Boolean macrocheck; +extern Boolean widestring; +extern Boolean at_linestart; +extern char *prep_file_start; +extern char *prep_file_end; +extern char *macrostart; +extern Boolean cprep_strconcat; +extern CPrepFileInfo *prep_file; +extern short filesp; +extern SInt32 linenumber; +extern GList pplist; +extern TStreamElement *ts_current; +extern SInt32 ts_preread_elements; + +extern void CPrep_InsertSpecialMacro(Macro *macro, char *name); +extern void CPrep_InsertSpecialMacros(); +extern void CPrep_RemoveSpecialMacros(); +extern Boolean setupprep(); +extern void cleanupprep(); +extern void CPrep_TSBufferGrow(int amount); +extern void CPrep_TokenStreamGetState(SInt32 *state); +extern void CPrep_TokenStreamSetState(SInt32 *state); +extern void CPrep_UnLex(); +extern void CPrep_TokenStreamSetCurState(SInt32 *state); +extern void CPrep_StreamGetBlock(); +extern void CPrep_StreamGetSemicolon(); +extern void CPrep_StreamGetTemplate(); +extern void CPrep_StreamInsert(); +extern void CPrep_StreamRemove(); +extern void CPrep_RemoveTokens(); +extern void CPrep_TokenStreamFlush(); +extern void CPrep_CurStreamElement(); +extern void CPrep_GetTokenContext(TStreamElement *token, CPrepFileInfo **tokenfile, SInt32 *selectionoffset, short *tokensize, SInt32 *linenumber, char *buf1, short *tokenoffset, short *tokenlength, char *buf2, short *lastarg); +extern void CPrep_Error(short code); +extern void CPrep_ErrorName(short code, const char *name); +extern void CPrep_Warning(short code); +extern void CPrep_WarningName(short code, const char *name); +extern void CPrep_ErrorMessage(int errTable, char *str, Boolean flag1, Boolean flag2); +extern void CPrep_ErrorMessageVA(int code, const char *format, va_list list, Boolean flag1, Boolean flag2); +extern void popfile(); +extern void CPrep_SetSourceFile(); +extern void CPrep_GetSourceFilePath(); +extern void CPrep_NewFileOffsetInfo(); +extern void CPrep_GetFileOffsetInfo(); +extern void CPrep_GetFileOffsetInfo2(); +extern void CPrep_ResetFileInfo(); +extern void CPrep_GetPrepPos(); +extern Boolean C_Compiler(CParams *param); +extern void poptokenseq(); +extern void foundnl(); +extern void newline(); +extern short notendofline(); +extern char *CPrep_GetFileName(char *buffer, Boolean flag1, Boolean flag2); +extern void macrotest(); +extern void CPrep_PragmaLex(); +extern void CPrep_PushOption(); +extern void CPrep_PopOption(); +extern void preprocessor(); +extern void CPrep_BrowserTokenOffset(); +extern void CPrep_BrowserFileOffset(); +extern void CPrep_BrowserFilePosition(CPrepFileInfo **fileinfo, SInt32 *offset); +extern CPrepFileInfo *CPrep_BrowserCurrentFile(); + +// CPrepTokenizer.c +extern short prepskipnextchar(); +extern short prepnextchar(); +extern short prepnextstringchar(char *str, Boolean flag); +extern void CPrep_MatchChar(char ch, Boolean flag); +extern char *CPrep_MatchChar2(char *str, char ch, Boolean flag); +extern short prepcurchar(); +extern char *ReadIdentifier(char *str); +extern char *CPrep_SkipNewComment(char *str); +extern Boolean skipendoflinematch(char *str, Boolean flag); +extern void skipendofline(); +extern void CPrep_SkipAsmComment(); +extern short lookahead(); +extern short lookahead_noeol(); +extern short lex(); +extern short plex(); +extern short lexidentifier(); + +// LOOSE DECLS +extern Boolean C_Compiler(CParams *param); +extern void PrecompilerRead(short refnum, void *buffer); +extern void CodeGen_InitCompiler(); +extern void CodeGen_TermCompiler(); +extern void CodeGen_InitBackEndOptions(); +extern void CodeGen_UpdateOptimizerOptions(); +extern void CodeGen_UpdateBackEndOptions(); +extern void MWUnmangle(const char *name, char *buf, int size); +extern COpts copts; +extern CParams *cparamblkptr; +extern FuncArg elipsis; +extern FuncArg oldstyle; +extern HashNameNode *constructor_name_node; +extern HashNameNode *destructor_name_node; +extern char *CMangler_GetOperator(HashNameNode *str); +extern jmp_buf errorreturn; +extern Boolean cprep_nomem_exit; +extern Boolean anyerrors; +extern Boolean fatalerrors; +extern SInt32 lines; +extern char string[256]; +extern TemplStack *ctempl_curinstance; +typedef struct ParserTryBlock { + struct ParserTryBlock *next; + jmp_buf jmpbuf; + NameSpace *cscope_current; + TypeClass *cscope_currentclass; + Object *cscope_currentfunc; + TemplStack *ctempl_curinstance; + TStreamElement *cerror_locktoken; + Boolean cscope_is_member_func; +} ParserTryBlock; +extern ParserTryBlock *trychain; +extern Boolean in_assembler; +extern Boolean preprocessing_only; +extern void AssemblerError(); +#include "compiler/types.h" +extern short tk; +extern HashNameNode *tkidentifier; +extern short lex(); +extern short notendofline(); +extern short lookahead(); +extern Object *CClass_Constructor(TypeClass *tclass); +extern Object *CClass_Destructor(TypeClass *tclass); +extern int CClass_CheckPures(TypeClass *tclass); +extern Boolean CParser_IsPublicRuntimeObject(Object *obj); +extern Boolean CParser_ParseOperatorName(short *token, Boolean flag1, Boolean flag2); +extern Boolean CTemplTool_EqualArgs(TemplArg *a, TemplArg *b); +extern TypeTemplDep *CDecl_NewTemplDepType(TypeTemplDepType tdtype); +extern GList name_mangle_list; +extern void CPrep_UnLex(); +extern Type *CTempl_ClassGetType(TypeClass *tclass); +extern short is_typesame(Type *t1, Type *t2); +extern Boolean is_unsigned(Type *type); +extern void CDecl_CompleteType(Type *type); +extern TemplArg *CTempl_ParseUncheckTemplArgs(void *fixmelater, Boolean flag); +extern SInt32 CClass_VirtualBaseOffset(TypeClass *tclass, TypeClass *base); +extern Boolean CClass_IsMoreAccessiblePath(BClassList *a, BClassList *b); +extern Boolean CClass_ClassDominates(TypeClass *a, TypeClass *b); +extern Boolean CParser_CheckTemplateClassUsage(TemplClass *tmclass, Boolean flag); +extern Type *CTempl_ParseTemplTemplParam(Type *t); +extern void CClass_CheckPathAccess(BClassList *bcl, void *unk, AccessType access); +extern BClassList *CClass_GetPathCopy(BClassList *path, Boolean flag); +extern AccessType global_access; +extern UInt32 CParser_GetTypeQualifiers(Type *type, UInt32 qual); +extern void CTemplClass_RegisterUsingDecl(TemplClass *tclass, Type *target, AccessType access); +extern void CodeGen_InsertSpecialMacros(); +extern char *CodeGen_ExpandSpecialMacro(Macro *macro); +extern void CPrep_PreprocessDumpFileInfo(Boolean flag); +extern Boolean gForceSourceLoc; +extern void ObjGen_SegmentName(); // might take an arg, not sure since it's empty + +enum { + CPU_PPC401, + CPU_PPC403, + CPU_PPC505, + CPU_PPC509, + CPU_PPC555, + CPU_PPC601, + CPU_PPC602, + CPU_PPC603, + CPU_PPC603e, + CPU_PPC604, + CPU_PPC604e, + CPU_PPC740, + CPU_PPC750, + CPU_PPC801, + CPU_PPC821, + CPU_PPC823, + CPU_PPC850, + CPU_PPC860, + CPU_PPC8240, + CPU_PPC8260, + CPU_PPC7400 = 0x15, + CPU_PPCGEKKO, + CPU_PPCELF, + CPU_PPC7450, + CPU_PPC556, + CPU_PPC565 +}; + +extern char *ScanFloat(char *input, double *output, Boolean *fail); + +#ifdef __MWERKS__ +#pragma options align=reset +#endif diff --git a/includes/compiler/CError.h b/includes/compiler/CError.h new file mode 100644 index 0000000..89f67e4 --- /dev/null +++ b/includes/compiler/CError.h @@ -0,0 +1,364 @@ +#ifndef COMPILER_CERROR_H +#define COMPILER_CERROR_H + +#include "compiler/common.h" + +#define CError_ASSERT(cond) if (!(cond)) { CError_Internal(__FILE__, __LINE__); } +#define CError_FAIL(cond) if (cond) { CError_Internal(__FILE__, __LINE__); } +#define CError_FATAL() do { CError_Internal(__FILE__, __LINE__); } while (0) + +enum { + CErrorStr100 = 100, + CErrorStr101 = 101, + CErrorStr102 = 102, + CErrorStr103 = 103, + CErrorStr104 = 104, + CErrorStr105 = 105, + CErrorStr106 = 106, + CErrorStr107 = 107, + CErrorStr108 = 108, + CErrorStr109 = 109, + CErrorStr110 = 110, + CErrorStr111 = 111, + CErrorStr112 = 112, + CErrorStr113 = 113, + CErrorStr114 = 114, + CErrorStr115 = 115, + CErrorStr116 = 116, + CErrorStr117 = 117, + CErrorStr118 = 118, + CErrorStr119 = 119, + CErrorStr120 = 120, + CErrorStr121 = 121, + CErrorStr122 = 122, + CErrorStr123 = 123, + CErrorStr124 = 124, + CErrorStr125 = 125, + CErrorStr126 = 126, + CErrorStr127 = 127, + CErrorStr128 = 128, + CErrorStr129 = 129, + CErrorStr130 = 130, + CErrorStr131 = 131, + CErrorStr132 = 132, + CErrorStr133 = 133, + CErrorStr134 = 134, + CErrorStr135 = 135, + CErrorStr136 = 136, + CErrorStr137 = 137, + CErrorStr138 = 138, + CErrorStr139 = 139, + CErrorStr140 = 140, + CErrorStr141 = 141, + CErrorStr142 = 142, + CErrorStr143 = 143, + CErrorStr144 = 144, + CErrorStr145 = 145, + CErrorStr146 = 146, + CErrorStr147 = 147, + CErrorStr148 = 148, + CErrorStr149 = 149, + CErrorStr150 = 150, + CErrorStr151 = 151, + CErrorStr152 = 152, + CErrorStr153 = 153, + CErrorStr154 = 154, + CErrorStr155 = 155, + CErrorStr156 = 156, + CErrorStr157 = 157, + CErrorStr158 = 158, + CErrorStr159 = 159, + CErrorStr160 = 160, + CErrorStr161 = 161, + CErrorStr162 = 162, + CErrorStr163 = 163, + CErrorStr164 = 164, + CErrorStr165 = 165, + CErrorStr166 = 166, + CErrorStr167 = 167, + CErrorStr168 = 168, + CErrorStr169 = 169, + CErrorStr170 = 170, + CErrorStr171 = 171, + CErrorStr172 = 172, + CErrorStr173 = 173, + CErrorStr174 = 174, + CErrorStr175 = 175, + CErrorStr176 = 176, + CErrorStr177 = 177, + CErrorStr178 = 178, + CErrorStr179 = 179, + CErrorStr180 = 180, + CErrorStr181 = 181, + CErrorStr182 = 182, + CErrorStr183 = 183, + CErrorStr184 = 184, + CErrorStr185 = 185, + CErrorStr186 = 186, + CErrorStr187 = 187, + CErrorStr188 = 188, + CErrorStr189 = 189, + CErrorStr190 = 190, + CErrorStr191 = 191, + CErrorStr192 = 192, + CErrorStr193 = 193, + CErrorStr194 = 194, + CErrorStr195 = 195, + CErrorStr196 = 196, + CErrorStr197 = 197, + CErrorStr198 = 198, + CErrorStr199 = 199, + CErrorStr200 = 200, + CErrorStr201 = 201, + CErrorStr202 = 202, + CErrorStr203 = 203, + CErrorStr204 = 204, + CErrorStr205 = 205, + CErrorStr206 = 206, + CErrorStr207 = 207, + CErrorStr208 = 208, + CErrorStr209 = 209, + CErrorStr210 = 210, + CErrorStr211 = 211, + CErrorStr212 = 212, + CErrorStr213 = 213, + CErrorStr214 = 214, + CErrorStr215 = 215, + CErrorStr216 = 216, + CErrorStr217 = 217, + CErrorStr218 = 218, + CErrorStr219 = 219, + CErrorStr220 = 220, + CErrorStr221 = 221, + CErrorStr222 = 222, + CErrorStr223 = 223, + CErrorStr224 = 224, + CErrorStr225 = 225, + CErrorStr226 = 226, + CErrorStr227 = 227, + CErrorStr228 = 228, + CErrorStr229 = 229, + CErrorStr230 = 230, + CErrorStr231 = 231, + CErrorStr232 = 232, + CErrorStr233 = 233, + CErrorStr234 = 234, + CErrorStr235 = 235, + CErrorStr236 = 236, + CErrorStr237 = 237, + CErrorStr238 = 238, + CErrorStr239 = 239, + CErrorStr240 = 240, + CErrorStr241 = 241, + CErrorStr242 = 242, + CErrorStr243 = 243, + CErrorStr244 = 244, + CErrorStr245 = 245, + CErrorStr246 = 246, + CErrorStr247 = 247, + CErrorStr248 = 248, + CErrorStr249 = 249, + CErrorStr250 = 250, + CErrorStr251 = 251, + CErrorStr252 = 252, + CErrorStr253 = 253, + CErrorStr254 = 254, + CErrorStr255 = 255, + CErrorStr256 = 256, + CErrorStr257 = 257, + CErrorStr258 = 258, + CErrorStr259 = 259, + CErrorStr260 = 260, + CErrorStr261 = 261, + CErrorStr262 = 262, + CErrorStr263 = 263, + CErrorStr264 = 264, + CErrorStr265 = 265, + CErrorStr266 = 266, + CErrorStr267 = 267, + CErrorStr268 = 268, + CErrorStr269 = 269, + CErrorStr270 = 270, + CErrorStr271 = 271, + CErrorStr272 = 272, + CErrorStr273 = 273, + CErrorStr274 = 274, + CErrorStr275 = 275, + CErrorStr276 = 276, + CErrorStr277 = 277, + CErrorStr278 = 278, + CErrorStr279 = 279, + CErrorStr280 = 280, + CErrorStr281 = 281, + CErrorStr282 = 282, + CErrorStr283 = 283, + CErrorStr284 = 284, + CErrorStr285 = 285, + CErrorStr286 = 286, + CErrorStr287 = 287, + CErrorStr288 = 288, + CErrorStr289 = 289, + CErrorStr290 = 290, + CErrorStr291 = 291, + CErrorStr292 = 292, + CErrorStr293 = 293, + CErrorStr294 = 294, + CErrorStr295 = 295, + CErrorStr296 = 296, + CErrorStr297 = 297, + CErrorStr298 = 298, + CErrorStr299 = 299, + CErrorStr300 = 300, + CErrorStr301 = 301, + CErrorStr302 = 302, + CErrorStr303 = 303, + CErrorStr304 = 304, + CErrorStr305 = 305, + CErrorStr306 = 306, + CErrorStr307 = 307, + CErrorStr308 = 308, + CErrorStr309 = 309, + CErrorStr310 = 310, + CErrorStr311 = 311, + CErrorStr312 = 312, + CErrorStr313 = 313, + CErrorStr314 = 314, + CErrorStr315 = 315, + CErrorStr316 = 316, + CErrorStr317 = 317, + CErrorStr318 = 318, + CErrorStr319 = 319, + CErrorStr320 = 320, + CErrorStr321 = 321, + CErrorStr322 = 322, + CErrorStr323 = 323, + CErrorStr324 = 324, + CErrorStr325 = 325, + CErrorStr326 = 326, + CErrorStr327 = 327, + CErrorStr328 = 328, + CErrorStr329 = 329, + CErrorStr330 = 330, + CErrorStr331 = 331, + CErrorStr332 = 332, + CErrorStr333 = 333, + CErrorStr334 = 334, + CErrorStr335 = 335, + CErrorStr336 = 336, + CErrorStr337 = 337, + CErrorStr338 = 338, + CErrorStr339 = 339, + CErrorStr340 = 340, + CErrorStr341 = 341, + CErrorStr342 = 342, + CErrorStr343 = 343, + CErrorStr344 = 344, + CErrorStr345 = 345, + CErrorStr346 = 346, + CErrorStr347 = 347, + CErrorStr348 = 348, + CErrorStr349 = 349, + CErrorStr350 = 350, + CErrorStr351 = 351, + CErrorStr352 = 352, + CErrorStr353 = 353, + CErrorStr354 = 354, + CErrorStr355 = 355, + CErrorStr356 = 356, + CErrorStr357 = 357, + CErrorStr358 = 358, + CErrorStr359 = 359, + CErrorStr360 = 360, + CErrorStr361 = 361, + CErrorStr362 = 362, + CErrorStr363 = 363, + CErrorStr364 = 364, + CErrorStr365 = 365, + CErrorStr366 = 366, + CErrorStr367 = 367, + CErrorStr368 = 368, + CErrorStr369 = 369, + CErrorStr370 = 370, + CErrorStr371 = 371, + CErrorStr372 = 372, + CErrorStr373 = 373, + CErrorStr374 = 374, + CErrorStr375 = 375, + CErrorStr376 = 376, + CErrorStr377 = 377, + CErrorStr378 = 378, + CErrorStr379 = 379, + CErrorStr380 = 380, + CErrorStr381 = 381, + CErrorStr382 = 382, + CErrorStr383 = 383, + CErrorStr384 = 384, + CErrorStr385 = 385, + CErrorStr386 = 386, + CErrorStr387 = 387, + CErrorStr388 = 388, + CErrorStr389 = 389, + CErrorStr390 = 390, + CErrorStr391 = 391, + CErrorStr392 = 392, + CErrorStrMAX = 393 +}; + +typedef struct _CErrorBuffer { + char *start; + char *end; + UInt32 size; + UInt32 remaining; +} CErrorBuffer; + +extern void CError_Init(); +extern void CError_SetErrorToken(TStreamElement *token); +extern void CError_SetNullErrorToken(); +extern void CError_LockErrorPos(TStreamElement *token, TStreamElement **saved); +extern void CError_UnlockErrorPos(TStreamElement **saved); +extern void CError_ResetErrorSkip(); +extern void CError_GetErrorString(char *buf, short code); +extern void CError_BufferInit(CErrorBuffer *eb, char *buf, SInt32 bufSize); +extern void CError_BufferGrow(CErrorBuffer *eb, SInt32 amount); +extern void CError_BufferAppendChar(CErrorBuffer *eb, char ch); +extern void CError_BufferAppendString(CErrorBuffer *eb, const char *str); +extern void CError_BufferTerminate(CErrorBuffer *eb); +extern void CError_BufferAppendQualifier(CErrorBuffer *eb, UInt32 qual); +extern void CError_BufferAppendTemplArgExpr(CErrorBuffer *eb, ENode *node); +extern void CError_BufferAppendTemplArg(CErrorBuffer *eb, TemplArg *targ); +extern void CError_BufferAppendTemplArgs(CErrorBuffer *eb, TemplArg *targs); +extern void CError_BufferAppendNameSpace(CErrorBuffer *eb, NameSpace *nspace); +extern void CError_BufferAppendPType(CErrorBuffer *eb, Type *ty); +extern void CError_BufferAppendTemplDepType(CErrorBuffer *eb, TypeTemplDep *type); +extern void CError_BufferAppendFuncArgs(CErrorBuffer *eb, TypeFunc *tfunc, Boolean isMethod); +extern void CError_BufferAppendType(CErrorBuffer *eb, Type *ty, UInt32 qual); +extern char *CError_GetTypeName(Type *ty, UInt32 qual, Boolean useGlobalHeap); +extern void CError_AppendUnqualFunctionName(CErrorBuffer *eb, NameSpace *nspace, HashNameNode *name, TypeFunc *tfunc); +extern void CError_AppendFunctionName(CErrorBuffer *eb, NameSpace *nspace, HashNameNode *name, TemplArg *templargs, TypeFunc *tfunc); +extern void CError_AppendObjectName(CErrorBuffer *eb, Object *obj); +extern void CError_AppendMethodName(CErrorBuffer *eb, ObjCMethod *meth); +extern char *CError_GetQualifiedName(NameSpace *nspace, HashNameNode *name); +extern char *CError_GetFunctionName(NameSpace *nspace, HashNameNode *name, TypeFunc *tfunc); +extern char *CError_GetObjectName(Object *obj); +extern char *CError_GetNameString(NameSpace *nspace, HashNameNode *operatorName); +extern void CError_ErrorMessage(int errTable, char *buf, Boolean flag1, Boolean flag2); +extern void CError_BufferAppendTemplateStack(CErrorBuffer *eb); +extern void CError_ErrorMessageVA(int code, const char *format, va_list list, Boolean flag1, Boolean flag2); +extern void CError_VAErrorMessage(int code, va_list list, Boolean flag1, Boolean flag2); +extern void CError_Error(int code, ...); +extern void CError_ErrorTerm(short code); +extern void CError_ErrorSkip(int code, ...); +extern void CError_ErrorFuncCall(short code, NameSpaceObjectList *args, ENodeList *argNodes); +extern void CError_OverloadedFunctionError2(Object *obj, ObjectList *olst, ENodeList *argNodes); +extern void CError_OverloadedFunctionError(Object *obj, ObjectList *olst); +extern void CError_AbstractClassError(TypeClass *tclass); +extern void CError_Warning(int code, ...); +extern void CError_BreakPoint(const char *a, const char *b); +extern void CError_Internal(); +extern void CError_ExpressionTooComplex(); +extern void CError_NoMem(); +extern void CError_UserBreak(); +extern void CError_CannotOpen(); +extern void CError_QualifierCheck(UInt32 qual); + +#endif diff --git a/CInt64.h b/includes/compiler/CInt64.h similarity index 55% rename from CInt64.h rename to includes/compiler/CInt64.h index 37030f9..455bf3f 100644 --- a/CInt64.h +++ b/includes/compiler/CInt64.h @@ -1,9 +1,7 @@ -#pragma once +#ifndef COMPILER_CINT64_H +#define COMPILER_CINT64_H -typedef struct _CInt64 { - long a; - unsigned long b; -} CInt64; +#include "compiler/common.h" // make sure this is in the right place extern const CInt64 cint64_negone; @@ -13,23 +11,26 @@ extern const CInt64 cint64_max; extern const CInt64 cint64_min; inline int CInt64_IsNegative(const CInt64 *n) { - return (n->a & 0x80000000) != 0; + return (n->hi & 0x80000000) != 0; } -inline void CInt64_SetLong(CInt64 *pN, long n) { - pN->b = n; - pN->a = (n < 0) ? 0xFFFFFFFF : 0; +inline void CInt64_SetLong(CInt64 *pN, SInt32 n) { + pN->lo = n; + pN->hi = (n < 0) ? 0xFFFFFFFF : 0; } -inline void CInt64_SetULong(CInt64 *pN, unsigned long n) { - pN->b = n; - pN->a = 0; +inline void CInt64_SetULong(CInt64 *pN, UInt32 n) { + pN->lo = n; + pN->hi = 0; } -// i don't think this one is real lol inline int CInt64_IsZero(CInt64 *n) { - return n->a == 0 && n->b == 0; + //if (n->hi == 0 && n->lo == 0) + // return 1; + //else + // return 0; + return n->hi == 0 && n->lo == 0; } inline void CInt64_Extend32(CInt64 *n) { // assumed name - n->a = (n->b >> 31) ? 0xFFFFFFFF : 0; + n->hi = (n->lo >> 31) ? 0xFFFFFFFF : 0; } extern void CInt64_Init(); @@ -50,18 +51,18 @@ extern CInt64 CInt64_Shr(CInt64 lhs, CInt64 rhs); extern CInt64 CInt64_ShrU(CInt64 lhs, CInt64 rhs); extern int CInt64_UnsignedCompare(const CInt64 *lhs, const CInt64 *rhs); extern int CInt64_SignedCompare(const CInt64 *lhs, const CInt64 *rhs); -extern unsigned char CInt64_Less(CInt64 lhs, CInt64 rhs); -extern unsigned char CInt64_LessU(CInt64 lhs, CInt64 rhs); -extern unsigned char CInt64_Greater(CInt64 lhs, CInt64 rhs); -extern unsigned char CInt64_GreaterU(CInt64 lhs, CInt64 rhs); -extern unsigned char CInt64_LessEqual(CInt64 lhs, CInt64 rhs); -extern unsigned char CInt64_LessEqualU(CInt64 lhs, CInt64 rhs); -extern unsigned char CInt64_GreaterEqual(CInt64 lhs, CInt64 rhs); -extern unsigned char CInt64_GreaterEqualU(CInt64 lhs, CInt64 rhs); -extern unsigned char CInt64_Equal(CInt64 lhs, CInt64 rhs); -extern unsigned char CInt64_NotEqual(CInt64 lhs, CInt64 rhs); -extern unsigned char CInt64_IsInRange(CInt64 value, short len); -extern unsigned char CInt64_IsInURange(CInt64 value, short len); +extern Boolean CInt64_Less(CInt64 lhs, CInt64 rhs); +extern Boolean CInt64_LessU(CInt64 lhs, CInt64 rhs); +extern Boolean CInt64_Greater(CInt64 lhs, CInt64 rhs); +extern Boolean CInt64_GreaterU(CInt64 lhs, CInt64 rhs); +extern Boolean CInt64_LessEqual(CInt64 lhs, CInt64 rhs); +extern Boolean CInt64_LessEqualU(CInt64 lhs, CInt64 rhs); +extern Boolean CInt64_GreaterEqual(CInt64 lhs, CInt64 rhs); +extern Boolean CInt64_GreaterEqualU(CInt64 lhs, CInt64 rhs); +extern Boolean CInt64_Equal(CInt64 lhs, CInt64 rhs); +extern Boolean CInt64_NotEqual(CInt64 lhs, CInt64 rhs); +extern Boolean CInt64_IsInRange(CInt64 value, short len); +extern Boolean CInt64_IsInURange(CInt64 value, short len); extern CInt64 CInt64_And(CInt64 lhs, CInt64 rhs); extern CInt64 CInt64_Xor(CInt64 lhs, CInt64 rhs); extern CInt64 CInt64_Or(CInt64 lhs, CInt64 rhs); @@ -75,11 +76,13 @@ extern void CInt64_ConvertUFromLongDouble(CInt64 *pResult, double value); extern void CInt64_ConvertFromLongDouble(CInt64 *pResult, double value); extern double CInt64_ConvertUToLongDouble(const CInt64 *value); extern double CInt64_ConvertToLongDouble(const CInt64 *value); -extern char *CInt64_ScanOctString(CInt64 *pResult, char *str, unsigned char *pFail); -extern char *CInt64_ScanDecString(CInt64 *pResult, char *str, unsigned char *pFail); -extern char *CInt64_ScanHexString(CInt64 *pResult, char *str, unsigned char *pFail); -extern char *CInt64_ScanBinString(CInt64 *pResult, char *str, unsigned char *pFail); -extern char *CInt64_ScanAsmNumber(CInt64 *pResult, char *str, unsigned char *pFail); +extern char *CInt64_ScanOctString(CInt64 *pResult, char *str, Boolean *pFail); +extern char *CInt64_ScanDecString(CInt64 *pResult, char *str, Boolean *pFail); +extern char *CInt64_ScanHexString(CInt64 *pResult, char *str, Boolean *pFail); +extern char *CInt64_ScanBinString(CInt64 *pResult, char *str, Boolean *pFail); +extern char *CInt64_ScanAsmNumber(CInt64 *pResult, char *str, Boolean *pFail); extern int CInt64_PrintDec(char *output, CInt64 value); extern int CInt64_PrintHex(char *output, CInt64 value); -extern int CInt64_PrintBin(char *output, CInt64 value); \ No newline at end of file +extern int CInt64_PrintBin(char *output, CInt64 value); + +#endif diff --git a/includes/compiler/CompilerTools.h b/includes/compiler/CompilerTools.h new file mode 100644 index 0000000..50581b0 --- /dev/null +++ b/includes/compiler/CompilerTools.h @@ -0,0 +1,129 @@ +#ifndef COMPILER_COMPILERTOOLS_H +#define COMPILER_COMPILERTOOLS_H + +#include "compiler/common.h" + +extern void CompilerGetPString(short index, unsigned char *string); +extern void CompilerGetCString(short index, char *string); +extern unsigned char *CTool_CtoPstr(char *cstr); + +typedef struct HeapBlock { + struct HeapBlock *next; + Handle blockhandle; + SInt32 blocksize; + SInt32 blockfree; +} HeapBlock; + +typedef struct HeapMem { + HeapBlock *blocks; + /// The minimum size for a new block + SInt32 allocsize; + HeapBlock *curblock; + char *curfreep; + SInt32 curfree; +} HeapMem; + +typedef struct _HeapInfo { + /// The amount of blocks in this heap + SInt32 blocks; + /// The value of allocsize for the heap + SInt32 allocsize; + /// The total amount of bytes across all blocks + SInt32 total_size; + /// The amount of free bytes across all blocks + SInt32 total_free; + /// The average size of a block + SInt32 average_block_size; + /// The average amount of free space in a block + SInt32 average_block_free; + /// The amount of bytes in the largest contiguous section of free space + SInt32 largest_free_block; +} HeapInfo; + +typedef struct GList { + char **data; + SInt32 size; + SInt32 hndlsize; + SInt32 growsize; +} GList; + +extern long hash_name_id; +extern HashNameNode **name_hash_nodes; +extern void (*GListErrorProc)(); + +extern short InitGList(GList *gl, SInt32 size); +extern void FreeGList(GList *gl); +extern void LockGList(GList *gl); +extern void UnlockGList(GList *gl); +extern void ShrinkGList(GList *gl); +extern void AppendGListData(GList *gl, const void *data, SInt32 size); +extern void AppendGListNoData(GList *gl, SInt32 size); +extern void AppendGListByte(GList *gl, SInt8 thebyte); +extern void AppendGListWord(GList *gl, SInt16 theword); +extern void AppendGListTargetEndianWord(GList *gl, SInt16 theword); +extern void AppendGListLong(GList *gl, SInt32 theword); +extern void AppendGListTargetEndianLong(GList *gl, SInt32 theword); +extern void AppendGListID(GList *gl, const char *name); +extern void AppendGListName(GList *gl, const char *name); +extern void RemoveGListData(GList *gl, SInt32 size); +extern SInt16 GetGListByte(GList *gl); +extern SInt16 GetGListWord(GList *gl); +extern SInt32 GetGListLong(GList *gl); +extern short GetGListID(GList *gl, char *name); +extern void GetGListData(GList *gl, char *where, SInt32 size); + +extern SInt16 CHash(const char *string); +extern HashNameNode *GetHashNameNode(const char *name); +extern HashNameNode *GetHashNameNodeHash(const char *name, SInt16 hashval); +extern HashNameNode *GetHashNameNodeHash2(const char *name, SInt16 hashval); +extern HashNameNode *GetHashNameNodeExport(const char *name); +extern SInt32 GetHashNameNodeExportID(HashNameNode *node); +extern HashNameNode *GetHashNameNodeByID(SInt32 id); +extern void NameHashExportReset(); +extern void NameHashWriteNameTable(GList *glist); +extern void NameHashWriteTargetEndianNameTable(GList *glist); +extern void InitNameHash(); + +typedef void (*heaperror_t)(); + +extern SInt32 CTool_TotalHeapSize(); +extern void CTool_GetHeapInfo(HeapInfo *result, unsigned char heapID); +extern short initheaps(heaperror_t heaperrorproc); +extern short initgheap(heaperror_t heaperrorproc); +extern heaperror_t getheaperror(); +extern void setheaperror(heaperror_t heaperrorproc); +extern void releaseheaps(); +extern void releasegheap(); +extern void releaseoheap(); +extern void *galloc(SInt32 s); +extern void *lalloc(SInt32 s); +extern void *aalloc(SInt32 s); +extern void *oalloc(SInt32 s); +extern void *balloc(SInt32 s); + +extern void locklheap(); +extern void unlocklheap(); +extern void freelheap(); +extern void freeaheap(); +extern void freeoheap(); +extern void freebheap(); + +extern char *ScanHex(char *string, UInt32 *result, Boolean *overflow); +extern char *ScanOct(char *string, UInt32 *result, Boolean *overflow); +extern char *ScanDec(char *string, UInt32 *result, Boolean *overflow); + +extern void OldUnmangle(char *name, char *out, Boolean full); + +extern short hash(char *a); +extern void memclr(void *ptr, SInt32 size); +extern void memclrw(void *ptr, SInt32 size); +extern void CToLowercase(char *a, char *b); +extern short getbit(SInt32 l); +extern void CTool_EndianConvertWord64(CInt64 ci, char *result); +extern UInt16 CTool_EndianConvertInPlaceWord16Ptr(UInt16 *x); +extern UInt32 CTool_EndianConvertInPlaceWord32Ptr(UInt32 *x); +extern void CTool_EndianConvertVector128(); // not correct but idc +extern HashNameNode *CTool_GetPathName(const FSSpec *fss, SInt32 *moddateptr); +extern int strcat_safe(char *dest, const char *src, SInt32 len); + +#endif diff --git a/includes/compiler/common.h b/includes/compiler/common.h new file mode 100644 index 0000000..b5909e2 --- /dev/null +++ b/includes/compiler/common.h @@ -0,0 +1,283 @@ +#ifndef COMPILER_COMMON_H +#define COMPILER_COMMON_H + +#include "cw_common.h" + +typedef struct HashNameNode { + struct HashNameNode *next; + SInt32 id; + SInt16 hashval; + char name[1]; +} HashNameNode; + +typedef struct CPrepFileInfo CPrepFileInfo; + +#ifdef __MWERKS__ +#pragma options align=mac68k +#endif +// TODO move me into CPrep.h or something? +struct CPrepFileInfo { + FSSpec textfile; + HashNameNode *nameNode; + SInt32 fileModDate; + char *textbuffer; + SInt32 textlength; + SInt32 linenumber; + SInt32 pos; + Boolean hasprepline; + SInt16 fileID; + Boolean recordbrowseinfo; + Boolean unkfield123; + Boolean unkfield124; + Boolean unkfield125; + Boolean unkfield126; +}; +#ifdef __MWERKS__ +#pragma options align=reset +#endif + +typedef struct CInt64 { + SInt32 hi; + UInt32 lo; +} CInt64; + +typedef struct Float { + double value; +} Float; + +typedef union MWVector128 { + UInt8 uc[16]; + UInt16 us[8]; + UInt32 ul[4]; + float f[4]; +} MWVector128; + +typedef enum AccessType { + ACCESSPUBLIC, + ACCESSPRIVATE, + ACCESSPROTECTED, + ACCESSNONE +} AccessType; + +typedef enum Section { + SECT_DEFAULT = 0, + SECT_TEXT = 1, + SECT_DATA = 2, + SECT_UDATA = 3, + SECT_DATA_FAR = 4, + SECT_DATA_NEAR = 5, + SECT_INIT = 6, + SECT_OBJC_CAT_CLS_METH = 7, + SECT_OBJC_CAT_INST_METH = 8, + SECT_OBJC_STRING_OBJECT = 9, + SECT_OBJC_CSTRING_OBJECT = 10, + SECT_OBJC_MESSAGE_REFS = 11, + SECT_OBJC_SEL_FIXUP = 12, + SECT_OBJC_CLS_REFS = 13, + SECT_OBJC_CLASS = 14, + SECT_OBJC_META_CLASS = 15, + SECT_OBJC_CLS_METH = 16, + SECT_OBJC_INST_METH = 17, + SECT_OBJC_PROTOCOL = 18, + SECT_OBJC_CLASS_NAMES = 19, + SECT_OBJC_METH_VAR_TYPES = 20, + SECT_OBJC_METH_VAR_NAMES = 21, + SECT_OBJC_CATEGORY = 22, + SECT_OBJC_CLASS_VARS = 23, + SECT_OBJC_INSTANCE_VARS = 24, + SECT_OBJC_MODULE_INFO = 25, + SECT_OBJC_MSYMBOLS = 26, + SECT_TEXT_CSTRING = 27, + SECT_BACKEND_SPECIFIC = 28, + SECT_MW_EX_TABLE = 28, + SECT_MW_EX_TABLE_INDEX = 29, + SECT_MW_SWITCH = 30, + SECT_8BYTE_LITERALS = 31, + SECT_4BYTE_LITERALS = 32, + SECT_MOD_INIT_FUNC = 33, + SECT_MOD_TERM_FUNC = 34, + SECT_CONST = 35, + SECT_CONST_PTR = 36, + SECT_NONLAZY_PTRS = 37, + SECT_COMMON_VARS = 38, + SECT_16BYTE_LITERALS = 39, + SECT_TEXT_COALESCE = 40, + SECT_DATA_COALESCE = 41, + SECT_UDATA_COALESCE = 42, + SECT_CONST_COALESCE = 43, + SECT_CONST_PTR_COALESCE = 44, + SECT_CSTR_COALESCE = 45, + N_SECTIONS = 46 +} Section; + +typedef struct BClassList BClassList; +typedef struct CI_FuncData CI_FuncData; +typedef struct CLabel CLabel; +typedef struct DefArgCtorInfo DefArgCtorInfo; +typedef struct DepName DepName; +typedef struct ENode ENode; +typedef struct ENodeList ENodeList; +typedef struct ExceptionAction ExceptionAction; +typedef struct ExtendedParam ExtendedParam; +typedef struct FuncArg FuncArg; +typedef struct Initializer Initializer; +typedef struct InlineXRef InlineXRef; +typedef struct MemInitializer MemInitializer; +typedef struct NameSpace NameSpace; +typedef struct NameSpaceName NameSpaceName; +typedef struct NameSpaceList NameSpaceList; +typedef struct NameSpaceLookupList NameSpaceLookupList; +typedef struct NameSpaceObjectList NameSpaceObjectList; +typedef struct ObjBase ObjBase; +typedef struct ObjEnumConst ObjEnumConst; +typedef struct ObjMemberVar ObjMemberVar; +typedef struct ObjMemberVarPath ObjMemberVarPath; +typedef struct ObjNameSpace ObjNameSpace; +typedef struct ObjType ObjType; +typedef struct ObjTypeTag ObjTypeTag; +typedef struct Object Object; +typedef struct ObjectList ObjectList; +typedef struct ObjCInfo ObjCInfo; +typedef struct ObjCMethod ObjCMethod; +typedef struct PCodeLabel PCodeLabel; +typedef struct PointsToFunction PointsToFunction; +typedef struct PTFList PTFList; +typedef struct SOMInfo SOMInfo; +typedef struct Statement Statement; +typedef struct StructMember StructMember; +typedef struct Template Template; +typedef struct TemplateAction TemplateAction; +typedef struct TemplateFriend TemplateFriend; +typedef struct TemplateMember TemplateMember; +typedef struct TemplArg TemplArg; +typedef struct TemplClass TemplClass; +typedef struct TemplClassInst TemplClassInst; +typedef struct TemplateFunction TemplateFunction; +typedef struct TemplFuncInstance TemplFuncInstance; +typedef struct TemplInstance TemplInstance; +typedef struct TemplParam TemplParam; +typedef struct TemplPartialSpec TemplPartialSpec; +typedef struct TemplStack TemplStack; +typedef struct TStream TStream; +typedef struct TStreamElement TStreamElement; +typedef struct Type Type; +typedef struct TypeBitfield TypeBitfield; +typedef struct TypeClass TypeClass; +typedef struct TypeEnum TypeEnum; +typedef struct TypeFunc TypeFunc; +typedef struct TypeIntegral TypeIntegral; +typedef struct TypeMemberPointer TypeMemberPointer; +typedef struct TypeMethod TypeMethod; +typedef struct TypePointer TypePointer; +typedef struct TypeStruct TypeStruct; +typedef struct TypeTemplDep TypeTemplDep; +typedef struct VarInfo VarInfo; +typedef struct VarRecord VarRecord; + +// Common bits for templates +typedef enum TemplParamType { + TPT_TYPE = 0, + TPT_NONTYPE, + TPT_TEMPLATE +} TemplParamType; + +typedef struct TemplParamID { + UInt16 index; + UInt8 nindex; + TemplParamType type; +} TemplParamID; + +typedef enum TemplDepSubType { + TDE_PARAM, + TDE_TYPEEXPR, + TDE_CAST, + TDE_QUALNAME, + TDE_QUALTEMPL, + TDE_OBJACCESS, + TDE_SOURCEREF, + TDE_FUNCCALL, + TDE_LOCAL, + TDE_MONAND, + TDE_MONPLUS, + TDE_MONMUL, + TDE_NEW, + TDE_DELETE, + TDE_ARRAY, + TDE_DYNAMIC_CAST, + TDE_STATIC_CAST, + TDE_REINTERPRET_CAST, + TDE_CONST_CAST, + TDE_TYPEID, + TDE_MEMBERACCESS, + TDE_THROW, + TDE_EXCEPTIONINIT, + TDE_LOCALINIT, + TDE_STATICINIT, + TDE_LOCALDESTROY, + TDE_ILLEGAL +} TemplDepSubType; + +/// Things that can be applied to a type expression +typedef enum TEFuncSel { + TEFS_SIZEOF, + TEFS_ALIGNOF, + TEFS_UUIDOF, + TEFS_BI_ALIGN, + TEFS_BI_TYPE, + TEFS_BI_VTYPE, + TEFS_BI_CTYPE +} TEFuncSel; + +/// How to access an object +/// this might not actually be in Pro7 lol +typedef struct ObjAccess { + NameSpaceObjectList *list; + TypeClass *naming; + TypeClass *member; + TemplArg *targs; + HashNameNode *name; + ENode *expr; + Boolean is_qualified; + Boolean is_member; + Boolean is_ambig : 1; + Boolean is_ptm : 1; + Boolean ext_only : 1; +} ObjAccess; + +/// Qualifiers +enum { + Q_CONST = 1, + Q_VOLATILE = 2, + Q_ASM = 4, + Q_PASCAL = 8, + Q_INLINE = 0x10, + Q_REFERENCE = 0x20, + Q_EXPLICIT = 0x40, + Q_MUTABLE = 0x80, + Q_VIRTUAL = 0x100, + Q_FRIEND = 0x200, + Q_IN = 0x400, + Q_OUT = 0x800, + Q_INOUT = 0x1000, + Q_BYCOPY = 0x2000, + Q_BYREF = 0x4000, + Q_ONEWAY = 0x8000, + Q_RESTRICT = 0x200000, + Q_ALIGNED_1 = 0x2000000, + Q_ALIGNED_2 = 0x4000000, + Q_ALIGNED_4 = 0x6000000, + Q_ALIGNED_8 = 0x8000000, + Q_ALIGNED_16 = 0xA000000, + Q_ALIGNED_32 = 0xC000000, + Q_ALIGNED_64 = 0x10000000, + Q_ALIGNED_128 = 0x12000000, + Q_ALIGNED_256 = 0x14000000, + Q_ALIGNED_512 = 0x16000000, + Q_ALIGNED_1024 = 0x18000000, + Q_ALIGNED_2048 = 0x1A000000, + Q_ALIGNED_4096 = 0x1C000000, + Q_ALIGNED_8192 = 0x1E000000, + Q_ALIGNED_MASK = 0x1E000000 +}; + +#endif diff --git a/includes/compiler/enode.h b/includes/compiler/enode.h new file mode 100644 index 0000000..6e0ab2c --- /dev/null +++ b/includes/compiler/enode.h @@ -0,0 +1,264 @@ +#ifndef COMPILER_ENODE_H +#define COMPILER_ENODE_H + +#include "compiler/common.h" + +#ifdef __MWERKS__ +#pragma options align=mac68k +#endif + +typedef enum ENodeType { + EPOSTINC, + EPOSTDEC, + EPREINC, + EPREDEC, + EINDIRECT, + EMONMIN, + EBINNOT, + ELOGNOT, + EFORCELOAD, + EMUL, + EMULV, + EDIV, + EMODULO, + EADDV, + ESUBV, + EADD, + ESUB, + ESHL, + ESHR, + ELESS, + EGREATER, + ELESSEQU, + EGREATEREQU, + EEQU, + ENOTEQU, + EAND, + EXOR, + EOR, + ELAND, + ELOR, + EASS, + EMULASS, + EDIVASS, + EMODASS, + EADDASS, + ESUBASS, + ESHLASS, + ESHRASS, + EANDASS, + EXORASS, + EORASS, + ECOMMA, + EPMODULO, + EROTL, + EROTR, + EBCLR, + EBTST, + EBSET, + ETYPCON, + EBITFIELD, + EINTCONST, + EFLOATCONST, + ESTRINGCONST, + ECOND, + EFUNCCALL, + EFUNCCALLP, + EOBJREF, + EMFPOINTER, + ENULLCHECK, + EPRECOMP, + ETEMP, + EARGOBJ, + ELOCOBJ, + ELABEL, + ESETCONST, + ENEWEXCEPTION, + ENEWEXCEPTIONARRAY, + EOBJLIST, + EMEMBER, + ETEMPLDEP, + EINSTRUCTION, + EDEFINE, + EREUSE, + EASSBLK, + EVECTOR128CONST, + ECONDASS, + MAXEXPR +} ENodeType; + + +struct ENodeList { + ENodeList *next; + ENode *node; +}; + + +typedef union ENodeUnion { + CInt64 intval; + Float floatval; + SInt32 longval; + ENode *monadic; + Object *objref; + CLabel *label; + MWVector128 vector128val; + struct { + ENode *left; + ENode *right; + } diadic; + struct { + ENode *cond; + ENode *expr1; + ENode *expr2; + } cond; + struct { + ENode *funcref; + ENodeList *args; + TypeFunc *functype; + } funccall; + ObjAccess objaccess; + struct { + ENode *accessnode; + ENode *mfpointer; + } mfpointer; + struct { + ENode *nullcheckexpr; + ENode *condexpr; + SInt32 precompid; + } nullcheck; + SInt32 precompid; + struct { + Type *type; + SInt32 uniqueid; + Boolean needs_dtor; + } temp; + struct { + SInt32 size; + char *data; + SInt32 segnum; + char ispascal; + char ispacked; + } string; + struct { + SInt32 size; + char *data; + } set; + struct { + ENode *initexpr; + ENode *tryexpr; + Object *pointertemp; + Object *deletefunc; + } newexception; + struct { + ENode *initexpr; + ENode *tryexpr; + ENode *catchexpr; + ENode *result; + } itc; + struct { + Object *objref; + SInt32 offset; + } addr; + void *inst; + MemInitializer *ctorinit; + Statement *stmt; + struct { + union { + TemplParamID pid; + struct { + union { + Type *type; + ENode *expr; + } u; + TEFuncSel sel; + Boolean is_expr; + } typeexpr; + struct { + ENodeList *args; + Type *type; + UInt32 qual; + } cast; + struct { + TypeTemplDep *type; + HashNameNode *name; + } qual; + struct { + TypeTemplDep *type; + HashNameNode *name; + TemplArg *args; + } qualtempl; + ObjAccess objaccess; + struct { + ENode *expr; + TStreamElement *token; + } sourceref; + ENode *monadic; + struct { + ENode *expr; + ENodeList *args; + } funccall; + struct { + Type *type; + UInt32 qual; + ENode *arraydim; + ENodeList *placement; + ENodeList *initlist; + Boolean is_global; + Boolean has_init; + } nw; + struct { + ENode *expr; + Boolean is_global; + Boolean is_array; + } del; + struct { + ENode *left; + ENode *right; + } dyadic; + struct { + ENode *expr; + Type *type; + UInt32 qual; + } newcast; + struct { + ENode *expr; + DepName *dname; + Boolean is_pointer; + } member; + struct { + Object *object; + Object *info; + } exinit; + struct { + Object *obj; + Initializer *init; + } varinit; + Object *obj; + } u; + TemplDepSubType subtype; + } templdep; +} ENodeUnion; + +struct ENode { + ENodeType type; + UInt8 cost; + UInt16 flags; // &1, &2 correspond to quals + Boolean ignored; + Boolean hascall; + // void *loc; - might not be in pro7? + Type *rtype; + PointsToFunction *pointsTo; + ENodeUnion data; +}; + +enum { + ENODE_FLAG_CONST = Q_CONST, + ENODE_FLAG_VOLATILE = Q_VOLATILE, + ENODE_FLAG_QUALS = Q_CONST | Q_VOLATILE +}; + +#ifdef __MWERKS__ +#pragma options align=reset +#endif + +#endif diff --git a/includes/compiler/objc.h b/includes/compiler/objc.h new file mode 100644 index 0000000..ce3ebe4 --- /dev/null +++ b/includes/compiler/objc.h @@ -0,0 +1,80 @@ +#ifndef COMPILER_OBJC_H +#define COMPILER_OBJC_H + +#include "compiler/common.h" + +#ifdef __MWERKS__ +#pragma options align=mac68k +#endif + +typedef struct ObjCMethodArg { // bigger in v7 (0x20 vs 0x14) + struct ObjCMethodArg *next; + HashNameNode *selector; + HashNameNode *name; + Type *type; + UInt32 qual; + UInt32 unk14; + UInt32 unk18; + UInt32 unk1C; +} ObjCMethodArg; + +typedef struct ObjCMethodList { // verified via CPrec + struct ObjCMethodList *next; + struct ObjCMethod *method; +} ObjCMethodList; + +typedef struct ObjCSelector { // verified via CPrec + struct ObjCSelector *next; + Object *selobject; + HashNameNode *name; + struct ObjCMethodList *methods; +} ObjCSelector; + +typedef struct ObjCMethod { // verified via CPrec + struct ObjCMethod *next; + Object *object; + TypeFunc *functype; + ObjCSelector *selector; + Type *return_type; + UInt32 return_qual; + ObjCMethodArg *selector_args; + Boolean has_valist; + Boolean is_class_method; + Boolean is_defined; +} ObjCMethod; + +typedef struct ObjCProtocol { // verified via CPrec + struct ObjCProtocol *next; + HashNameNode *name; + struct ObjCProtocolList *protocols; + ObjCMethod *methods; + Object *object; +} ObjCProtocol; + +typedef struct ObjCProtocolList { // verified via CPrec + struct ObjCProtocolList *next; + ObjCProtocol *protocol; +} ObjCProtocolList; + +typedef struct ObjCCategory { // verified via CPrec + struct ObjCCategory *next; + HashNameNode *name; + ObjCProtocolList *protocols; + ObjCMethod *methods; +} ObjCCategory; + +struct ObjCInfo { // verified via CPrec + Object *classobject; + Object *metaobject; + Object *classrefobj; + ObjCMethod *methods; + ObjCProtocolList *protocols; + ObjCCategory *categories; + Boolean is_implemented; +}; + +#ifdef __MWERKS__ +#pragma options align=reset +#endif + +#endif diff --git a/includes/compiler/objects.h b/includes/compiler/objects.h new file mode 100644 index 0000000..32552ec --- /dev/null +++ b/includes/compiler/objects.h @@ -0,0 +1,200 @@ +#ifndef COMPILER_OBJECTS_H +#define COMPILER_OBJECTS_H + +#include "compiler/common.h" + +#ifdef __MWERKS__ +#pragma options align=mac68k +#endif + +typedef enum ObjectType { + OT_ENUMCONST, + OT_TYPE, + OT_TYPETAG, + OT_NAMESPACE, + OT_MEMBERVAR, + OT_OBJECT, + OT_ILLEGAL +} ObjectType; + + +struct ObjectList { + ObjectList *next; + Object *object; +}; + + +/// General structure with all shared fields for all kinds of objects +struct ObjBase { + ObjectType otype; + AccessType access; +}; + + +/// Type 0 (OT_ENUMCONST) +struct ObjEnumConst { + ObjectType otype; + AccessType access; + ObjEnumConst *next; + HashNameNode *name; + Type *type; + CInt64 val; +}; + + +/// Type 1 (OT_TYPE) +struct ObjType { + ObjectType otype; + AccessType access; + Type *type; + void *unk6; +}; + + +/// Type 2 (OT_TYPETAG) +struct ObjTypeTag { + ObjectType otype; + AccessType access; + Type *type; +}; + + +/// Type 3 (OT_NAMESPACE) +struct ObjNameSpace { + ObjectType otype; + AccessType access; + NameSpace *nspace; +}; + + +/// Type 4 (OT_MEMBERVAR) +struct ObjMemberVar { + ObjectType otype; + AccessType access; + Boolean anonunion; + Boolean has_path; + struct ObjMemberVar *next; + HashNameNode *name; + Type *type; + UInt32 qual; + UInt32 offset; +}; +struct ObjMemberVarPath { + ObjectType otype; + AccessType access; + Boolean anonunion; + Boolean has_path; + struct ObjMemberVar *next; + HashNameNode *name; + Type *type; + UInt32 qual; + UInt32 offset; + BClassList *path; +}; + + +typedef enum DataType { + DDATA, + DLOCAL, + DABSOLUTE, + DFUNC, + DVFUNC, + DINLINEFUNC, + DALIAS, + DEXPR, + DNONLAZYPTR, + DLABEL, + DUNUSED +} DataType; + +/// Type 5 (OT_OBJECT) +struct Object { + ObjectType otype; + AccessType access; + DataType datatype; + Section section; + NameSpace *nspace; + HashNameNode *name; + Type *type; + UInt32 qual; + SInt16 sclass; + UInt8 flags; + ExtendedParam *extParam; + Object *toc; + void *any; + //char reg; // notsure? + //VarRecord *varptr; // notsure? + // union starts at 0x24 in v7 + union { + struct { + union { + CInt64 intconst; + Float *floatconst; + MWVector128 *vector128const; + char *string; + struct { + char *data; + SInt32 size; + } switchtable; + } u; + VarInfo *info; + HashNameNode *linkname; + Boolean islocalstatic; + } data; + UInt32 address; + struct { + VarInfo *info; + HashNameNode *linkname; + Object *over_load; + } toc; + struct { + union { + TemplateFunction *templ; + CI_FuncData *ifuncdata; + SInt32 intrinsicid; + } u; + DefArgCtorInfo *defargdata; + HashNameNode *linkname; + TemplFuncInstance *inst; + PTFList *ptfList; + ObjectList *argList; + } func; + struct { + char *data; + SInt32 size; + InlineXRef *xrefs; + } ifunc; + struct { + VarInfo *info; + SInt32 uid; + SInt32 offset; + Object *realObj; + } var; + struct { + Object *object; + //TypeClass *member; + BClassList *member; // ??? + SInt32 offset; + } alias; + struct { + Object *function; + HashNameNode *labelname; + } label; + ENode *expr; + } u; +}; + +#define OBJ_BASE(obj) ((ObjBase *) (obj)) +#define OBJ_ENUM_CONST(obj) ((ObjEnumConst *) (obj)) +#define OBJ_TYPE(obj) ((ObjType *) (obj)) +#define OBJ_TYPE_TAG(obj) ((ObjTypeTag *) (obj)) +#define OBJ_NAMESPACE(obj) ((ObjNameSpace *) (obj)) +#define OBJ_MEMBER_VAR(obj) ((ObjMemberVar *) (obj)) +#define OBJ_MEMBER_VAR_PATH(obj) ((ObjMemberVarPath *) (obj)) +#define OBJECT(obj) ((Object *) (obj)) + +#endif + +#ifdef __MWERKS__ +#pragma options align=reset +#endif diff --git a/includes/compiler/scopes.h b/includes/compiler/scopes.h new file mode 100644 index 0000000..ea2ae98 --- /dev/null +++ b/includes/compiler/scopes.h @@ -0,0 +1,53 @@ +#ifndef COMPILER_SCOPES_H +#define COMPILER_SCOPES_H + +#include "compiler/common.h" + +#ifdef __MWERKS__ +#pragma options align=mac68k +#endif + +struct NameSpace { + NameSpace *parent; + HashNameNode *name; + NameSpaceList *usings; + TypeClass *theclass; + NameSpaceName *tparams; + union { + NameSpaceName **hash; + NameSpaceName *list; + } data; + UInt32 names; + Boolean is_hash; + Boolean is_global; + Boolean is_unnamed; + Boolean is_templ; +}; + +struct NameSpaceList { + NameSpaceList *next; + NameSpace *nspace; +}; + +struct NameSpaceObjectList { + NameSpaceObjectList *next; + ObjBase *object; +}; + +struct NameSpaceName { + NameSpaceName *next; + HashNameNode *name; + NameSpaceObjectList first; +}; + +struct NameSpaceLookupList { // assumed name + NameSpaceLookupList *next; + NameSpace *nspace; + NameSpaceList *namespaces; +}; + +#ifdef __MWERKS__ +#pragma options align=reset +#endif + +#endif diff --git a/includes/compiler/som.h b/includes/compiler/som.h new file mode 100644 index 0000000..ab541ef --- /dev/null +++ b/includes/compiler/som.h @@ -0,0 +1,35 @@ +#ifndef COMPILER_SOM_H +#define COMPILER_SOM_H + +#include "compiler/common.h" + +#ifdef __MWERKS__ +#pragma options align=mac68k +#endif + +typedef enum SOMMethodState { + SOMMS_Deleted, + SOMMS_Method, + SOMMS_Migrated +} SOMMethodState; + +typedef struct SOMReleaseOrder { // checked via CPrec + struct SOMReleaseOrder *next; + HashNameNode *name; + SOMMethodState state; +} SOMReleaseOrder; + +struct SOMInfo { // checked via CPrec + TypeClass *metaclass; + Object *classdataobject; + SOMReleaseOrder *order; + UInt32 majorversion; + UInt32 minorversion; + UInt8 oidl_callstyle; +}; + +#ifdef __MWERKS__ +#pragma options align=reset +#endif + +#endif diff --git a/includes/compiler/templates.h b/includes/compiler/templates.h new file mode 100644 index 0000000..f188e0d --- /dev/null +++ b/includes/compiler/templates.h @@ -0,0 +1,237 @@ +#ifndef COMPILER_TEMPLATES_H +#define COMPILER_TEMPLATES_H + +#include "compiler/common.h" +#include "compiler/types.h" +#include "compiler/tokens.h" + +#ifdef __MWERKS__ +#pragma options align=mac68k +#endif + +typedef struct PackedDeclInfo { // ok + Type *thetype; + UInt32 qual; + NameSpace *nspace; + HashNameNode *name; + TemplArg *expltargs; + SInt16 storageclass; + Section section; + UInt8 exportflags; + Boolean has_expltargs; +} PackedDeclInfo; + +struct Template { + Template *parent; + TemplInstance *parentinst; + TemplParam *params; + Boolean is_class; +}; + +struct TemplateFriend { // verified via CPrec + PackedDeclInfo decl; + FileOffsetInfo fileoffset; + TStream stream; +}; + +struct TemplateMember { // verified via CPrec + struct TemplateMember *next; + TemplParam *params; + Object *object; + FileOffsetInfo fileoffset; + TStream stream; + CPrepFileInfo *srcfile; + SInt32 startoffset; + SInt32 endoffset; +}; + +struct TemplInstance { + // Template *templ; + TemplInstance *parent; + TemplArg *args; + Boolean is_instantiated; + Boolean is_specialized; + Boolean is_extern; + Boolean static_instantiated; +}; +/* +struct __attribute__((packed)) TemplInstance +{ + Template *templ; + TemplInstance *parent; + TemplArg *args; + unsigned __int8 is_instantiated; + unsigned __int8 is_specialized; + unsigned __int8 is_extern; + unsigned __int8 static_instantiated; +}; + + */ + +struct TemplParam { // verified via CPrec + TemplParam *next; + HashNameNode *name; + TemplParamID pid; + union { + struct { + Type *type; + UInt32 qual; + } typeparam; + struct { + Type *type; + UInt32 qual; + ENode *defaultarg; + } paramdecl; + struct { + TemplParam *plist; + Type *defaultarg; + } templparam; + } data; +}; + +struct TemplArg { // verified by CPrec + TemplArg *next; + TemplParamID pid; + union { + struct { + Type *type; + UInt32 qual; + } typeparam; + struct { + ENode *expr; + Boolean is_ref; + } paramdecl; + Type *ttargtype; + } data; + Boolean is_deduced; +}; + +struct TemplPartialSpec { // confirmed via CPrec (but templ might be a different type?) + TemplPartialSpec *next; + TemplClass *templ; + TemplArg *args; +}; + +struct TemplStack { + TemplStack *next; + union { + Object *func; + TypeClass *theclass; + } u; + Boolean is_func; + Boolean is_poi; +}; + +/***********/ +/* Classes */ +/***********/ + +struct TemplClass { + TypeClass theclass; + TemplClass *next; + TemplClass *templ__parent; + Type *x3A_maybe_parentinst; + TemplParam *templ__params; + TemplateMember *members; + TemplClassInst *instances; + TemplClass *pspec_owner; + TemplPartialSpec *pspecs; + TemplateAction *actions; + // not confirmed these last 3 fields yet but there is space for them + UInt16 lex_order_count; + SInt8 align; + UInt8 flags; +}; + +struct TemplClassInst { + TypeClass theclass; + TemplClassInst *next; + Type *x36; // not sure what this represents + TemplClass *templ; + TemplArg *inst_args; + TemplArg *oargs; + void *x46; +}; + +#define TEMPL_CLASS(ty) ( (TemplClass *) (ty) ) +#define TEMPL_CLASS_INST(ty) ( (TemplClassInst *) (ty) ) + +/*************/ +/* Functions */ +/*************/ + +struct TemplateFunction { // verified via CPrec + TemplateFunction *next; + TemplateFunction *unk4; // parent? + HashNameNode *name; + TemplParam *params; + TStream stream; + TStreamElement deftoken; + Object *tfunc; + TemplFuncInstance *instances; + CPrepFileInfo *srcfile; + SInt32 startoffset; + SInt32 endoffset; +}; + +struct TemplFuncInstance { // verified via CPrec + TemplFuncInstance *next; + Object *object; + TemplArg *args; + Boolean is_instantiated; + Boolean is_specialized; + Boolean is_extern; + Boolean static_instantiated; +}; + +/***********/ +/* Actions */ +/***********/ + +typedef enum TemplateActionType { + TAT_NESTEDCLASS, + TAT_ENUMTYPE, + TAT_FRIEND, + TAT_ENUMERATOR, // in pro7 but not pro8 + TAT_BASE, + TAT_OBJECTINIT, + TAT_USINGDECL, + TAT_OBJECTDEF, + TAT_ILLEGAL +} TemplateActionType; + +struct TemplateAction { // verified via CPrec + TemplateAction *next; + TStreamElement source_ref; + union { + TemplClass *tclasstype; + TypeEnum *enumtype; + TemplateFriend *tfriend; + struct { + ObjEnumConst *objenumconst; + ENode *initexpr; + } enumerator; + struct { + Type *type; + ClassList *insert_after; + AccessType access; + Boolean is_virtual; + } base; + struct { + Object *object; + ENode *initexpr; + } objectinit; + struct { + TypeTemplDep *type; + AccessType access; + } usingdecl; + ObjBase *refobj; + } u; + TemplateActionType type; +}; + +#ifdef __MWERKS__ +#pragma options align=reset +#endif + +#endif diff --git a/includes/compiler/tokens.h b/includes/compiler/tokens.h new file mode 100644 index 0000000..b574a81 --- /dev/null +++ b/includes/compiler/tokens.h @@ -0,0 +1,182 @@ +#ifndef COMPILER_TOKENS_H +#define COMPILER_TOKENS_H + +#include "compiler/common.h" + +#ifdef __MWERKS__ +#pragma options align=mac68k +#endif + +#define TKD_OPERATOR 328 +#define TKD_TEMPLATE 332 +#define TKD_IDENTIFIER -3 +#define TKD_COLON_COLON 372 + +typedef enum EToken { + TK_INTCONST = -1, + TK_FLOATCONST = -2, + TK_IDENTIFIER = -3, + TK_STRING = -4, + TK_STRING_WIDE = -5, + TK_NEG6 = -6, + TK_NEG7 = -7, + TK_AUTO = 256, + TK_REGISTER, + TK_STATIC, + TK_EXTERN, + TK_TYPEDEF, + TK_INLINE, + TK_VOID, + TK_CHAR, + TK_SHORT, + TK_INT, + TK_LONG, + TK_FLOAT, + TK_DOUBLE, + TK_SIGNED, + TK_UNSIGNED, + TK_STRUCT, + TK_UNION, + TK_ENUM, + TK_CLASS, + TK_UU_VECTOR = 283, + TK_UU_TYPEOF_UU, + TK_BOOL, + TK_WCHAR_T, + TK_U_COMPLEX, + TK_U_IMAGINARY, + TK_TYPENAME, + TK_CONST, + TK_VOLATILE, + TK_PASCAL, + TK_UU_DECLSPEC, + TK_UU_STDCALL, + TK_UU_CDECL, + TK_UU_FASTCALL, + TK_UU_FAR, + TK_EXPLICIT, + TK_MUTABLE, + TK_ONEWAY, + TK_IN, + TK_INOUT, + TK_OUT, + TK_BYCOPY, + TK_BYREF, + TK_ASM = 310, + TK_CASE, + TK_DEFAULT, + TK_IF, + TK_ELSE, + TK_SWITCH, + TK_WHILE, + TK_DO, + TK_FOR, + TK_GOTO, + TK_CONTINUE, + TK_BREAK, + TK_RETURN, + TK_SIZEOF, + TK_CATCH, + TK_DELETE, + TK_FRIEND, + TK_NEW, + TK_OPERATOR, + TK_PRIVATE, + TK_PROTECTED, + TK_PUBLIC, + TK_TEMPLATE, + TK_THIS, + TK_THROW, + TK_TRY, + TK_VIRTUAL, + TK_INHERITED, + TK_CONST_CAST, + TK_DYNAMIC_CAST, + TK_NAMESPACE, + TK_REINTERPRET_CAST, + TK_STATIC_CAST, + TK_USING, + TK_TRUE, + TK_FALSE, + TK_TYPEID, + TK_EXPORT, + TK_MULT_ASSIGN, + TK_DIV_ASSIGN, + TK_MOD_ASSIGN, + TK_ADD_ASSIGN, + TK_SUB_ASSIGN, + TK_SHL_ASSIGN, + TK_SHR_ASSIGN, + TK_AND_ASSIGN, + TK_XOR_ASSIGN, + TK_OR_ASSIGN, + TK_LOGICAL_OR, + TK_LOGICAL_AND, + TK_LOGICAL_EQ, + TK_LOGICAL_NE, + TK_LESS_EQUAL, + TK_GREATER_EQUAL, + TK_SHL, + TK_SHR, + TK_INCREMENT, + TK_DECREMENT, + TK_ARROW, + TK_ELLIPSIS, + TK_DOT_STAR, + TK_ARROW_STAR, + TK_COLON_COLON, + TK_AT_INTERFACE, + TK_AT_IMPLEMENTATION, + TK_AT_PROTOCOL, + TK_AT_END, + TK_AT_PRIVATE, + TK_AT_PROTECTED, + TK_AT_PUBLIC, + TK_AT_CLASS, + TK_AT_SELECTOR, + TK_AT_ENCODE, + TK_AT_DEFS, + TK_SELF, + TK_SUPER, + TK_UU_ALIGNOF_UU = 388, + TK_RESTRICT, + TK_UU_ATTRIBUTE_UU, + TK_UU_UUIDOF +} EToken; + +typedef struct FileOffsetInfo { + CPrepFileInfo *file; + SInt32 offset; + SInt32 tokenoffset; + Boolean is_inline; +} FileOffsetInfo; + +typedef union TData { + HashNameNode *tkidentifier; + CInt64 tkintconst; + Float tkfloatconst; + struct { + char *data; + SInt32 size; + } tkstring; +} TData; + +struct TStreamElement { + SInt16 tokentype; + SInt16 subtype; + CPrepFileInfo *tokenfile; + SInt32 tokenoffset; + SInt32 tokenline; + TData data; +}; + +struct TStream { + SInt32 tokens; + TStreamElement *firsttoken; +}; + +#endif + +#ifdef __MWERKS__ +#pragma options align=reset +#endif diff --git a/includes/compiler/types.h b/includes/compiler/types.h new file mode 100644 index 0000000..9b07590 --- /dev/null +++ b/includes/compiler/types.h @@ -0,0 +1,324 @@ +#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 +} IntegralType; + +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_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 +}; + + +typedef struct ClassList { // checked via CPrec + struct ClassList *next; + TypeClass *base; + SInt32 offset; + SInt32 voffset; + AccessType access; + Boolean is_virtual; +} ClassList; + +typedef struct VClassList { // checked via CPrec + struct VClassList *next; + TypeClass *base; + SInt32 offset; + SInt32 voffset; + Boolean has_override; + char alignsave; +} VClassList; + +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; +}; + +enum { + CLASS_FLAGS_2 = 2, + CLASS_FLAGS_20 = 0x20, + CLASS_FLAGS_100 = 0x100, // is TemplClass + CLASS_FLAGS_800 = 0x800, // is TemplClassInst + CLASS_FLAGS_900 = 0x900 +}; + + +typedef struct ExceptSpecList { + struct ExceptSpecList *next; + Type *type; + UInt32 qual; +} ExceptSpecList; + +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_METHOD = 0x10, + FUNC_FLAGS_40 = 0x40, // func that's like "operator SomeOtherType()" + FUNC_FLAGS_1000 = 0x1000, + FUNC_FLAGS_2000 = 0x2000, + FUNC_FLAGS_100000 = 0x100000, + FUNC_FLAGS_900000 = 0x900000 +}; + +// 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; + void *x1E; + void *x22; + Boolean x26; +}; + + +struct TypeBitfield { + TypeType type; + SInt32 size; + Type *bitfieldtype; + unsigned char unkA; + char unkB; +}; + + +// 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; +}; + + +// ObjCID + + +// Not sure if these existed originally, but they'll help +#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)) + +#ifdef __MWERKS__ +#pragma options align=reset +#endif + +#endif diff --git a/includes/cw_common.h b/includes/cw_common.h index bea498a..eb016f1 100644 --- a/includes/cw_common.h +++ b/includes/cw_common.h @@ -1,4 +1,5 @@ -#pragma once +#ifndef ROOT_CW_COMMON_H +#define ROOT_CW_COMMON_H /* * Things that seem to be shared across different CodeWarrior modules @@ -41,3 +42,5 @@ typedef struct ParserPluginCallbacks { CWPLUGIN_ENTRY (*SupportsPlugin)(const CLPluginInfo *pluginfo, OSType cpu, OSType os, Boolean *isSupported); CWPLUGIN_ENTRY (*SupportsPanels)(int numPanels, const char **panelNames, Boolean *isSupported); } ParserPluginCallbacks; + +#endif diff --git a/includes/oslib.h b/includes/oslib.h index dfa3827..9aedb8d 100644 --- a/includes/oslib.h +++ b/includes/oslib.h @@ -1,4 +1,6 @@ -#pragma once +#ifndef CMDLINE_OSLIB_H +#define CMDLINE_OSLIB_H + #include "common.h" #define OS_PATHSEP '/' @@ -236,3 +238,5 @@ extern int HPrintF(Handle text, const char *format, ...); #ifdef __cplusplus } #endif + +#endif diff --git a/includes/pref_structs.h b/includes/pref_structs.h index b443bf7..ee016b6 100644 --- a/includes/pref_structs.h +++ b/includes/pref_structs.h @@ -211,9 +211,9 @@ typedef struct PFrontEndC { Boolean ecplusplus; Boolean objective_c; Boolean defer_codegen; - Boolean templateparser; - Boolean c99; - Boolean bottomupinline; + // Boolean templateparser; + // Boolean c99; + // Boolean bottomupinline; } PFrontEndC; typedef struct PWarningC { diff --git a/notes b/notes index 190d074..aaecc43 100644 --- a/notes +++ b/notes @@ -59,7 +59,7 @@ DONE compiler_and_linker/CmdLine_Tools/MacOS_PPC/Tools_PPC/Src/Plugin/libimp-ma ---- CCompiler.c ---- CParser.c ----- compiler_and_linker/FrontEnd/Common/CompilerTools.c +DONE compiler_and_linker/FrontEnd/Common/CompilerTools.c (except for endian work) ---- CodeGenOptPPC.c ---- IrOptimizer.c ---- CodeGen.c diff --git a/osx_build.sh b/osx_build.sh index 7847f47..add410f 100755 --- a/osx_build.sh +++ b/osx_build.sh @@ -64,7 +64,10 @@ MWC_FLAGS="-c -g -opt l=4,noschedule,speed -enum min -Iincludes -Isdk_hdrs -w al # #~/bin/mwccppc $MWC_FLAGS -o objs/cc-mach-ppc-mw.o compiler_and_linker/CmdLine_Tools/MacOS_PPC/Tools_PPC/Src/Static/cc-mach-ppc-mw.c # +~/bin/mwccppc $MWC_FLAGS -o objs/CCompiler.o compiler_and_linker/unsorted/CCompiler.c +# #~/bin/mwccppc $MWC_FLAGS -o objs/Arguments.o unsorted/Arguments.c +~/bin/mwccppc $MWC_FLAGS -o objs/CmdLineBuildDate.o unsorted/CmdLineBuildDate.c #~/bin/mwccppc $MWC_FLAGS -o objs/Help.o unsorted/Help.c #~/bin/mwccppc $MWC_FLAGS -o objs/IO.o unsorted/IO.c #~/bin/mwccppc $MWC_FLAGS -o objs/OptimizerHelpers.o unsorted/OptimizerHelpers.c @@ -87,3 +90,5 @@ MWC_FLAGS="-c -g -opt l=4,noschedule,speed -enum min -Iincludes -Isdk_hdrs -w al #~/bin/mwccppc $MWC_FLAGS -o objs/uCOS.o unsorted/uCOS.c #~/bin/mwccppc $MWC_FLAGS -o objs/uLibImporter.o unsorted/uLibImporter.c #~/bin/mwccppc $MWC_FLAGS -o objs/Utils.o unsorted/Utils.c + +ld /usr/lib/crt1.o objs/*.o -framework System /Applications/Metrowerks\ CodeWarrior\ 7.0/Metrowerks\ CodeWarrior/MacOS\ X\ Support/Libraries/Runtime/Libs/MSL_Runtime_Mach-O.a diff --git a/unsorted/CmdLineBuildDate.c b/unsorted/CmdLineBuildDate.c new file mode 100644 index 0000000..313ca75 --- /dev/null +++ b/unsorted/CmdLineBuildDate.c @@ -0,0 +1,2 @@ +const char *CMDLINE_BUILD_TIME = "19:36:14"; +const char *CMDLINE_BUILD_DATE = "Aug 25 2001";