summaryrefslogtreecommitdiff
path: root/compiler_and_linker/unsorted
diff options
context:
space:
mode:
Diffstat (limited to 'compiler_and_linker/unsorted')
-rw-r--r--compiler_and_linker/unsorted/CCompiler.c255
-rw-r--r--compiler_and_linker/unsorted/CError.c1096
-rw-r--r--compiler_and_linker/unsorted/CInt64.c892
-rw-r--r--compiler_and_linker/unsorted/CMachine.c1499
-rw-r--r--compiler_and_linker/unsorted/CPrec.c2142
5 files changed, 5884 insertions, 0 deletions
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/compiler_and_linker/unsorted/CInt64.c b/compiler_and_linker/unsorted/CInt64.c
new file mode 100644
index 0000000..ce2c45c
--- /dev/null
+++ b/compiler_and_linker/unsorted/CInt64.c
@@ -0,0 +1,892 @@
+#include "compiler/CInt64.h"
+
+const CInt64 cint64_negone = {0xFFFFFFFF, 0xFFFFFFFF};
+const CInt64 cint64_zero = {0, 0};
+const CInt64 cint64_one = {0, 1};
+const CInt64 cint64_max = {0x7FFFFFFF, 0xFFFFFFFF};
+const CInt64 cint64_min = {0x80000000, 0};
+
+#define SHIFT_LEFT_ONE(a, b) do { a <<= 1; if (b & 0x80000000) { a |= 1; } b <<= 1; } while(0)
+
+void CInt64_Init() {
+}
+
+CInt64 CInt64_Not(CInt64 input) {
+ CInt64 output;
+ Boolean c;
+
+ c = (input.hi == 0 && input.lo == 0);
+ CInt64_SetLong(&output, c);
+
+ return output;
+}
+
+CInt64 CInt64_Inv(CInt64 input) {
+ CInt64 output;
+ output.hi = ~input.hi;
+ output.lo = ~input.lo;
+ return output;
+}
+
+CInt64 CInt64_Add(CInt64 lhs, CInt64 rhs) {
+ if (lhs.lo & 0x80000000) {
+ if (rhs.lo & 0x80000000) {
+ lhs.lo += rhs.lo;
+ lhs.hi += 1;
+ } else {
+ lhs.lo += rhs.lo;
+ if (!(lhs.lo & 0x80000000))
+ lhs.hi += 1;
+ }
+ } else {
+ if (rhs.lo & 0x80000000) {
+ lhs.lo += rhs.lo;
+ if (!(lhs.lo & 0x80000000))
+ lhs.hi += 1;
+ } else {
+ lhs.lo += rhs.lo;
+ }
+ }
+ lhs.hi += rhs.hi;
+ return lhs;
+}
+
+CInt64 CInt64_Neg(CInt64 input) {
+ CInt64 result;
+ result = CInt64_Add(CInt64_Inv(input), cint64_one);
+ return result;
+}
+
+CInt64 CInt64_Sub(CInt64 lhs, CInt64 rhs) {
+ lhs = CInt64_Add(lhs, CInt64_Neg(rhs));
+ return lhs;
+}
+
+CInt64 CInt64_MulU(CInt64 lhs, CInt64 rhs) {
+ CInt64 result;
+ CInt64 work1;
+ UInt32 aaaa;
+ UInt32 bbbb;
+ UInt32 cccc;
+ UInt32 dddd;
+ UInt32 eeee;
+
+ aaaa = rhs.lo;
+ result.hi = result.lo = 0;
+ bbbb = lhs.lo;
+ cccc = rhs.hi;
+ dddd = rhs.lo;
+
+ while (bbbb != 0) {
+ if (bbbb & 1) {
+ work1.hi = cccc;
+ work1.lo = dddd;
+ result = CInt64_Add(result, work1);
+ }
+ cccc <<= 1;
+ if (dddd & 0x80000000)
+ cccc |= 1;
+ dddd <<= 1;
+ bbbb >>= 1;
+ }
+
+ eeee = lhs.hi;
+ while (eeee != 0 && aaaa != 0) {
+ if (eeee & 1)
+ result.hi += aaaa;
+ aaaa <<= 1;
+ eeee >>= 1;
+ }
+
+ return result;
+}
+
+CInt64 CInt64_Mul(CInt64 lhs, CInt64 rhs) {
+ if (CInt64_IsNegative(&rhs)) {
+ if (CInt64_IsNegative(&lhs)) {
+ return CInt64_MulU(CInt64_Neg(lhs), CInt64_Neg(rhs));
+ }
+ return CInt64_Neg(CInt64_MulU(lhs, CInt64_Neg(rhs)));
+ }
+ if (CInt64_IsNegative(&lhs)) {
+ return CInt64_Neg(CInt64_MulU(CInt64_Neg(lhs), rhs));
+ }
+ return CInt64_MulU(lhs, rhs);
+}
+
+void CInt64_DivMod(const CInt64 *lhs, const CInt64 *rhs, CInt64 *pDiv, CInt64 *pMod) {
+ Boolean bad;
+ UInt32 workA;
+ UInt32 workB;
+ UInt32 leftA;
+ UInt32 leftB;
+ UInt32 rightA;
+ UInt32 rightB;
+ UInt32 outA;
+ UInt32 outB;
+ CInt64 work;
+ int counter;
+
+ bad = (rhs->hi == 0) && (rhs->lo == 0);
+ if (!bad) {
+ workA = 0;
+ workB = 0;
+ leftA = lhs->hi;
+ leftB = lhs->lo;
+ rightA = rhs->hi;
+ rightB = rhs->lo;
+ outA = 0;
+ outB = 0;
+ counter = 0;
+
+ do {
+ workA <<= 1;
+ if (workB & 0x80000000)
+ workA |= 1;
+ workB <<= 1;
+ if (leftA & 0x80000000)
+ workB |= 1;
+ leftA <<= 1;
+ if (leftB & 0x80000000)
+ leftA |= 1;
+ leftB <<= 1;
+
+ outA <<= 1;
+ if (outB & 0x80000000)
+ outA |= 1;
+ outB <<= 1;
+
+ if (workA <= rightA) {
+ if (workA != rightA)
+ continue;
+ if (workB < rightB)
+ continue;
+ }
+
+ outB |= 1;
+
+ work.hi = workA;
+ work.lo = workB;
+ work = CInt64_Sub(work, *rhs);
+ workA = work.hi;
+ workB = work.lo;
+ } while (++counter < 64);
+
+ if (pDiv) {
+ pDiv->hi = outA;
+ pDiv->lo = outB;
+ }
+ if (pMod) {
+ pMod->hi = workA;
+ pMod->lo = workB;
+ }
+ }
+}
+
+CInt64 CInt64_Div(CInt64 lhs, CInt64 rhs) {
+ CInt64 result;
+ if (CInt64_IsNegative(&rhs)) {
+ rhs = CInt64_Neg(rhs);
+ if (CInt64_IsNegative(&lhs)) {
+ lhs = CInt64_Neg(lhs);
+ CInt64_DivMod(&lhs, &rhs, &result, 0);
+ return result;
+ } else {
+ CInt64_DivMod(&lhs, &rhs, &result, 0);
+ return CInt64_Neg(result);
+ }
+ } else {
+ if (CInt64_IsNegative(&lhs)) {
+ lhs = CInt64_Neg(lhs);
+ CInt64_DivMod(&lhs, &rhs, &result, 0);
+ return CInt64_Neg(result);
+ } else {
+ CInt64_DivMod(&lhs, &rhs, &result, 0);
+ return result;
+ }
+ }
+}
+
+CInt64 CInt64_DivU(CInt64 lhs, CInt64 rhs) {
+ CInt64 result;
+ CInt64_DivMod(&lhs, &rhs, &result, 0);
+ return result;
+}
+
+CInt64 CInt64_Mod(CInt64 lhs, CInt64 rhs) {
+ CInt64 result;
+ if (CInt64_IsNegative(&lhs)) {
+ lhs = CInt64_Neg(lhs);
+ if (CInt64_IsNegative(&rhs))
+ rhs = CInt64_Neg(rhs);
+ CInt64_DivMod(&lhs, &rhs, 0, &result);
+ return CInt64_Neg(result);
+ } else {
+ if (CInt64_IsNegative(&rhs))
+ rhs = CInt64_Neg(rhs);
+ CInt64_DivMod(&lhs, &rhs, 0, &result);
+ return result;
+ }
+}
+
+CInt64 CInt64_ModU(CInt64 lhs, CInt64 rhs) {
+ CInt64 result;
+ CInt64_DivMod(&lhs, &rhs, 0, &result);
+ return result;
+}
+
+CInt64 CInt64_Shl(CInt64 lhs, CInt64 rhs) {
+ int counter;
+ UInt32 a;
+ UInt32 b;
+
+ 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.hi = a;
+ lhs.lo = b;
+ } else {
+ lhs.hi = 0;
+ lhs.lo = 0;
+ }
+ return lhs;
+}
+
+CInt64 CInt64_Shr(CInt64 lhs, CInt64 rhs) {
+ int counter;
+ SInt32 a;
+ UInt32 b;
+
+ 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.hi = a;
+ lhs.lo = b;
+ } else {
+ if (lhs.hi & 0x80000000) {
+ lhs.hi = 0xFFFFFFFF;
+ lhs.lo = 0xFFFFFFFF;
+ } else {
+ lhs.hi = 0;
+ lhs.lo = 0;
+ }
+ }
+ return lhs;
+}
+
+CInt64 CInt64_ShrU(CInt64 lhs, CInt64 rhs) {
+ int counter;
+ UInt32 a;
+ UInt32 b;
+
+ 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.hi = a;
+ lhs.lo = b;
+ } else {
+ lhs.hi = 0;
+ lhs.lo = 0;
+ }
+ return lhs;
+}
+
+int CInt64_UnsignedCompare(const CInt64 *lhs, const CInt64 *rhs) {
+ if (lhs->hi == rhs->hi) {
+ if (lhs->lo < rhs->lo)
+ return -1;
+ else
+ return lhs->lo > rhs->lo;
+ } else {
+ return ((UInt32) lhs->hi < rhs->hi) ? -1 : 1;
+ }
+}
+
+int CInt64_SignedCompare(const CInt64 *lhs, const CInt64 *rhs) {
+ CInt64 lhs_;
+ CInt64 rhs_;
+
+ lhs_ = CInt64_Xor(*lhs, cint64_min);
+ rhs_ = CInt64_Xor(*rhs, cint64_min);
+ return CInt64_UnsignedCompare(&lhs_, &rhs_);
+}
+
+Boolean CInt64_Less(CInt64 lhs, CInt64 rhs) {
+ return CInt64_SignedCompare(&lhs, &rhs) < 0;
+}
+
+Boolean CInt64_LessU(CInt64 lhs, CInt64 rhs) {
+ return CInt64_UnsignedCompare(&lhs, &rhs) < 0;
+}
+
+Boolean CInt64_Greater(CInt64 lhs, CInt64 rhs) {
+ return CInt64_SignedCompare(&lhs, &rhs) > 0;
+}
+
+Boolean CInt64_GreaterU(CInt64 lhs, CInt64 rhs) {
+ return CInt64_UnsignedCompare(&lhs, &rhs) > 0;
+}
+
+Boolean CInt64_LessEqual(CInt64 lhs, CInt64 rhs) {
+ return CInt64_SignedCompare(&lhs, &rhs) <= 0;
+}
+
+Boolean CInt64_LessEqualU(CInt64 lhs, CInt64 rhs) {
+ return CInt64_UnsignedCompare(&lhs, &rhs) <= 0;
+}
+
+Boolean CInt64_GreaterEqual(CInt64 lhs, CInt64 rhs) {
+ return CInt64_SignedCompare(&lhs, &rhs) >= 0;
+}
+
+Boolean CInt64_GreaterEqualU(CInt64 lhs, CInt64 rhs) {
+ return CInt64_UnsignedCompare(&lhs, &rhs) >= 0;
+}
+
+Boolean CInt64_Equal(CInt64 lhs, CInt64 rhs) {
+ return lhs.hi == rhs.hi && lhs.lo == rhs.lo;
+}
+
+Boolean CInt64_NotEqual(CInt64 lhs, CInt64 rhs) {
+ return lhs.hi != rhs.hi || lhs.lo != rhs.lo;
+}
+
+Boolean CInt64_IsInRange(CInt64 value, short len) {
+ CInt64 bound;
+
+ if (value.hi & 0x80000000) {
+ switch (len) {
+ case 1:
+ bound.lo = 0xFFFFFF80;
+ bound.hi = 0xFFFFFFFF;
+ break;
+ case 2:
+ bound.lo = 0xFFFF8000;
+ bound.hi = 0xFFFFFFFF;
+ break;
+ case 4:
+ bound.lo = 0x80000000;
+ bound.hi = 0xFFFFFFFF;
+ break;
+ case 8:
+ return 1;
+ default:
+ return 0;
+ }
+ return CInt64_GreaterEqual(value, bound);
+ } else {
+ switch (len) {
+ case 1:
+ bound.lo = 0x7F;
+ bound.hi = 0;
+ break;
+ case 2:
+ bound.lo = 0x7FFF;
+ bound.hi = 0;
+ break;
+ case 4:
+ bound.lo = 0x7FFFFFFF;
+ bound.hi = 0;
+ break;
+ case 8:
+ return 1;
+ default:
+ return 0;
+ }
+ return CInt64_LessEqual(value, bound);
+ }
+}
+
+Boolean CInt64_IsInURange(CInt64 value, short len) {
+ switch (len) {
+ case 1:
+ return value.hi == 0 && (value.lo & 0xFFFFFF00) == 0;
+ case 2:
+ return value.hi == 0 && (value.lo & 0xFFFF0000) == 0;
+ case 4:
+ return value.hi == 0;
+ case 8:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+CInt64 CInt64_And(CInt64 lhs, CInt64 rhs) {
+ lhs.hi &= rhs.hi;
+ lhs.lo &= rhs.lo;
+ return lhs;
+}
+
+CInt64 CInt64_Xor(CInt64 lhs, CInt64 rhs) {
+ lhs.hi ^= rhs.hi;
+ lhs.lo ^= rhs.lo;
+ return lhs;
+}
+
+CInt64 CInt64_Or(CInt64 lhs, CInt64 rhs) {
+ lhs.hi |= rhs.hi;
+ lhs.lo |= rhs.lo;
+ return lhs;
+}
+
+void CInt64_ConvertInt32(CInt64 *i) {
+ CInt64_Extend32(i);
+}
+
+void CInt64_ConvertUInt32(CInt64 *i) {
+ CInt64_SetULong(i, (UInt32) i->lo);
+}
+
+void CInt64_ConvertInt16(CInt64 *i) {
+ i->lo = (SInt32) i->lo;
+ CInt64_Extend32(i);
+}
+
+void CInt64_ConvertUInt16(CInt64 *i) {
+ CInt64_SetULong(i, (UInt16) i->lo);
+}
+
+void CInt64_ConvertInt8(CInt64 *i) {
+ i->lo = (SInt8) i->lo;
+ CInt64_Extend32(i);
+}
+
+void CInt64_ConvertUInt8(CInt64 *i) {
+ CInt64_SetULong(i, (UInt8) i->lo);
+}
+
+void CInt64_ConvertUFromLongDouble(CInt64 *pResult, double value) {
+ union { float f; UInt32 l; } cvt;
+ UInt32 a, b;
+ float threshold;
+ int bits;
+
+ if (value <= 0.0) {
+ pResult->hi = 0;
+ pResult->lo = 0;
+ return;
+ }
+
+ cvt.l = 0x5F800000;
+ if (value >= cvt.f) {
+ pResult->hi = 0xFFFFFFFF;
+ pResult->lo = 0xFFFFFFFF;
+ return;
+ }
+
+ a = b = 0;
+ for (bits = 63; bits >= 0; bits--) {
+ a <<= 1;
+ if (b & 0x80000000)
+ a |= 1;
+ b <<= 1;
+
+ if ((short) bits == 0) {
+ threshold = 1.0f;
+ } else {
+ cvt.l = (((short) bits + 127) & 255) << 23;
+ threshold = cvt.f;
+ }
+
+ if (threshold <= value) {
+ b |= 1;
+ value -= threshold;
+ }
+ }
+
+ pResult->hi = a;
+ pResult->lo = b;
+}
+
+void CInt64_ConvertFromLongDouble(CInt64 *pResult, double value) {
+ if (value < 0.0) {
+ CInt64_ConvertUFromLongDouble(pResult, -value);
+ *pResult = CInt64_Neg(*pResult);
+ } else {
+ CInt64_ConvertUFromLongDouble(pResult, value);
+ }
+}
+
+double CInt64_ConvertUToLongDouble(const CInt64 *value) {
+ Boolean bad;
+ UInt32 work;
+ int counter;
+ double result;
+
+ bad = (value->hi == 0) && (value->lo == 0);
+ if (bad) {
+ return 0.0;
+ } else {
+ result = 0.0;
+
+ work = value->hi;
+ if (work != 0) {
+ for (counter = 0; counter < 32; counter++) {
+ result += result;
+ if (work & 0x80000000)
+ result += 1.0;
+ work <<= 1;
+ }
+ }
+
+ counter = 0;
+ work = value->lo;
+ for (; counter < 32; counter++) {
+ result += result;
+ if (work & 0x80000000)
+ result += 1.0;
+ work <<= 1;
+ }
+
+ return result;
+ }
+}
+
+double CInt64_ConvertToLongDouble(const CInt64 *value) {
+ CInt64 tmp;
+ if (value->hi & 0x80000000) {
+ tmp = CInt64_Neg(*value);
+ return -CInt64_ConvertUToLongDouble(&tmp);
+ } else {
+ return CInt64_ConvertUToLongDouble(value);
+ }
+}
+
+char *CInt64_ScanOctString(CInt64 *pResult, char *str, Boolean *pFail) {
+ int ch;
+ CInt64 tmp;
+ UInt32 a;
+ UInt32 b;
+
+ *pFail = 0;
+ pResult->hi = pResult->lo = 0;
+
+ while ((ch = *str) >= '0' && *str <= '7') {
+ a = pResult->hi;
+ b = pResult->lo;
+ if (a & 0xE0000000)
+ *pFail = 1;
+
+ SHIFT_LEFT_ONE(a, b);
+ SHIFT_LEFT_ONE(a, b);
+ SHIFT_LEFT_ONE(a, b);
+
+ pResult->hi = a;
+ pResult->lo = b;
+
+ CInt64_SetLong(&tmp, ch - '0');
+ *pResult = CInt64_Add(*pResult, tmp);
+ ++str;
+ }
+
+ return str;
+}
+
+char *CInt64_ScanDecString(CInt64 *pResult, char *str, Boolean *pFail) {
+ int ch;
+ CInt64 tmp;
+ UInt32 a;
+ UInt32 b;
+
+ *pFail = 0;
+ pResult->hi = pResult->lo = 0;
+
+ while ((ch = *str) >= '0' && *str <= '9') {
+ a = pResult->hi;
+ b = pResult->lo;
+ if (a & 0xE0000000)
+ *pFail = 1;
+
+ SHIFT_LEFT_ONE(a, b);
+ tmp.hi = a;
+ tmp.lo = b;
+ SHIFT_LEFT_ONE(a, b);
+ SHIFT_LEFT_ONE(a, b);
+ pResult->hi = a;
+ pResult->lo = b;
+
+ if (CInt64_IsNegative(pResult)) {
+ *pResult = CInt64_Add(*pResult, tmp);
+ if (!CInt64_IsNegative(pResult))
+ *pFail = 1;
+ } else {
+ *pResult = CInt64_Add(*pResult, tmp);
+ }
+
+ CInt64_SetLong(&tmp, ch - '0');
+ if (CInt64_IsNegative(pResult)) {
+ *pResult = CInt64_Add(*pResult, tmp);
+ if (!CInt64_IsNegative(pResult))
+ *pFail = 1;
+ } else {
+ *pResult = CInt64_Add(*pResult, tmp);
+ }
+
+ ++str;
+ }
+
+ return str;
+}
+
+char *CInt64_ScanHexString(CInt64 *pResult, char *str, Boolean *pFail) {
+ /* NOT MATCHING */
+ int digit;
+ CInt64 tmp;
+ UInt32 a;
+ UInt32 b;
+
+ *pFail = 0;
+ pResult->hi = pResult->lo = 0;
+
+ for (;;) {
+ if ((digit = str[0]) >= '0' && digit <= '9')
+ digit = digit - '0';
+ else if (digit >= 'A' && digit <= 'F')
+ digit = digit - 'A' + 10;
+ else if (digit >= 'a' && digit <= 'f')
+ digit = digit - 'a' + 10;
+ else
+ break;
+
+ a = pResult->hi;
+ b = pResult->lo;
+ ++str;
+
+ if (a & 0xF0000000)
+ *pFail = 1;
+
+ SHIFT_LEFT_ONE(a, b);
+ SHIFT_LEFT_ONE(a, b);
+ SHIFT_LEFT_ONE(a, b);
+ SHIFT_LEFT_ONE(a, b);
+
+ pResult->hi = a;
+ pResult->lo = b;
+
+ CInt64_SetLong(&tmp, (char) digit);
+ *pResult = CInt64_Add(*pResult, tmp);
+ }
+
+ return str;
+}
+
+char *CInt64_ScanBinString(CInt64 *pResult, char *str, Boolean *pFail) {
+ char digit;
+ UInt32 a;
+ UInt32 b;
+
+ *pFail = 0;
+ pResult->hi = pResult->lo = 0;
+
+ for (;;) {
+ if (*str == '0')
+ digit = 0;
+ else if (*str == '1')
+ digit = 1;
+ else
+ break;
+
+ a = pResult->hi;
+ b = pResult->lo;
+ ++str;
+
+ if (a & 0x80000000)
+ *pFail = 1;
+
+ SHIFT_LEFT_ONE(a, b);
+
+ pResult->hi = a;
+ pResult->lo = b;
+
+ if (digit == 1)
+ *pResult = CInt64_Add(*pResult, cint64_one);
+ }
+
+ return str;
+}
+
+char *CInt64_ScanAsmNumber(CInt64 *pResult, char *str, Boolean *pFail) {
+ Boolean isMaybeBin;
+ Boolean isOct;
+ Boolean isMaybeDec;
+ Boolean isBin;
+ char *p;
+
+ isMaybeBin = 1;
+ isOct = *str == '0';
+ isMaybeDec = 1;
+ isBin = 0;
+ p = str;
+
+ for (;;) {
+ if (*p == 0)
+ break;
+
+ if (strchr("01", p[0])) {
+ if (isBin)
+ isMaybeBin = 0;
+ } else if (strchr("bB", p[0])) {
+ isBin = 1;
+ isMaybeDec = 0;
+ isOct = 0;
+ } else if (strchr("234567", p[0])) {
+ isMaybeBin = 0;
+ } else if (strchr("89", p[0])) {
+ isOct = 0;
+ isMaybeBin = 0;
+ } else if (strchr("acdefACEDF", p[0])) {
+ isMaybeDec = 0;
+ isMaybeBin = 0;
+ } else {
+ break;
+ }
+
+ ++p;
+ }
+
+ if (isMaybeBin && isBin) {
+ return CInt64_ScanBinString(pResult, str, pFail) + 1;
+ } else if (p[0] == 'h' || p[0] == 'H') {
+ return CInt64_ScanHexString(pResult, str, pFail) + 1;
+ } else if (isOct) {
+ return CInt64_ScanOctString(pResult, str, pFail);
+ } else if (isMaybeDec) {
+ return CInt64_ScanDecString(pResult, str, pFail);
+ } else {
+ *pFail = 1;
+ return p;
+ }
+}
+
+int CInt64_PrintDec(char *output, CInt64 value) {
+ int length;
+ CInt64 rem;
+ CInt64 divisor;
+ char buf[40];
+ char *bufp;
+
+ length = 0;
+ if (CInt64_IsNegative(&value)) {
+ value = CInt64_Neg(value);
+ *output = '-';
+ length++;
+ output++;
+ }
+
+ if (!CInt64_IsZero(&value)) {
+ divisor.lo = 10;
+ divisor.hi = 0;
+
+ bufp = buf;
+ for (;;) {
+ rem = CInt64_ModU(value, divisor);
+ *(bufp++) = rem.lo + '0';
+ value = CInt64_DivU(value, divisor);
+ if (CInt64_IsZero(&value) != 0)
+ break;
+ }
+
+ while (--bufp >= buf) {
+ *(output++) = *bufp;
+ length++;
+ }
+ } else {
+ *(output++) = '0';
+ length++;
+ }
+
+ *output = 0;
+ return length;
+}
+
+int CInt64_PrintHex(char *output, CInt64 value) {
+ int length;
+ CInt64 rem;
+ CInt64 shift;
+ CInt64 mask;
+ char buf[32];
+ char *bufp;
+
+ length = 0;
+ if (!CInt64_IsZero(&value)) {
+ shift.lo = 4;
+ shift.hi = 0;
+ mask.lo = 0xF;
+ mask.hi = 0;
+
+ bufp = buf;
+ for (;;) {
+ rem = CInt64_And(value, mask);
+ if ((SInt32) rem.lo >= 10)
+ *(bufp++) = rem.lo + 'A';
+ else
+ *(bufp++) = rem.lo + '0';
+ value = CInt64_ShrU(value, shift);
+ if (CInt64_IsZero(&value) != 0)
+ break;
+ }
+
+ while (--bufp >= buf) {
+ *(output++) = *bufp;
+ length++;
+ }
+ } else {
+ *(output++) = '0';
+ length++;
+ }
+
+ *output = 0;
+ return length;
+}
+
+int CInt64_PrintBin(char *output, CInt64 value) {
+ int length;
+ CInt64 rem;
+ char buf[64];
+ char *bufp;
+
+ length = 0;
+ if (!CInt64_IsZero(&value)) {
+ bufp = buf;
+ for (;;) {
+ rem = CInt64_And(value, cint64_one);
+ if (CInt64_Equal(rem, cint64_one))
+ *(bufp++) = '1';
+ else
+ *(bufp++) = '0';
+ value = CInt64_ShrU(value, cint64_one);
+ if (CInt64_IsZero(&value) != 0)
+ break;
+ }
+
+ while (--bufp >= buf) {
+ *(output++) = *bufp;
+ length++;
+ }
+ } else {
+ *(output++) = '0';
+ length++;
+ }
+
+ *output = 0;
+ return length;
+}
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(&current->type, CPrec_GetTypePatch(exspec->type));
+
+ if (!exspec->next)
+ break;
+ next = CPrec_AppendAlign();
+ CPrec_NewPointerPatch(&current->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(&current->name, lst->name);
+
+ if (lst->dexpr)
+ CPrec_NewPointerPatch(&current->dexpr, CPrec_GetExpressionPatch(lst->dexpr));
+ if (lst->type)
+ CPrec_NewPointerPatch(&current->type, CPrec_GetTypePatch(lst->type));
+ else
+#line 1167
+ CError_FATAL();
+
+ if (lst->next) {
+ if ((addrPatch = CPrec_FindAddrPatch(lst->next))) {
+ CPrec_NewPointerPatch(&current->next, addrPatch->value);
+ } else {
+ next = CPrec_AppendAlign();
+ CPrec_NewPointerPatch(&current->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(&current->base, CPrec_GetTypePatch((Type *) cl->base));
+
+ if (!cl->next)
+ break;
+
+ if ((addrPatch = CPrec_FindAddrPatch(cl->next))) {
+ CPrec_NewPointerPatch(&current->next, addrPatch->value);
+ break;
+ } else {
+ next = CPrec_AppendAlign();
+ CPrec_NewPointerPatch(&current->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(&current->base, CPrec_GetTypePatch((Type *) vcl->base));
+
+ if (!vcl->next)
+ break;
+ next = CPrec_AppendAlign();
+ CPrec_NewPointerPatch(&current->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(&current->u.theclass, CPrec_GetTypePatch((Type *) cf->u.theclass));
+ else
+ CPrec_NewPointerPatch(&current->u.theclass, CPrec_GetObjectPatch(cf->u.obj));
+
+ if (!cf->next)
+ break;
+ next = CPrec_AppendAlign();
+ CPrec_NewPointerPatch(&current->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(&current->type, CPrec_GetTypePatch((Type *) bcl->type));
+
+ if (!bcl->next)
+ break;
+ next = CPrec_AppendAlign();
+ CPrec_NewPointerPatch(&current->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(&current->name, sro->name);
+ if (!sro->next)
+ break;
+ next = CPrec_AppendAlign();
+ CPrec_NewPointerPatch(&current->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(&current->selector, arg->selector);
+ if (arg->name)
+ CPrec_NamePatch(&current->name, arg->name);
+ if (arg->type)
+ CPrec_NewPointerPatch(&current->type, CPrec_GetTypePatch(arg->type));
+
+ if (!arg->next)
+ break;
+ next = CPrec_AppendAlign();
+ CPrec_NewPointerPatch(&current->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(&current->method, CPrec_GetObjCMethodPatch(lst->method));
+
+ if (!lst->next)
+ break;
+
+ if ((addrPatch = CPrec_FindAddrPatch(lst->next))) {
+ CPrec_NewPointerPatch(&current->next, addrPatch->value);
+ break;
+ } else {
+ next = CPrec_AppendAlign();
+ CPrec_NewPointerPatch(&current->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(&current->selobject, CPrec_GetObjectPatch(sel->selobject));
+ CPrec_NamePatch(&current->name, sel->name);
+ if (sel->methods)
+ CPrec_NewPointerPatch(&current->methods, CPrec_GetObjCMethodListPatch(sel->methods));
+
+ if (!sel->next)
+ break;
+
+ if ((addrPatch = CPrec_FindAddrPatch(sel->next))) {
+ CPrec_NewPointerPatch(&current->next, addrPatch->value);
+ break;
+ } else {
+ next = CPrec_AppendAlign();
+ CPrec_NewPointerPatch(&current->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(&current->object, CPrec_GetObjectPatch(meth->object));
+ if (meth->functype)
+ CPrec_NewPointerPatch(&current->functype, CPrec_GetTypePatch((Type *) meth->functype));
+ if (meth->selector)
+ CPrec_NewPointerPatch(&current->selector, CPrec_GetObjCSelectorPatch(meth->selector));
+ if (meth->return_type)
+ CPrec_NewPointerPatch(&current->return_type, CPrec_GetTypePatch(meth->return_type));
+ if (meth->selector_args)
+ CPrec_NewPointerPatch(&current->selector_args, CPrec_GetObjCMethodArgPatch(meth->selector_args));
+
+ if (!meth->next)
+ break;
+
+ if ((addrPatch = CPrec_FindAddrPatch(meth->next))) {
+ CPrec_NewPointerPatch(&current->next, addrPatch->value);
+ break;
+ } else {
+ next = CPrec_AppendAlign();
+ CPrec_NewPointerPatch(&current->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(&current->name, prot->name);
+ if (prot->protocols)
+ CPrec_NewPointerPatch(&current->protocols, CPrec_GetObjCProtocolListPatch(prot->protocols));
+ if (prot->methods)
+ CPrec_NewPointerPatch(&current->methods, CPrec_GetObjCMethodPatch(prot->methods));
+ if (prot->object)
+ CPrec_NewPointerPatch(&current->object, CPrec_GetObjectPatch(prot->object));
+
+ if (!prot->next)
+ break;
+
+ if ((addrPatch = CPrec_FindAddrPatch(prot->next))) {
+ CPrec_NewPointerPatch(&current->next, addrPatch->value);
+ break;
+ } else {
+ next = CPrec_AppendAlign();
+ CPrec_NewPointerPatch(&current->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(&current->protocol, CPrec_GetObjCProtocolPatch(lst->protocol));
+
+ if (!lst->next)
+ break;
+
+ next = CPrec_AppendAlign();
+ CPrec_NewPointerPatch(&current->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(&current->name, cat->name);
+ if (cat->protocols)
+ CPrec_NewPointerPatch(&current->protocols, CPrec_GetObjCProtocolListPatch(cat->protocols));
+ if (cat->methods)
+ CPrec_NewPointerPatch(&current->methods, CPrec_GetObjCMethodPatch(cat->methods));
+
+ if (!cat->next)
+ break;
+
+ if ((addrPatch = CPrec_FindAddrPatch(cat->next))) {
+ CPrec_NewPointerPatch(&current->next, addrPatch->value);
+ break;
+ } else {
+ next = CPrec_AppendAlign();
+ CPrec_NewPointerPatch(&current->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(&current->data.typeparam.type, CPrec_GetTypePatch(arg->data.typeparam.type));
+ break;
+ case TPT_NONTYPE:
+ if (arg->data.paramdecl.expr)
+ CPrec_NewPointerPatch(&current->data.paramdecl.expr, CPrec_GetExpressionPatch(arg->data.paramdecl.expr));
+ break;
+ case TPT_TEMPLATE:
+ if (arg->data.ttargtype)
+ CPrec_NewPointerPatch(&current->data.ttargtype, CPrec_GetTypePatch(arg->data.ttargtype));
+ break;
+ default:
+#line 1879
+ CError_FATAL();
+ }
+
+ if (!arg->next)
+ break;
+ next = CPrec_AppendAlign();
+ CPrec_NewPointerPatch(&current->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(&current->name, param->name);
+
+ switch (param->pid.type) {
+ case TPT_TYPE:
+ if (param->data.typeparam.type)
+ CPrec_NewPointerPatch(&current->data.typeparam.type, CPrec_GetTypePatch(param->data.typeparam.type));
+ break;
+ case TPT_NONTYPE:
+ CPrec_NewPointerPatch(&current->data.paramdecl.type, CPrec_GetTypePatch(param->data.paramdecl.type));
+ if (param->data.paramdecl.defaultarg)
+ CPrec_NewPointerPatch(&current->data.paramdecl.defaultarg, CPrec_GetExpressionPatch(param->data.paramdecl.defaultarg));
+ break;
+ case TPT_TEMPLATE:
+ if (param->data.templparam.plist)
+ CPrec_NewPointerPatch(&current->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(&current->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(&current->data.tkidentifier, tokens->data.tkidentifier);
+ break;
+ case TK_INTCONST:
+ case TK_FLOATCONST:
+ break;
+ case TK_STRING:
+ case TK_STRING_WIDE:
+ CPrec_RawMemPatch(&current->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(&current->object, CPrec_GetObjectPatch(inst->object));
+ CPrec_NewPointerPatch(&current->args, CPrec_GetTemplateArgPatch(inst->args));
+
+ if (!inst->next)
+ break;
+
+ if ((addrPatch = CPrec_FindAddrPatch(inst->next))) {
+ CPrec_NewPointerPatch(&current->next, addrPatch->value);
+ break;
+ } else {
+ next = CPrec_AppendAlign();
+ CPrec_NewPointerPatch(&current->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(&current->params, CPrec_GetTemplateParamPatch(memb->params));
+ CPrec_NewPointerPatch(&current->object, CPrec_GetObjectPatch(memb->object));
+ if (memb->stream.firsttoken)
+ CPrec_NewPointerPatch(&current->stream.firsttoken, CPrec_GetTStreamPatch(memb->stream.firsttoken, memb->stream.tokens));
+
+ if (!memb->next)
+ break;
+ next = CPrec_AppendAlign();
+ CPrec_NewPointerPatch(&current->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(&current->templ, CPrec_GetTypePatch((Type *) pspec->templ));
+ if (pspec->args)
+ CPrec_NewPointerPatch(&current->args, CPrec_GetTemplateArgPatch(pspec->args));
+
+ if (!pspec->next)
+ break;
+ next = CPrec_AppendAlign();
+ CPrec_NewPointerPatch(&current->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(&current->u.tclasstype, CPrec_GetTypePatch((Type *) act->u.tclasstype));
+ break;
+ case TAT_ENUMTYPE:
+ CPrec_NewPointerPatch(&current->u.enumtype, CPrec_GetTypePatch((Type *) act->u.enumtype));
+ break;
+ case TAT_FRIEND:
+ CPrec_NewPointerPatch(&current->u.tfriend, CPrec_GetTemplateFriendPatch(act->u.tfriend));
+ break;
+ case TAT_ENUMERATOR:
+ CPrec_NewPointerPatch(&current->u.enumerator.objenumconst, CPrec_GetObjEnumConstPatch(act->u.enumerator.objenumconst));
+ if (act->u.enumerator.initexpr)
+ CPrec_NewPointerPatch(&current->u.enumerator.initexpr, CPrec_GetExpressionPatch(act->u.enumerator.initexpr));
+ break;
+ case TAT_BASE:
+ CPrec_NewPointerPatch(&current->u.base.type, CPrec_GetTypePatch(act->u.base.type));
+ if (act->u.base.insert_after)
+ CPrec_NewPointerPatch(&current->u.base.insert_after, CPrec_GetClassListPatch(act->u.base.insert_after));
+ break;
+ case TAT_OBJECTINIT:
+ CPrec_NewPointerPatch(&current->u.objectinit.object, CPrec_GetObjectPatch(act->u.objectinit.object));
+ CPrec_NewPointerPatch(&current->u.objectinit.initexpr, CPrec_GetExpressionPatch(act->u.objectinit.initexpr));
+ break;
+ case TAT_USINGDECL:
+ CPrec_NewPointerPatch(&current->u.usingdecl.type, CPrec_GetTypeTemplDepPatch(act->u.usingdecl.type));
+ break;
+ case TAT_OBJECTDEF:
+ CPrec_NewPointerPatch(&current->u.refobj, CPrec_GetObjBasePatch(act->u.refobj));
+ break;
+ default:
+#line 2410
+ CError_FATAL();
+ }
+
+ if (!act->next)
+ break;
+ next = CPrec_AppendAlign();
+ CPrec_NewPointerPatch(&current->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(&current->unk4, CPrec_GetTemplateFunctionPatch(tf->unk4));
+ CPrec_NamePatch(&current->name, tf->name);
+ if (tf->params)
+ CPrec_NewPointerPatch(&current->params, CPrec_GetTemplateParamPatch(tf->params));
+ if (tf->stream.firsttoken)
+ CPrec_NewPointerPatch(&current->stream.firsttoken, CPrec_GetTStreamPatch(tf->stream.firsttoken, tf->stream.tokens));
+ CPrec_NewPointerPatch(&current->tfunc, CPrec_GetObjectPatch(tf->tfunc));
+ if (tf->instances)
+ CPrec_NewPointerPatch(&current->instances, CPrec_GetTemplFuncInstancePatch(tf->instances));
+
+ if (!tf->next)
+ break;
+
+ if ((addrPatch = CPrec_FindAddrPatch(tf->next))) {
+ CPrec_NewPointerPatch(&current->next, addrPatch->value);
+ break;
+ } else {
+ next = CPrec_AppendAlign();
+ CPrec_NewPointerPatch(&current->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(&current->nspace, CPrec_GetNameSpacePatch(tclass->nspace));
+ if (tclass->classname)
+ CPrec_NamePatch(&current->classname, tclass->classname);
+ if (tclass->bases)
+ CPrec_NewPointerPatch(&current->bases, CPrec_GetClassListPatch(tclass->bases));
+ if (tclass->vbases)
+ CPrec_NewPointerPatch(&current->vbases, CPrec_GetVClassListPatch(tclass->vbases));
+ if (tclass->ivars)
+ CPrec_NewPointerPatch(&current->ivars, CPrec_GetObjMemberVarPatch(tclass->ivars));
+ if (tclass->friends)
+ CPrec_NewPointerPatch(&current->friends, CPrec_GetClassFriendPatch(tclass->friends));
+ if (tclass->vtable)
+ CPrec_NewPointerPatch(&current->vtable, CPrec_GetVTablePatch(tclass->vtable));
+ if (tclass->sominfo)
+ CPrec_NewPointerPatch(&current->sominfo, CPrec_GetSOMInfoPatch(tclass->sominfo));
+ if (tclass->objcinfo)
+ CPrec_NewPointerPatch(&current->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(&current->data.destroy_local.dtor, CPrec_GetObjectPatch(exc->data.destroy_local.dtor));
+ break;
+ case EAT_DESTROYLOCALCOND:
+ CPrec_NewPointerPatch(&current->data.destroy_local_cond.dtor, CPrec_GetObjectPatch(exc->data.destroy_local_cond.dtor));
+ break;
+ case EAT_DESTROYLOCALOFFSET:
+ CPrec_NewPointerPatch(&current->data.destroy_local_offset.dtor, CPrec_GetObjectPatch(exc->data.destroy_local_offset.dtor));
+ break;
+ case EAT_DESTROYLOCALPOINTER:
+ CPrec_NewPointerPatch(&current->data.destroy_local_pointer.dtor, CPrec_GetObjectPatch(exc->data.destroy_local_pointer.dtor));
+ break;
+ case EAT_DESTROYLOCALARRAY:
+ CPrec_NewPointerPatch(&current->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(&current->data.destroy_member.dtor, CPrec_GetObjectPatch(exc->data.destroy_member.dtor));
+ break;
+ case EAT_DESTROYMEMBERCOND:
+ CPrec_NewPointerPatch(&current->data.destroy_member_cond.dtor, CPrec_GetObjectPatch(exc->data.destroy_member_cond.dtor));
+ break;
+ case EAT_DESTROYMEMBERARRAY:
+ CPrec_NewPointerPatch(&current->data.destroy_member_array.dtor, CPrec_GetObjectPatch(exc->data.destroy_member_array.dtor));
+ break;
+ case EAT_DELETEPOINTER:
+ case EAT_DELETELOCALPOINTER:
+ CPrec_NewPointerPatch(&current->data.delete_pointer.deletefunc, CPrec_GetObjectPatch(exc->data.delete_pointer.deletefunc));
+ break;
+ case EAT_DELETEPOINTERCOND:
+ CPrec_NewPointerPatch(&current->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(&current->data.catch_block.catch_typeid, CPrec_GetObjectPatch(exc->data.catch_block.catch_typeid));
+ CPrec_NewPointerPatch(&current->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(&current->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(&current->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(&current->node, CPrec_GetExpressionPatch(lst->node));
+
+ if (!lst->next)
+ break;
+ next = CPrec_AppendAlign();
+ CPrec_NewPointerPatch(&current->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(&current->name, obj->name);
+ CPrec_NewPointerPatch(&current->type, CPrec_GetTypePatch( obj->type));
+
+ if (!obj->next)
+ break;
+
+ if ((addrPatch = CPrec_FindAddrPatch(obj->next))) {
+ CPrec_NewPointerPatch(&current->next, addrPatch->value);
+ break;
+ } else {
+ next = CPrec_AppendAlign();
+ CPrec_NewPointerPatch(&current->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(&current->object, CPrec_GetObjectPatch(ix->object));
+
+ if (!ix->next)
+ break;
+ next = CPrec_AppendAlign();
+ CPrec_NewPointerPatch(&current->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(&current->object, CPrec_GetObjectPatch(ol->object));
+ if (ol->next) {
+ next = CPrec_AppendAlign();
+ CPrec_NewPointerPatch(&current->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(&current->object, CPrec_GetObjBasePatch(nsol->object));
+
+ if (!nsol->next)
+ break;
+
+ if ((addrPatch = CPrec_FindAddrPatch(nsol->next))) {
+ CPrec_NewPointerPatch(&current->next, addrPatch->value);
+ break;
+ } else {
+ next = CPrec_AppendAlign();
+ CPrec_NewPointerPatch(&current->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(&current->name, nsn->name);
+ CPrec_NewPointerPatch(&current->first.object, CPrec_GetObjBasePatch(nsn->first.object));
+ if (nsn->first.next)
+ CPrec_NewPointerPatch(&current->first.next, CPrec_GetNameSpaceObjectListPatch(nsn->first.next));
+
+ if (!nsn->next)
+ break;
+
+ if ((addrPatch = CPrec_FindAddrPatch(nsn->next))) {
+ CPrec_NewPointerPatch(&current->next, addrPatch->value);
+ break;
+ } else {
+ next = CPrec_AppendAlign();
+ CPrec_NewPointerPatch(&current->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(&current->nspace, CPrec_GetNameSpacePatch(nsl->nspace));
+
+ if (!nsl->next)
+ break;
+ next = CPrec_AppendAlign();
+ CPrec_NewPointerPatch(&current->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) {
+}