diff options
Diffstat (limited to 'compiler_and_linker/unsorted')
| -rw-r--r-- | compiler_and_linker/unsorted/CCompiler.c | 255 | ||||
| -rw-r--r-- | compiler_and_linker/unsorted/CError.c | 1096 | ||||
| -rw-r--r-- | compiler_and_linker/unsorted/CInt64.c | 892 | ||||
| -rw-r--r-- | compiler_and_linker/unsorted/CMachine.c | 1499 | ||||
| -rw-r--r-- | compiler_and_linker/unsorted/CPrec.c | 2142 | 
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(¤t->type, CPrec_GetTypePatch(exspec->type)); + +        if (!exspec->next) +            break; +        next = CPrec_AppendAlign(); +        CPrec_NewPointerPatch(¤t->next, next); +        current = next; +        exspec = exspec->next; +    } + +    return first; +} + +static FuncArg *CPrec_GetArgListPatch(FuncArg *lst, Boolean includeNames) { +    // too many register swaps +    AddrPatch *addrPatch; +    FuncArg *first, *current, *next; + +    if ((addrPatch = CPrec_FindAddrPatch(lst))) +        return addrPatch->value; + +    first = current = CPrec_AppendAlign(); +restart: +    if (!includeNames) +        lst->name = NULL; +    CPrec_AppendData(lst, sizeof(FuncArg)); +    if (includeNames && lst->name) +        CPrec_NamePatch(¤t->name, lst->name); + +    if (lst->dexpr) +        CPrec_NewPointerPatch(¤t->dexpr, CPrec_GetExpressionPatch(lst->dexpr)); +    if (lst->type) +        CPrec_NewPointerPatch(¤t->type, CPrec_GetTypePatch(lst->type)); +    else +#line 1167 +        CError_FATAL(); + +    if (lst->next) { +        if ((addrPatch = CPrec_FindAddrPatch(lst->next))) { +            CPrec_NewPointerPatch(¤t->next, addrPatch->value); +        } else { +            next = CPrec_AppendAlign(); +            CPrec_NewPointerPatch(¤t->next, next); +            current = next; +            lst = lst->next; +            CPrec_NewAddrPatch(lst, next); +            goto restart; +        } +    } + +    return first; +} + +static TypeFunc *CPrec_GetTypeFuncPatch(TypeFunc *type) { +    TypeFunc *p = CPrec_AppendAlign(); +    CPrec_NewAddrPatch(type, p); + +    CPrec_AppendData(type, (type->flags & FUNC_FLAGS_METHOD) ? sizeof(TypeMethod) : sizeof(TypeFunc)); + +    CPrec_NewPointerPatch(&p->functype, CPrec_GetTypePatch(type->functype)); +    if (type->args) +        CPrec_NewPointerPatch(&p->args, CPrec_GetArgListPatch(type->args, (type->flags & FUNC_FLAGS_900000) != 0)); +    if (type->exspecs) +        CPrec_NewPointerPatch(&p->exspecs, CPrec_GetExceptSpecPatch(type->exspecs)); +    if (type->flags & FUNC_FLAGS_METHOD) +        CPrec_NewPointerPatch(&TYPE_METHOD(p)->theclass, CPrec_GetTypePatch((Type *) TYPE_METHOD(type)->theclass)); + +    return p; +} + +static TypeMemberPointer *CPrec_GetTypeMemberPointerPatch(TypeMemberPointer *type) { +    TypeMemberPointer *p = CPrec_AppendAlign(); +    CPrec_NewAddrPatch(type, p); + +    CPrec_AppendData(type, sizeof(TypeMemberPointer)); + +    CPrec_NewPointerPatch(&p->ty1, CPrec_GetTypePatch(type->ty1)); +    CPrec_NewPointerPatch(&p->ty2, CPrec_GetTypePatch(type->ty2)); + +    return p; +} + +static TypeTemplDep *CPrec_GetTypeTemplDepPatch(TypeTemplDep *type) { +    TypeTemplDep *p = CPrec_AppendAlign(); +    CPrec_NewAddrPatch(type, p); + +    CPrec_AppendData(type, sizeof(TypeTemplDep)); + +    switch (type->dtype) { +        case TEMPLDEP_ARGUMENT: +            break; +        case TEMPLDEP_QUALNAME: +            CPrec_NewPointerPatch(&p->u.qual.type, CPrec_GetTypeTemplDepPatch(type->u.qual.type)); +            CPrec_NamePatch(&p->u.qual.name, type->u.qual.name); +            break; +        case TEMPLDEP_TEMPLATE: +            CPrec_NewPointerPatch(&p->u.templ.templ, CPrec_GetTypePatch((Type *) type->u.templ.templ)); +            CPrec_NewPointerPatch(&p->u.templ.args, CPrec_GetTemplateArgPatch(type->u.templ.args)); +            break; +        case TEMPLDEP_ARRAY: +            CPrec_NewPointerPatch(&p->u.array.type, CPrec_GetTypePatch(type->u.array.type)); +            CPrec_NewPointerPatch(&p->u.array.index, CPrec_GetExpressionPatch(type->u.array.index)); +            break; +        case TEMPLDEP_QUALTEMPL: +            CPrec_NewPointerPatch(&p->u.qualtempl.type, CPrec_GetTypeTemplDepPatch(type->u.qualtempl.type)); +            CPrec_NewPointerPatch(&p->u.qualtempl.args, CPrec_GetTemplateArgPatch(type->u.qualtempl.args)); +            break; +        case TEMPLDEP_BITFIELD: +            CPrec_NewPointerPatch(&p->u.bitfield.type, CPrec_GetTypePatch(type->u.bitfield.type)); +            CPrec_NewPointerPatch(&p->u.bitfield.size, CPrec_GetExpressionPatch(type->u.bitfield.size)); +            break; +        default: +#line 1295 +            CError_FATAL(); +    } + +    return p; +} + +static ClassList *CPrec_GetClassListPatch(ClassList *cl) { +    AddrPatch *addrPatch; +    ClassList *first, *current, *next; + +    if ((addrPatch = CPrec_FindAddrPatch(cl))) +        return addrPatch->value; + +    first = current = CPrec_AppendAlign(); +    CPrec_NewAddrPatch(cl, first); + +    do { +        CPrec_AppendData(cl, sizeof(ClassList)); +        CPrec_NewPointerPatch(¤t->base, CPrec_GetTypePatch((Type *) cl->base)); + +        if (!cl->next) +            break; + +        if ((addrPatch = CPrec_FindAddrPatch(cl->next))) { +            CPrec_NewPointerPatch(¤t->next, addrPatch->value); +            break; +        } else { +            next = CPrec_AppendAlign(); +            CPrec_NewPointerPatch(¤t->next, next); +            current = next; +            cl = cl->next; +        } +    } while (1); + +    return first; +} + +static VClassList *CPrec_GetVClassListPatch(VClassList *vcl) { +    VClassList *first, *current, *next; +    first = current = CPrec_AppendAlign(); + +    do { +        CPrec_AppendData(vcl, sizeof(VClassList)); +        CPrec_NewPointerPatch(¤t->base, CPrec_GetTypePatch((Type *) vcl->base)); + +        if (!vcl->next) +            break; +        next = CPrec_AppendAlign(); +        CPrec_NewPointerPatch(¤t->next, next); +        current = next; +        vcl = vcl->next; +    } while (1); + +    return first; +} + +static ClassFriend *CPrec_GetClassFriendPatch(ClassFriend *cf) { +    ClassFriend *first, *current, *next; +    first = current = CPrec_AppendAlign(); + +    do { +        CPrec_AppendData(cf, sizeof(ClassFriend)); +        if (cf->isclass) +            CPrec_NewPointerPatch(¤t->u.theclass, CPrec_GetTypePatch((Type *) cf->u.theclass)); +        else +            CPrec_NewPointerPatch(¤t->u.theclass, CPrec_GetObjectPatch(cf->u.obj)); + +        if (!cf->next) +            break; +        next = CPrec_AppendAlign(); +        CPrec_NewPointerPatch(¤t->next, next); +        current = next; +        cf = cf->next; +    } while (1); + +    return first; +} + +static BClassList *CPrec_GetBClassListPatch(BClassList *bcl) { +    BClassList *first, *current, *next; +    first = current = CPrec_AppendAlign(); + +    do { +        CPrec_AppendData(bcl, sizeof(BClassList)); +        CPrec_NewPointerPatch(¤t->type, CPrec_GetTypePatch((Type *) bcl->type)); + +        if (!bcl->next) +            break; +        next = CPrec_AppendAlign(); +        CPrec_NewPointerPatch(¤t->next, next); +        current = next; +        bcl = bcl->next; +    } while (1); + +    return first; +} + +static VTable *CPrec_GetVTablePatch(VTable *vtbl) { +    VTable *p = CPrec_AppendAlign(); +    CPrec_AppendData(vtbl, sizeof(VTable)); + +    if (vtbl->object) +        CPrec_NewPointerPatch(&p->object, CPrec_GetObjectPatch(vtbl->object)); +    if (vtbl->owner) +        CPrec_NewPointerPatch(&p->owner, CPrec_GetTypePatch((Type *) vtbl->owner)); + +    return p; +} + +static SOMReleaseOrder *CPrec_GetSOMReleaseOrderPatch(SOMReleaseOrder *sro) { +    SOMReleaseOrder *first, *current, *next; +    first = current = CPrec_AppendAlign(); + +    do { +        CPrec_AppendData(sro, sizeof(SOMReleaseOrder)); +        CPrec_NamePatch(¤t->name, sro->name); +        if (!sro->next) +            break; +        next = CPrec_AppendAlign(); +        CPrec_NewPointerPatch(¤t->next, next); +        current = next; +        sro = sro->next; +    } while (1); + +    return first; +} + +static SOMInfo *CPrec_GetSOMInfoPatch(SOMInfo *som) { +    SOMInfo *p = CPrec_AppendAlign(); +    CPrec_AppendData(som, sizeof(SOMInfo)); + +    if (som->metaclass) +        CPrec_NewPointerPatch(&p->metaclass, CPrec_GetTypePatch((Type *) som->metaclass)); +    if (som->classdataobject) +        CPrec_NewPointerPatch(&p->classdataobject, CPrec_GetObjectPatch(som->classdataobject)); +    if (som->order) +        CPrec_NewPointerPatch(&p->order, CPrec_GetSOMReleaseOrderPatch(som->order)); + +    return p; +} + +static ObjCMethodArg *CPrec_GetObjCMethodArgPatch(ObjCMethodArg *arg) { +    ObjCMethodArg *first, *current, *next; +    first = current = CPrec_AppendAlign(); + +    do { +        CPrec_AppendData(arg, sizeof(ObjCMethodArg)); +        if (arg->selector) +            CPrec_NamePatch(¤t->selector, arg->selector); +        if (arg->name) +            CPrec_NamePatch(¤t->name, arg->name); +        if (arg->type) +            CPrec_NewPointerPatch(¤t->type, CPrec_GetTypePatch(arg->type)); + +        if (!arg->next) +            break; +        next = CPrec_AppendAlign(); +        CPrec_NewPointerPatch(¤t->next, next); +        current = next; +        arg = arg->next; +    } while (1); + +    return first; +} + +static ObjCMethodList *CPrec_GetObjCMethodListPatch(ObjCMethodList *lst) { +    AddrPatch *addrPatch; +    ObjCMethodList *first, *current, *next; + +    if ((addrPatch = CPrec_FindAddrPatch(lst))) +        return addrPatch->value; + +    first = current = CPrec_AppendAlign(); +    CPrec_NewAddrPatch(lst, first); + +    do { +        CPrec_AppendData(lst, sizeof(ObjCMethodList)); +        if (lst->method) +            CPrec_NewPointerPatch(¤t->method, CPrec_GetObjCMethodPatch(lst->method)); + +        if (!lst->next) +            break; + +        if ((addrPatch = CPrec_FindAddrPatch(lst->next))) { +            CPrec_NewPointerPatch(¤t->next, addrPatch->value); +            break; +        } else { +            next = CPrec_AppendAlign(); +            CPrec_NewPointerPatch(¤t->next, next); +            current = next; +            lst = lst->next; +            CPrec_NewAddrPatch(lst, next); +        } +    } while (1); + +    return first; +} + +static ObjCSelector *CPrec_GetObjCSelectorPatch(ObjCSelector *sel) { +    AddrPatch *addrPatch; +    ObjCSelector *current, *first, *next; + +    if ((addrPatch = CPrec_FindAddrPatch(sel))) +        return addrPatch->value; + +    first = current = CPrec_AppendAlign(); +    CPrec_NewAddrPatch(sel, first); + +    do { +        CPrec_AppendData(sel, sizeof(ObjCSelector)); +        if (sel->selobject) +            CPrec_NewPointerPatch(¤t->selobject, CPrec_GetObjectPatch(sel->selobject)); +        CPrec_NamePatch(¤t->name, sel->name); +        if (sel->methods) +            CPrec_NewPointerPatch(¤t->methods, CPrec_GetObjCMethodListPatch(sel->methods)); + +        if (!sel->next) +            break; + +        if ((addrPatch = CPrec_FindAddrPatch(sel->next))) { +            CPrec_NewPointerPatch(¤t->next, addrPatch->value); +            break; +        } else { +            next = CPrec_AppendAlign(); +            CPrec_NewPointerPatch(¤t->next, next); +            current = next; +            sel = sel->next; +            CPrec_NewAddrPatch(sel, next); +        } +    } while (1); + +    return first; +} + +static ObjCMethod *CPrec_GetObjCMethodPatch(ObjCMethod *meth) { +    // does not match - affected by weirdness where the arg goes into r31 instead of r28 +    AddrPatch *addrPatch; +    ObjCMethod *current, *first, *next; + +    if ((addrPatch = CPrec_FindAddrPatch(meth))) +        return addrPatch->value; + +    first = current = CPrec_AppendAlign(); +    CPrec_NewAddrPatch(meth, first); + +    do { +        CPrec_AppendData(meth, sizeof(ObjCMethod)); +        if (meth->object) +            CPrec_NewPointerPatch(¤t->object, CPrec_GetObjectPatch(meth->object)); +        if (meth->functype) +            CPrec_NewPointerPatch(¤t->functype, CPrec_GetTypePatch((Type *) meth->functype)); +        if (meth->selector) +            CPrec_NewPointerPatch(¤t->selector, CPrec_GetObjCSelectorPatch(meth->selector)); +        if (meth->return_type) +            CPrec_NewPointerPatch(¤t->return_type, CPrec_GetTypePatch(meth->return_type)); +        if (meth->selector_args) +            CPrec_NewPointerPatch(¤t->selector_args, CPrec_GetObjCMethodArgPatch(meth->selector_args)); + +        if (!meth->next) +            break; + +        if ((addrPatch = CPrec_FindAddrPatch(meth->next))) { +            CPrec_NewPointerPatch(¤t->next, addrPatch->value); +            break; +        } else { +            next = CPrec_AppendAlign(); +            CPrec_NewPointerPatch(¤t->next, next); +            current = next; +            meth = meth->next; +            CPrec_NewAddrPatch(meth, next); +        } +    } while (1); + +    return first; +} + +static ObjCProtocol *CPrec_GetObjCProtocolPatch(ObjCProtocol *prot) { +    AddrPatch *addrPatch; +    ObjCProtocol *current, *first, *next; + +    if ((addrPatch = CPrec_FindAddrPatch(prot))) +        return addrPatch->value; + +    first = current = CPrec_AppendAlign(); +    CPrec_NewAddrPatch(prot, first); + +    do { +        CPrec_AppendData(prot, sizeof(ObjCProtocol)); +        CPrec_NamePatch(¤t->name, prot->name); +        if (prot->protocols) +            CPrec_NewPointerPatch(¤t->protocols, CPrec_GetObjCProtocolListPatch(prot->protocols)); +        if (prot->methods) +            CPrec_NewPointerPatch(¤t->methods, CPrec_GetObjCMethodPatch(prot->methods)); +        if (prot->object) +            CPrec_NewPointerPatch(¤t->object, CPrec_GetObjectPatch(prot->object)); + +        if (!prot->next) +            break; + +        if ((addrPatch = CPrec_FindAddrPatch(prot->next))) { +            CPrec_NewPointerPatch(¤t->next, addrPatch->value); +            break; +        } else { +            next = CPrec_AppendAlign(); +            CPrec_NewPointerPatch(¤t->next, next); +            current = next; +            prot = prot->next; +            CPrec_NewAddrPatch(prot, next); +        } +    } while (1); + +    return first; +} + +static ObjCProtocolList *CPrec_GetObjCProtocolListPatch(ObjCProtocolList *lst) { +    AddrPatch *addrPatch; +    ObjCProtocolList *first, *current, *next; + +    if ((addrPatch = CPrec_FindAddrPatch(lst))) +        return addrPatch->value; + +    first = current = CPrec_AppendAlign(); +    CPrec_NewAddrPatch(lst, first); + +    do { +        CPrec_AppendData(lst, sizeof(ObjCProtocolList)); +        CPrec_NewPointerPatch(¤t->protocol, CPrec_GetObjCProtocolPatch(lst->protocol)); + +        if (!lst->next) +            break; + +        next = CPrec_AppendAlign(); +        CPrec_NewPointerPatch(¤t->next, next); +        current = next; +        lst = lst->next; +    } while (1); + +    return first; +} + +static ObjCCategory *CPrec_GetObjCCategoryPatch(ObjCCategory *cat) { +    AddrPatch *addrPatch; +    ObjCCategory *current, *first, *next; + +    if ((addrPatch = CPrec_FindAddrPatch(cat))) +        return addrPatch->value; + +    first = current = CPrec_AppendAlign(); +    CPrec_NewAddrPatch(cat, first); + +    do { +        CPrec_AppendData(cat, sizeof(ObjCCategory)); +        CPrec_NamePatch(¤t->name, cat->name); +        if (cat->protocols) +            CPrec_NewPointerPatch(¤t->protocols, CPrec_GetObjCProtocolListPatch(cat->protocols)); +        if (cat->methods) +            CPrec_NewPointerPatch(¤t->methods, CPrec_GetObjCMethodPatch(cat->methods)); + +        if (!cat->next) +            break; + +        if ((addrPatch = CPrec_FindAddrPatch(cat->next))) { +            CPrec_NewPointerPatch(¤t->next, addrPatch->value); +            break; +        } else { +            next = CPrec_AppendAlign(); +            CPrec_NewPointerPatch(¤t->next, next); +            current = next; +            cat = cat->next; +            CPrec_NewAddrPatch(cat, next); +        } +    } while (1); + +    return first; +} + +static ObjCInfo *CPrec_GetObjCInfoPatch(ObjCInfo *info) { +    ObjCInfo *p = CPrec_AppendAlign(); +    CPrec_AppendData(info, sizeof(ObjCInfo)); + +    if (info->classobject) +        CPrec_NewPointerPatch(&p->classobject, CPrec_GetObjectPatch(info->classobject)); +    if (info->metaobject) +        CPrec_NewPointerPatch(&p->metaobject, CPrec_GetObjectPatch(info->metaobject)); +    if (info->classrefobj) +        CPrec_NewPointerPatch(&p->classrefobj, CPrec_GetObjectPatch(info->classrefobj)); +    if (info->methods) +        CPrec_NewPointerPatch(&p->methods, CPrec_GetObjCMethodPatch(info->methods)); +    if (info->protocols) +        CPrec_NewPointerPatch(&p->protocols, CPrec_GetObjCProtocolListPatch(info->protocols)); +    if (info->categories) +        CPrec_NewPointerPatch(&p->categories, CPrec_GetObjCCategoryPatch(info->categories)); + +    return p; +} + +static TemplArg *CPrec_GetTemplateArgPatch(TemplArg *arg) { +    TemplArg *first, *current, *next; +    first = current = CPrec_AppendAlign(); + +    do { +        CPrec_AppendData(arg, sizeof(TemplArg)); +        switch (arg->pid.type) { +            case TPT_TYPE: +                if (arg->data.typeparam.type) +                    CPrec_NewPointerPatch(¤t->data.typeparam.type, CPrec_GetTypePatch(arg->data.typeparam.type)); +                break; +            case TPT_NONTYPE: +                if (arg->data.paramdecl.expr) +                    CPrec_NewPointerPatch(¤t->data.paramdecl.expr, CPrec_GetExpressionPatch(arg->data.paramdecl.expr)); +                break; +            case TPT_TEMPLATE: +                if (arg->data.ttargtype) +                    CPrec_NewPointerPatch(¤t->data.ttargtype, CPrec_GetTypePatch(arg->data.ttargtype)); +                break; +            default: +#line 1879 +                CError_FATAL(); +        } + +        if (!arg->next) +            break; +        next = CPrec_AppendAlign(); +        CPrec_NewPointerPatch(¤t->next, next); +        current = next; +        arg = arg->next; +    } while (1); + +    return first; +} + +static TemplParam *CPrec_GetTemplateParamPatch(TemplParam *param) { +    // register swap issues +    TemplParam *first, *current, *next; +    first = current = CPrec_AppendAlign(); + +    do { +        CPrec_AppendData(param, sizeof(TemplParam)); +        if (param->name) +            CPrec_NamePatch(¤t->name, param->name); + +        switch (param->pid.type) { +            case TPT_TYPE: +                if (param->data.typeparam.type) +                    CPrec_NewPointerPatch(¤t->data.typeparam.type, CPrec_GetTypePatch(param->data.typeparam.type)); +                break; +            case TPT_NONTYPE: +                CPrec_NewPointerPatch(¤t->data.paramdecl.type, CPrec_GetTypePatch(param->data.paramdecl.type)); +                if (param->data.paramdecl.defaultarg) +                    CPrec_NewPointerPatch(¤t->data.paramdecl.defaultarg, CPrec_GetExpressionPatch(param->data.paramdecl.defaultarg)); +                break; +            case TPT_TEMPLATE: +                if (param->data.templparam.plist) +                    CPrec_NewPointerPatch(¤t->data.templparam.plist, CPrec_GetTemplateParamPatch(param->data.templparam.plist)); +#line 1953 +                CError_ASSERT(!param->data.templparam.defaultarg); +                break; +            default: +#line 1958 +                CError_FATAL(); +        } + +        if (!param->next) +            break; +        next = CPrec_AppendAlign(); +        CPrec_NewPointerPatch(¤t->next, next); +        current = next; +        param = param->next; +    } while (1); + +    return first; +} + +static TStreamElement *CPrec_GetTStreamPatch(TStreamElement *tokens, SInt32 count) { +    TStreamElement elem; +    TStreamElement *first, *current, *scan; +    SInt32 x; + +    scan = tokens; +    x = 0; +    while (x < count) { +        elem = *scan; +        memclrw(scan, sizeof(TStreamElement)); + +        scan->tokentype = elem.tokentype; +        switch (elem.tokentype) { +            case TK_IDENTIFIER: +                scan->data.tkidentifier = elem.data.tkidentifier; +                break; +            case TK_INTCONST: +                scan->subtype = elem.subtype; +                scan->data.tkintconst = elem.data.tkintconst; +                break; +            case TK_FLOATCONST: +                scan->subtype = elem.subtype; +                scan->data.tkfloatconst = elem.data.tkfloatconst; +                break; +            case TK_STRING: +            case TK_STRING_WIDE: +                scan->subtype = elem.subtype; +                scan->data.tkstring = elem.data.tkstring; +                break; +        } +        x++; +        scan++; +    } + +    first = current = CPrec_AppendAlign(); +    CPrec_AppendData(tokens, count * sizeof(TStreamElement)); + +    if (cprec_dowrite) { +        TokenPatch *tp = lalloc(sizeof(TokenPatch)); +        tp->tokens = current; +        tp->count = count; +        tp->next = cprec_tokenpatches; +        cprec_tokenpatches = tp; +    } + +    x = 0; +    while (x < count) { +        switch (tokens->tokentype) { +            case TK_IDENTIFIER: +                CPrec_NamePatch(¤t->data.tkidentifier, tokens->data.tkidentifier); +                break; +            case TK_INTCONST: +            case TK_FLOATCONST: +                break; +            case TK_STRING: +            case TK_STRING_WIDE: +                CPrec_RawMemPatch(¤t->data.tkstring.data, tokens->data.tkstring.data, tokens->data.tkstring.size); +                break; +            case TK_NEG7: +                break; +            default: +                if (tokens->tokentype < 0) +#line 2063 +                    CError_FATAL(); +        } +        x++; +        tokens++; +        current++; +    } + +    return first; +} + +static TemplFuncInstance *CPrec_GetTemplFuncInstancePatch(TemplFuncInstance *inst) { +    AddrPatch *addrPatch; +    TemplFuncInstance *first, *current, *next; + +    if ((addrPatch = CPrec_FindAddrPatch(inst))) +        return addrPatch->value; + +    first = current = CPrec_AppendAlign(); +    CPrec_NewAddrPatch(inst, first); + +    do { +        CPrec_AppendData(inst, sizeof(TemplFuncInstance)); +        CPrec_NewPointerPatch(¤t->object, CPrec_GetObjectPatch(inst->object)); +        CPrec_NewPointerPatch(¤t->args, CPrec_GetTemplateArgPatch(inst->args)); + +        if (!inst->next) +            break; + +        if ((addrPatch = CPrec_FindAddrPatch(inst->next))) { +            CPrec_NewPointerPatch(¤t->next, addrPatch->value); +            break; +        } else { +            next = CPrec_AppendAlign(); +            CPrec_NewPointerPatch(¤t->next, next); +            current = next; +            inst = inst->next; +            CPrec_NewAddrPatch(inst, next); +        } +    } while (1); + +    return first; +} + +static TemplateMember *CPrec_GetTemplateMemberPatch(TemplateMember *memb) { +    TemplateMember *current, *first, *next; +    first = current = CPrec_AppendAlign(); + +    do { +        memclrw(&memb->fileoffset, sizeof(FileOffsetInfo)); +        memb->srcfile = NULL; +        memb->startoffset = 0; +        memb->endoffset = 0; + +        CPrec_AppendData(memb, sizeof(TemplateMember)); +        if (memb->params) +            CPrec_NewPointerPatch(¤t->params, CPrec_GetTemplateParamPatch(memb->params)); +        CPrec_NewPointerPatch(¤t->object, CPrec_GetObjectPatch(memb->object)); +        if (memb->stream.firsttoken) +            CPrec_NewPointerPatch(¤t->stream.firsttoken, CPrec_GetTStreamPatch(memb->stream.firsttoken, memb->stream.tokens)); + +        if (!memb->next) +            break; +        next = CPrec_AppendAlign(); +        CPrec_NewPointerPatch(¤t->next, next); +        current = next; +        memb = memb->next; +    } while (1); + +    return first; +} + +static TemplPartialSpec *CPrec_GetTemplPartialSpecPatch(TemplPartialSpec *pspec) { +    TemplPartialSpec *first, *current, *next; +    first = current = CPrec_AppendAlign(); + +    do { +        CPrec_AppendData(pspec, sizeof(TemplPartialSpec)); +        if (pspec->templ) +            CPrec_NewPointerPatch(¤t->templ, CPrec_GetTypePatch((Type *) pspec->templ)); +        if (pspec->args) +            CPrec_NewPointerPatch(¤t->args, CPrec_GetTemplateArgPatch(pspec->args)); + +        if (!pspec->next) +            break; +        next = CPrec_AppendAlign(); +        CPrec_NewPointerPatch(¤t->next, next); +        current = next; +        pspec = pspec->next; +    } while (1); + +    return first; +} + +static TemplateFriend *CPrec_GetTemplateFriendPatch(TemplateFriend *frnd) { +    TemplateFriend *p; + +    memclrw(&frnd->fileoffset, sizeof(FileOffsetInfo)); +    p = CPrec_AppendAlign(); +    CPrec_AppendData(frnd, sizeof(TemplateFriend)); + +    if (frnd->decl.thetype) +        CPrec_NewPointerPatch(&p->decl.thetype, CPrec_GetTypePatch(frnd->decl.thetype)); +    if (frnd->decl.nspace) +        CPrec_NewPointerPatch(&p->decl.nspace, CPrec_GetNameSpacePatch(frnd->decl.nspace)); +    if (frnd->decl.name) +        CPrec_NamePatch(&p->decl.name, frnd->decl.name); +    if (frnd->decl.expltargs) +        CPrec_NewPointerPatch(&p->decl.expltargs, CPrec_GetTemplateArgPatch(frnd->decl.expltargs)); +    if (frnd->stream.firsttoken) +        CPrec_NewPointerPatch(&p->stream.firsttoken, CPrec_GetTStreamPatch(frnd->stream.firsttoken, frnd->stream.tokens)); + +    return p; +} + +static TemplateAction *CPrec_GetTemplateActionPatch(TemplateAction *act) { +    // register swap issue +    TemplateAction *current, *first, *next; +    first = current = CPrec_AppendAlign(); + +    do { +        memclrw(&act->source_ref, sizeof(TStreamElement)); +        CPrec_AppendData(act, sizeof(TemplateAction)); + +        switch (act->type) { +            case TAT_NESTEDCLASS: +                CPrec_NewPointerPatch(¤t->u.tclasstype, CPrec_GetTypePatch((Type *) act->u.tclasstype)); +                break; +            case TAT_ENUMTYPE: +                CPrec_NewPointerPatch(¤t->u.enumtype, CPrec_GetTypePatch((Type *) act->u.enumtype)); +                break; +            case TAT_FRIEND: +                CPrec_NewPointerPatch(¤t->u.tfriend, CPrec_GetTemplateFriendPatch(act->u.tfriend)); +                break; +            case TAT_ENUMERATOR: +                CPrec_NewPointerPatch(¤t->u.enumerator.objenumconst, CPrec_GetObjEnumConstPatch(act->u.enumerator.objenumconst)); +                if (act->u.enumerator.initexpr) +                    CPrec_NewPointerPatch(¤t->u.enumerator.initexpr, CPrec_GetExpressionPatch(act->u.enumerator.initexpr)); +                break; +            case TAT_BASE: +                CPrec_NewPointerPatch(¤t->u.base.type, CPrec_GetTypePatch(act->u.base.type)); +                if (act->u.base.insert_after) +                    CPrec_NewPointerPatch(¤t->u.base.insert_after, CPrec_GetClassListPatch(act->u.base.insert_after)); +                break; +            case TAT_OBJECTINIT: +                CPrec_NewPointerPatch(¤t->u.objectinit.object, CPrec_GetObjectPatch(act->u.objectinit.object)); +                CPrec_NewPointerPatch(¤t->u.objectinit.initexpr, CPrec_GetExpressionPatch(act->u.objectinit.initexpr)); +                break; +            case TAT_USINGDECL: +                CPrec_NewPointerPatch(¤t->u.usingdecl.type, CPrec_GetTypeTemplDepPatch(act->u.usingdecl.type)); +                break; +            case TAT_OBJECTDEF: +                CPrec_NewPointerPatch(¤t->u.refobj, CPrec_GetObjBasePatch(act->u.refobj)); +                break; +            default: +#line 2410 +                CError_FATAL(); +        } + +        if (!act->next) +            break; +        next = CPrec_AppendAlign(); +        CPrec_NewPointerPatch(¤t->next, next); +        current = next; +        act = act->next; +    } while (1); + +    return first; +} + +static TemplateFunction *CPrec_GetTemplateFunctionPatch(TemplateFunction *tf) { +    // the same cursed register swaps +    AddrPatch *addrPatch; +    TemplateFunction *first, *current, *next; + +    if ((addrPatch = CPrec_FindAddrPatch(tf))) +        return addrPatch->value; + +    first = current = CPrec_AppendAlign(); +    CPrec_NewAddrPatch(tf, first); + +    do { +        memclrw(&tf->deftoken, sizeof(TStreamElement)); +        tf->srcfile = NULL; +        tf->startoffset = 0; +        tf->endoffset = 0; + +        CPrec_AppendData(tf, sizeof(TemplateFunction)); +        if (tf->unk4) +            CPrec_NewPointerPatch(¤t->unk4, CPrec_GetTemplateFunctionPatch(tf->unk4)); +        CPrec_NamePatch(¤t->name, tf->name); +        if (tf->params) +            CPrec_NewPointerPatch(¤t->params, CPrec_GetTemplateParamPatch(tf->params)); +        if (tf->stream.firsttoken) +            CPrec_NewPointerPatch(¤t->stream.firsttoken, CPrec_GetTStreamPatch(tf->stream.firsttoken, tf->stream.tokens)); +        CPrec_NewPointerPatch(¤t->tfunc, CPrec_GetObjectPatch(tf->tfunc)); +        if (tf->instances) +            CPrec_NewPointerPatch(¤t->instances, CPrec_GetTemplFuncInstancePatch(tf->instances)); + +        if (!tf->next) +            break; + +        if ((addrPatch = CPrec_FindAddrPatch(tf->next))) { +            CPrec_NewPointerPatch(¤t->next, addrPatch->value); +            break; +        } else { +            next = CPrec_AppendAlign(); +            CPrec_NewPointerPatch(¤t->next, next); +            current = next; +            tf = tf->next; +            CPrec_NewAddrPatch(tf, next); +        } +    } while (1); + +    return first; +} + +static TypeClass *CPrec_GetTypeClassPatch(TypeClass *tclass) { +    TypeClass *first, *current, *next; +    Boolean hasNextTempl, hasNextTemplInst; +    first = current = CPrec_AppendAlign(); + +    do_over: +    hasNextTempl = hasNextTemplInst = 0; +    CPrec_NewAddrPatch(tclass, current); + +    if (tclass->flags & CLASS_FLAGS_100) { +        // template class +        CPrec_AppendData(tclass, sizeof(TemplClass)); +        if (TEMPL_CLASS(tclass)->next) +            hasNextTempl = 1; +        if (TEMPL_CLASS(tclass)->templ__parent) +            CPrec_NewPointerPatch(&TEMPL_CLASS(current)->templ__parent, CPrec_GetTypePatch((Type *) TEMPL_CLASS(tclass)->templ__parent)); +        if (TEMPL_CLASS(tclass)->x3A_maybe_parentinst) +            CPrec_NewPointerPatch(&TEMPL_CLASS(current)->x3A_maybe_parentinst, CPrec_GetTypePatch((Type *) TEMPL_CLASS(tclass)->x3A_maybe_parentinst)); +        if (TEMPL_CLASS(tclass)->templ__params) +            CPrec_NewPointerPatch(&TEMPL_CLASS(current)->templ__params, CPrec_GetTemplateParamPatch(TEMPL_CLASS(tclass)->templ__params)); +        if (TEMPL_CLASS(tclass)->members) +            CPrec_NewPointerPatch(&TEMPL_CLASS(current)->members, CPrec_GetTemplateMemberPatch(TEMPL_CLASS(tclass)->members)); +        if (TEMPL_CLASS(tclass)->instances) +            CPrec_NewPointerPatch(&TEMPL_CLASS(current)->instances, CPrec_GetTypePatch((Type *) TEMPL_CLASS(tclass)->instances)); +        if (TEMPL_CLASS(tclass)->pspec_owner) +            CPrec_NewPointerPatch(&TEMPL_CLASS(current)->pspec_owner, CPrec_GetTypePatch((Type *) TEMPL_CLASS(tclass)->pspec_owner)); +        if (TEMPL_CLASS(tclass)->pspecs) +            CPrec_NewPointerPatch(&TEMPL_CLASS(current)->pspecs, CPrec_GetTemplPartialSpecPatch(TEMPL_CLASS(tclass)->pspecs)); +        if (TEMPL_CLASS(tclass)->actions) +            CPrec_NewPointerPatch(&TEMPL_CLASS(current)->actions, CPrec_GetTemplateActionPatch(TEMPL_CLASS(tclass)->actions)); +    } else if (tclass->flags & CLASS_FLAGS_800) { +        // template class instance +        CPrec_AppendData(tclass, sizeof(TemplClassInst)); +        if (TEMPL_CLASS_INST(tclass)->next) +            hasNextTemplInst = 1; +        if (TEMPL_CLASS_INST(tclass)->x36) +            CPrec_NewPointerPatch(&TEMPL_CLASS_INST(current)->x36, CPrec_GetTypePatch((Type *) TEMPL_CLASS_INST(tclass)->x36)); +        if (TEMPL_CLASS_INST(tclass)->templ) +            CPrec_NewPointerPatch(&TEMPL_CLASS_INST(current)->templ, CPrec_GetTypePatch((Type *) TEMPL_CLASS_INST(tclass)->templ)); +        if (TEMPL_CLASS_INST(tclass)->inst_args) +            CPrec_NewPointerPatch(&TEMPL_CLASS_INST(current)->inst_args, CPrec_GetTemplateArgPatch(TEMPL_CLASS_INST(tclass)->inst_args)); +        if (TEMPL_CLASS_INST(tclass)->oargs) +            CPrec_NewPointerPatch(&TEMPL_CLASS_INST(current)->oargs, CPrec_GetTemplateArgPatch(TEMPL_CLASS_INST(tclass)->oargs)); +    } else { +        // base +        CPrec_AppendData(tclass, sizeof(TypeClass)); +    } + +    if (tclass->nspace) +        CPrec_NewPointerPatch(¤t->nspace, CPrec_GetNameSpacePatch(tclass->nspace)); +    if (tclass->classname) +        CPrec_NamePatch(¤t->classname, tclass->classname); +    if (tclass->bases) +        CPrec_NewPointerPatch(¤t->bases, CPrec_GetClassListPatch(tclass->bases)); +    if (tclass->vbases) +        CPrec_NewPointerPatch(¤t->vbases, CPrec_GetVClassListPatch(tclass->vbases)); +    if (tclass->ivars) +        CPrec_NewPointerPatch(¤t->ivars, CPrec_GetObjMemberVarPatch(tclass->ivars)); +    if (tclass->friends) +        CPrec_NewPointerPatch(¤t->friends, CPrec_GetClassFriendPatch(tclass->friends)); +    if (tclass->vtable) +        CPrec_NewPointerPatch(¤t->vtable, CPrec_GetVTablePatch(tclass->vtable)); +    if (tclass->sominfo) +        CPrec_NewPointerPatch(¤t->sominfo, CPrec_GetSOMInfoPatch(tclass->sominfo)); +    if (tclass->objcinfo) +        CPrec_NewPointerPatch(¤t->objcinfo, CPrec_GetObjCInfoPatch(tclass->objcinfo)); + +    if (hasNextTempl) { +        AddrPatch *addrPatch = CPrec_FindAddrPatch(TEMPL_CLASS(tclass)->next); +        if (!addrPatch) { +            next = CPrec_AppendAlign(); +            CPrec_NewPointerPatch(&TEMPL_CLASS(current)->next, next); +            current = next; +            tclass = (TypeClass *) TEMPL_CLASS(tclass)->next; +            goto do_over; +        } else { +            CPrec_NewPointerPatch(&TEMPL_CLASS(current)->next, addrPatch->value); +        } +    } + +    if (hasNextTemplInst) { +        AddrPatch *addrPatch = CPrec_FindAddrPatch(TEMPL_CLASS_INST(tclass)->next); +        if (!addrPatch) { +            next = CPrec_AppendAlign(); +            CPrec_NewPointerPatch(&TEMPL_CLASS_INST(current)->next, next); +            current = next; +            tclass = (TypeClass *) TEMPL_CLASS_INST(tclass)->next; +            goto do_over; +        } else { +            CPrec_NewPointerPatch(&TEMPL_CLASS_INST(current)->next, addrPatch->value); +        } +    } + +    return first; +} + +static Type *CPrec_GetTypePatch(Type *type) { +    AddrPatch *addrPatch = CPrec_FindAddrPatch(type); +    if (addrPatch) +        return addrPatch->value; + +    switch (type->type) { +        case TYPEPOINTER: +        case TYPEARRAY: +            return (Type *) CPrec_GetTypePointerPatch(TYPE_POINTER(type)); +        case TYPEENUM: +            return (Type *) CPrec_GetTypeEnumPatch(TYPE_ENUM(type)); +        case TYPEBITFIELD: +            return (Type *) CPrec_GetTypeBitfieldPatch(TYPE_BITFIELD(type)); +        case TYPESTRUCT: +            return (Type *) CPrec_GetTypeStructPatch(TYPE_STRUCT(type)); +        case TYPEFUNC: +            return (Type *) CPrec_GetTypeFuncPatch(TYPE_FUNC(type)); +        case TYPEMEMBERPOINTER: +            return (Type *) CPrec_GetTypeMemberPointerPatch(TYPE_MEMBER_POINTER(type)); +        case TYPETEMPLATE: +            return (Type *) CPrec_GetTypeTemplDepPatch(TYPE_TEMPLATE(type)); +        case TYPECLASS: +            return (Type *) CPrec_GetTypeClassPatch(TYPE_CLASS(type)); +        case TYPEVOID: +        case TYPEINT: +        case TYPEFLOAT: +        case TYPELABEL: +        case TYPEOBJCID: +        case TYPETEMPLDEPEXPR: +        default: +#line 2796 +            CError_FATAL(); +            return NULL; +    } +} + +static ExceptionAction *CPrec_GetExceptionPatch(ExceptionAction *exc) { +    ExceptionAction *first, *current, *next; + +    first = current = CPrec_AppendAlign(); +repeat: +    CPrec_AppendData(exc, sizeof(ExceptionAction)); +    switch (exc->type) { +        case EAT_DESTROYLOCAL: +            CPrec_NewPointerPatch(¤t->data.destroy_local.dtor, CPrec_GetObjectPatch(exc->data.destroy_local.dtor)); +            break; +        case EAT_DESTROYLOCALCOND: +            CPrec_NewPointerPatch(¤t->data.destroy_local_cond.dtor, CPrec_GetObjectPatch(exc->data.destroy_local_cond.dtor)); +            break; +        case EAT_DESTROYLOCALOFFSET: +            CPrec_NewPointerPatch(¤t->data.destroy_local_offset.dtor, CPrec_GetObjectPatch(exc->data.destroy_local_offset.dtor)); +            break; +        case EAT_DESTROYLOCALPOINTER: +            CPrec_NewPointerPatch(¤t->data.destroy_local_pointer.dtor, CPrec_GetObjectPatch(exc->data.destroy_local_pointer.dtor)); +            break; +        case EAT_DESTROYLOCALARRAY: +            CPrec_NewPointerPatch(¤t->data.destroy_local_array.dtor, CPrec_GetObjectPatch(exc->data.destroy_local_array.dtor)); +            break; +        case EAT_DESTROYPARTIALARRAY: +            break; +        case EAT_DESTROYMEMBER: +        case EAT_DESTROYBASE: +            CPrec_NewPointerPatch(¤t->data.destroy_member.dtor, CPrec_GetObjectPatch(exc->data.destroy_member.dtor)); +            break; +        case EAT_DESTROYMEMBERCOND: +            CPrec_NewPointerPatch(¤t->data.destroy_member_cond.dtor, CPrec_GetObjectPatch(exc->data.destroy_member_cond.dtor)); +            break; +        case EAT_DESTROYMEMBERARRAY: +            CPrec_NewPointerPatch(¤t->data.destroy_member_array.dtor, CPrec_GetObjectPatch(exc->data.destroy_member_array.dtor)); +            break; +        case EAT_DELETEPOINTER: +        case EAT_DELETELOCALPOINTER: +            CPrec_NewPointerPatch(¤t->data.delete_pointer.deletefunc, CPrec_GetObjectPatch(exc->data.delete_pointer.deletefunc)); +            break; +        case EAT_DELETEPOINTERCOND: +            CPrec_NewPointerPatch(¤t->data.delete_pointer_cond.deletefunc, CPrec_GetObjectPatch(exc->data.delete_pointer_cond.deletefunc)); +            break; +        case EAT_CATCHBLOCK: +            if (exc->data.catch_block.catch_typeid) { +                CPrec_NewPointerPatch(¤t->data.catch_block.catch_typeid, CPrec_GetObjectPatch(exc->data.catch_block.catch_typeid)); +                CPrec_NewPointerPatch(¤t->data.catch_block.catch_type, CPrec_GetTypePatch(exc->data.catch_block.catch_type)); +            } +            break; +        case EAT_ACTIVECATCHBLOCK: +            break; +        case EAT_SPECIFICATION: +            if (exc->data.specification.unexp_id) { +                int x; +                char *ptrs; +                ptrs = CPrec_AppendAlign(); +                CPrec_NewPointerPatch(¤t->data.specification.unexp_id, ptrs); +                CPrec_AppendData(exc->data.specification.unexp_id, sizeof(Object *) * exc->data.specification.unexp_ids); +                for (x = 0; x < exc->data.specification.unexp_ids; x++) { +                    CPrec_NewPointerPatch(ptrs + x * sizeof(Object *), CPrec_GetObjectPatch(exc->data.specification.unexp_id[x])); +                } +            } +            break; +        case EAT_TERMINATE: +            break; +        default: +#line 2905 +            CError_FATAL(); +    } + +    if (exc->prev) { +        next = CPrec_AppendAlign(); +        CPrec_NewPointerPatch(¤t->prev, next); +        current = next; +        exc = exc->prev; +        goto repeat; +    } +    return first; +} + +static ENodeList *CPrec_GetExpressionListPatch(ENodeList *lst) { +    ENodeList *first, *current, *next; +    first = current = CPrec_AppendAlign(); + +    do { +        CPrec_AppendData(lst, sizeof(ENodeList)); +        CPrec_NewPointerPatch(¤t->node, CPrec_GetExpressionPatch(lst->node)); + +        if (!lst->next) +            break; +        next = CPrec_AppendAlign(); +        CPrec_NewPointerPatch(¤t->next, next); +        current = next; +        lst = lst->next; +    } while (1); + +    return first; +} + +static void CPrec_GetEMemberInfoPatch() {} + +static ENode *CPrec_GetExpressionPatch(ENode *enode) { + +} + +static void CPrec_GetSwitchInfoPatch() {} +static void CPrec_GetInlineAsmPatch() {} +static void CPrec_GetStatementPatch() {} +static void CPrec_GetLocObjectPatch() {} +static void CPrec_GetInlineFuncPatch() {} + +static ObjEnumConst *CPrec_GetObjEnumConstPatch(ObjEnumConst *obj) { +    AddrPatch *addrPatch; +    ObjEnumConst *first, *current, *next; + +    if ((addrPatch = CPrec_FindAddrPatch(obj))) +        return addrPatch->value; + +    first = current = CPrec_AppendAlign(); +    CPrec_NewAddrPatch(obj, first); + +    do { +        CPrec_AppendData(obj, sizeof(ObjEnumConst)); +        if (cprec_dowrite) { +#line 3349 +            CError_ASSERT(obj->access != 255); +            obj->access = 255; +        } +        CPrec_NamePatch(¤t->name, obj->name); +        CPrec_NewPointerPatch(¤t->type, CPrec_GetTypePatch( obj->type)); + +        if (!obj->next) +            break; + +        if ((addrPatch = CPrec_FindAddrPatch(obj->next))) { +            CPrec_NewPointerPatch(¤t->next, addrPatch->value); +            break; +        } else { +            next = CPrec_AppendAlign(); +            CPrec_NewPointerPatch(¤t->next, next); +            current = next; +            obj = obj->next; +            CPrec_NewAddrPatch(obj, next); +        } +    } while (1); + +    return first; +} + +static ObjType *CPrec_GetObjTypePatch(ObjType *obj) { +    AddrPatch *addrPatch; +    ObjType *p; + +    if ((addrPatch = CPrec_FindAddrPatch(obj))) +        return addrPatch->value; + +    p = CPrec_AppendAlign(); +    CPrec_NewAddrPatch(obj, p); +    CPrec_AppendData(obj, sizeof(ObjType)); +    CPrec_NewPointerPatch(&p->type, CPrec_GetTypePatch(obj->type)); +    return p; +} + +static ObjTypeTag *CPrec_GetObjTypeTagPatch(ObjTypeTag *obj) { +    AddrPatch *addrPatch; +    ObjTypeTag *p; + +    if ((addrPatch = CPrec_FindAddrPatch(obj))) +        return addrPatch->value; + +    p = CPrec_AppendAlign(); +    CPrec_NewAddrPatch(obj, p); +    CPrec_AppendData(obj, sizeof(ObjTypeTag)); +    CPrec_NewPointerPatch(&p->type, CPrec_GetTypePatch(obj->type)); +    return p; +} + +static ObjNameSpace *CPrec_GetObjNameSpacePatch(ObjNameSpace *obj) { +    AddrPatch *addrPatch; +    ObjNameSpace *p; + +    if ((addrPatch = CPrec_FindAddrPatch(obj))) +        return addrPatch->value; + +    p = CPrec_AppendAlign(); +    CPrec_NewAddrPatch(obj, p); +    CPrec_AppendData(obj, sizeof(ObjNameSpace)); +    CPrec_NewPointerPatch(&p->nspace, CPrec_GetNameSpacePatch(obj->nspace)); +    return p; +} + +static ObjMemberVar *CPrec_GetObjMemberVarPatch(ObjMemberVar *obj) { + +} + +static DefArgCtorInfo *CPrec_GetDefArgCtorInfoPatch(DefArgCtorInfo *dac) { +    DefArgCtorInfo *p = CPrec_AppendAlign(); +    CPrec_AppendData(dac, sizeof(DefArgCtorInfo)); +    CPrec_NewPointerPatch(&p->default_func, CPrec_GetObjectPatch(dac->default_func)); +    CPrec_NewPointerPatch(&p->default_arg, CPrec_GetExpressionPatch(dac->default_arg)); +    return p; +} + +static InlineXRef *CPrec_GetInlineXRefPatch(InlineXRef *ix) { +    InlineXRef *first, *current, *next; +    first = current = CPrec_AppendAlign(); + +    do { +        CPrec_AppendData(ix, sizeof(InlineXRef) + sizeof(XRefOffset) * (ix->numxrefs - 1)); +        CPrec_NewPointerPatch(¤t->object, CPrec_GetObjectPatch(ix->object)); + +        if (!ix->next) +            break; +        next = CPrec_AppendAlign(); +        CPrec_NewPointerPatch(¤t->next, next); +        current = next; +        ix = ix->next; +    } while (1); + +    return first; +} + +static Object *CPrec_GetObjectPatch(Object *o) { + +} + +static ObjBase *CPrec_GetObjBasePatch(ObjBase *obj) { +    switch (obj->otype) { +        default: +#line 3694 +            CError_FATAL(); +        case OT_ENUMCONST: +            return (ObjBase *) CPrec_GetObjEnumConstPatch((ObjEnumConst *) obj); +        case OT_TYPE: +            return (ObjBase *) CPrec_GetObjTypePatch((ObjType *) obj); +        case OT_TYPETAG: +            return (ObjBase *) CPrec_GetObjTypeTagPatch((ObjTypeTag *) obj); +        case OT_NAMESPACE: +            return (ObjBase *) CPrec_GetObjNameSpacePatch((ObjNameSpace *) obj); +        case OT_MEMBERVAR: +            return (ObjBase *) CPrec_GetObjMemberVarPatch((ObjMemberVar *) obj); +        case OT_OBJECT: +            return (ObjBase *) CPrec_GetObjectPatch((Object *) obj); +    } +} + +static ObjectList *CPrec_GetObjectListPatch(ObjectList *ol) { +    AddrPatch *addrPatch; +    ObjectList *first, *current, *next; + +    if ((addrPatch = CPrec_FindAddrPatch(ol))) +        return addrPatch->value; + +    first = current = CPrec_AppendAlign(); +    CPrec_NewAddrPatch(ol, first); +restart: +    CPrec_AppendData(ol, sizeof(ObjectList)); +    CPrec_NewPointerPatch(¤t->object, CPrec_GetObjectPatch(ol->object)); +    if (ol->next) { +        next = CPrec_AppendAlign(); +        CPrec_NewPointerPatch(¤t->next, next); +        current = next; +        ol = ol->next; +        goto restart; +    } + +    return first; +} + +static NameSpaceObjectList *CPrec_GetNameSpaceObjectListPatch(NameSpaceObjectList *nsol) { +    AddrPatch *addrPatch; +    NameSpaceObjectList *first, *current, *next; + +    if ((addrPatch = CPrec_FindAddrPatch(nsol))) +        return addrPatch->value; + +    first = current = CPrec_AppendAlign(); +    CPrec_NewAddrPatch(nsol, first); + +    do { +        CPrec_AppendData(nsol, sizeof(NameSpaceObjectList)); +        CPrec_NewPointerPatch(¤t->object, CPrec_GetObjBasePatch(nsol->object)); + +        if (!nsol->next) +            break; + +        if ((addrPatch = CPrec_FindAddrPatch(nsol->next))) { +            CPrec_NewPointerPatch(¤t->next, addrPatch->value); +            break; +        } else { +            next = CPrec_AppendAlign(); +            CPrec_NewPointerPatch(¤t->next, next); +            current = next; +            nsol = nsol->next; +            CPrec_NewAddrPatch(nsol, next); +        } +    } while (1); + +    return first; +} + +static NameSpaceName *CPrec_GetNameSpaceNamePatch(NameSpaceName *nsn, Boolean flag) { +    AddrPatch *addrPatch; +    NameSpaceName *first, *current, *next; + +    if ((addrPatch = CPrec_FindAddrPatch(nsn))) +        return addrPatch->value; + +    first = current = CPrec_AppendAlign(); +    CPrec_NewAddrPatch(nsn, first); + +    do { +        CPrec_AppendData(nsn, sizeof(NameSpaceName)); +        CPrec_NamePatch(¤t->name, nsn->name); +        CPrec_NewPointerPatch(¤t->first.object, CPrec_GetObjBasePatch(nsn->first.object)); +        if (nsn->first.next) +            CPrec_NewPointerPatch(¤t->first.next, CPrec_GetNameSpaceObjectListPatch(nsn->first.next)); + +        if (!nsn->next) +            break; + +        if ((addrPatch = CPrec_FindAddrPatch(nsn->next))) { +            CPrec_NewPointerPatch(¤t->next, addrPatch->value); +            break; +        } else { +            next = CPrec_AppendAlign(); +            CPrec_NewPointerPatch(¤t->next, next); +            current = next; +            nsn = nsn->next; +            CPrec_NewAddrPatch(nsn, next); +        } +    } while (!flag || !cprec_dowrite || CPrec_FlushBufferCheck() == noErr); + +    return first; +} + +static NameSpaceList *CPrec_GetNameSpaceListPatch(NameSpaceList *nsl) { +    NameSpaceList *first, *current, *next; +    first = current = CPrec_AppendAlign(); + +    do { +        CPrec_AppendData(nsl, sizeof(NameSpaceList)); +        CPrec_NewPointerPatch(¤t->nspace, CPrec_GetNameSpacePatch(nsl->nspace)); + +        if (!nsl->next) +            break; +        next = CPrec_AppendAlign(); +        CPrec_NewPointerPatch(¤t->next, next); +        current = next; +        nsl = nsl->next; +    } while (1); + +    return first; +} + +static NameSpace *CPrec_GetNameSpacePatch(NameSpace *nspace) { +    NameSpace *p; +    AddrPatch *addrPatch; + +    if ((addrPatch = CPrec_FindAddrPatch(nspace))) +        return addrPatch->value; + +    p = CPrec_AppendAlign(); +    CPrec_NewAddrPatch(nspace, p); +    CPrec_AppendData(nspace, sizeof(NameSpace)); + +    if (nspace->parent) +        CPrec_NewPointerPatch(&p->parent, CPrec_GetNameSpacePatch(nspace->parent)); +    if (nspace->name) +        CPrec_NamePatch(&p->name, nspace->name); +    if (nspace->usings) +        CPrec_NewPointerPatch(&p->usings, CPrec_GetNameSpaceListPatch(nspace->usings)); +    if (nspace->theclass) +        CPrec_NewPointerPatch(&p->theclass, CPrec_GetTypePatch((Type *) nspace->theclass)); + +    if (nspace->is_hash) { +        char *hash; +        int i; +        hash = CPrec_AppendAlign(); +        CPrec_NewPointerPatch(&p->data.hash, hash); +        CPrec_AppendData(nspace->data.hash, sizeof(NameSpaceName *) * 1024); +        for (i = 0; i < 1024; i++) { +            if (nspace->data.hash[i]) +                CPrec_NewPointerPatch(hash + (i * sizeof(NameSpaceName *)), CPrec_GetNameSpaceNamePatch(nspace->data.hash[i], 0)); +        } +    } else if (nspace->data.list) { +        CPrec_NewPointerPatch(&p->data.list, CPrec_GetNameSpaceNamePatch(nspace->data.list, 0)); +    } + +    return p; +} + +static void CPrec_DumpRootNameSpace() {} +static void CPrec_GetSOMPatch() {} +static void CPrec_GetOLinkPatch() {} +static void CPrec_GetStaticDataPatch() {} +static void CPrec_GetCallbackPatch() {} +static void CPrec_GetSelHashTablePatch() {} +static void CPrec_GetIExpressionPatch() {} +static void CPrec_GetInlineActionPatch() {} + +static void CPrec_GenerateBuiltinPatches() { +    int x; +    int y; +    Patch *scan; + +    for (x = 0; x < cprec_builtins; x++) { +        y = 0; +        for (scan = cprec_builtin[x].patches; scan; scan = scan->next) +            ++y; + +        if (y) { +            CPrec_AppendWord32(y); +            CPrec_AppendWord32(x); +            for (scan = cprec_builtin[x].patches; scan; scan = scan->next) +                CPrec_AppendWord32(scan->offset); +        } +    } + +    CPrec_AppendWord32(0); +} + +static void CPrec_GenerateTokenStreamPatches() { +    TokenPatch *scan; + +    for (scan = cprec_tokenpatches; scan; scan = scan->next) { +        CPrec_AppendWord32((UInt32) scan->tokens); +        CPrec_AppendWord32((UInt32) scan->count); +    } +    CPrec_AppendWord32(0); +} + +static OSErr CPrec_CompressWrite(const char *data, SInt32 size) { +    char buf[2048 + 256]; +    OSErr err; +    int bufpos = 0; +    int blockstart; +    int c; +    const char *p = data; +    const char *end = data + size; + +    for (;;) { +        if (p < end) { +            if (!*p) { +                c = 224; +                while (!*p && p < end && c < 256) { +                    c++; +                    p++; +                } +                buf[bufpos++] = c - 1; +            } else { +                blockstart = bufpos++; +                c = 0; +                while (p < end && c < 224) { +                    if (!p[0] && !p[1]) { +                        break; +                    } else { +                        buf[bufpos++] = *(p++); +                        c++; +                    } +                } +                buf[blockstart] = c - 1; +            } +        } + +        if (p >= end || bufpos > 2048) { +            if ((err = COS_FileWrite(cprec_refnum, buf, bufpos))) +                return err; + +            if (p >= end) +                break; +            else +                bufpos = 0; +        } +    } + +    return noErr; +} + +static OSErr CPrec_FlushRawBuffer() { +    OSErr err; + +    if (cprec_dowrite) { +        CPrec_AppendAlign(); +        cprec_zero_offset += cprec_glist.size; +        COS_LockHandle(cprec_glist.data); +        err = CPrec_CompressWrite(*cprec_glist.data, cprec_glist.size); +        COS_UnlockHandle(cprec_glist.data); +        cprec_glist.size = 0; + +        return err; +    } else { +        return noErr; +    } +} + +static OSErr CPrec_FlushBufferCheck() { +    static SInt32 flushmax; +    OSErr err; + +    if (cprec_glist.size > flushmax) +        flushmax = cprec_glist.size; + +    if (cprec_glist.size > 10000) { +        err = CPrec_FlushRawBuffer(); +        if (err) { +            cprec_ioerror = err; +            return err; +        } +    } + +    return noErr; +} + +static int CPrec_CompressPatches() { +    Patch *scan; +    int count; +    SInt32 last; + +    cprec_glist.size = 0; + +    scan = cprec_patch_list; +    last = 0; +    count = 0; +    while (scan) { +#line 4339 +        CError_ASSERT((scan->offset & 0x80000001) == 0); + +        if ((scan->offset - last) >= -128 && (scan->offset - last) <= 126) +            CPrec_AppendByte(((scan->offset - last) >> 1) | 0x80); +        else +            CPrec_AppendWord32(scan->offset); + +        last = scan->offset; +        scan = scan->next; +        count++; +    } + +    return count; +} + +static void CPrec_DumpColorSymbolTable() {} + +static OSErr CPrec_FileAlign(short refnum, SInt32 *len) { +    OSErr err; +    SInt32 n; +    char buf[8]; + +    n = *len; +    if ((n & 7) == 0) +        return noErr; + +    memclrw(buf, 8); +    err = COS_FileWrite(refnum, buf, n = 8 - (n & 7)); +    *len += n; + +    return err; +} + +static void CPrec_WriteFile() {} + +void PrecompilerWrite() { +} + +static void CPrec_ReadData() {} +static void CPrec_ReadRawBuffer() {} +static void CPrec_RelocateRawBuffer() {} +static void CPrec_RelocateBuiltins() {} +static void CPrec_RelocateTokenStreams() {} +static void CPrec_RelocateMacroTable() {} +static void CPrec_RelocateTable() {} +static void CPrec_RelocateRootNameSpace() {} + +static void CPrec_FixNameIds() { +    int i; +    HashNameNode *node; + +    for (i = 0; i < 2048; i++) { +        for (node = name_hash_nodes[i]; node; node = node->next) +            node->id = -1; +    } +} + +static void CPrec_DefineStaticData() {} + +void PrecompilerRead(short refnum, void *buffer) { +} | 
