diff options
author | Ash Wolf <ninji@wuffs.org> | 2022-10-25 20:30:28 +0100 |
---|---|---|
committer | Ash Wolf <ninji@wuffs.org> | 2022-10-25 20:30:28 +0100 |
commit | d0b9848c54e6f85ab713f059dcd1ddef7e57caa6 (patch) | |
tree | 5bdb9dbf6c853780bc444dc92bf6f9fa3a95742a /compiler_and_linker | |
parent | 685f22a6a0a5403c76316a2390c021a7b0f7597d (diff) | |
download | MWCC-d0b9848c54e6f85ab713f059dcd1ddef7e57caa6.tar.gz MWCC-d0b9848c54e6f85ab713f059dcd1ddef7e57caa6.zip |
a bunch of compiler stuff
Diffstat (limited to 'compiler_and_linker')
-rw-r--r-- | compiler_and_linker/FrontEnd/C/CPrep.c | 921 | ||||
-rw-r--r-- | compiler_and_linker/FrontEnd/C/CPrepTokenizer.c | 166 | ||||
-rw-r--r-- | compiler_and_linker/FrontEnd/C/CScope.c | 2690 | ||||
-rw-r--r-- | compiler_and_linker/FrontEnd/Common/CompilerTools.c | 1216 | ||||
-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 |
9 files changed, 10877 insertions, 0 deletions
diff --git a/compiler_and_linker/FrontEnd/C/CPrep.c b/compiler_and_linker/FrontEnd/C/CPrep.c new file mode 100644 index 0000000..e69bcfb --- /dev/null +++ b/compiler_and_linker/FrontEnd/C/CPrep.c @@ -0,0 +1,921 @@ +#include "compiler.h" +#include "compiler/CError.h" +#include "compiler/tokens.h" +#include "cos.h" + +extern SInt16 *CLT_filesp; +extern CPrepFileInfo **CLT_filestack; + +//#define OPT_OFFSET(optname) ((short) (((char *) (&copts.optname)) - ((char *) &copts))) +#define OPT_OFFSET(optname) ((short) ( &((COpts *)0)->optname )) +enum { + OPT_FLAG_2000 = 0x2000, + OPT_FLAG_4000 = 0x4000 +}; + +struct { + char *name; + short bits; +} compileroptions[138] = { + "little_endian", OPT_FLAG_4000 | OPT_OFFSET(little_endian), + "longlong", OPT_OFFSET(longlong), + "traceback", OPT_OFFSET(traceback), + "disable_registers", OPT_OFFSET(disable_registers), + "fp_contract", OPT_OFFSET(fp_contract), + "no_common", OPT_OFFSET(no_common), + "no_implicit_templates", OPT_OFFSET(no_implicit_templates), + "absolutepath", OPT_OFFSET(absolutepath), + "debug_listing", OPT_OFFSET(debuglisting), + "profile", OPT_OFFSET(profile), + "optimizewithasm", OPT_OFFSET(optimizewithasm), + "use_lmw_stmw", OPT_OFFSET(use_lmw_stmw), + "no_register_save_helpers", OPT_OFFSET(no_register_save_helpers), + "ppc_opt_bclr_bcctr", OPT_OFFSET(ppc_opt_bclr_bcctr), + "misaligned_mem_access", OPT_OFFSET(misaligned_mem_access), + "switch_tables", OPT_OFFSET(switch_tables), + "prepare_compress", OPT_OFFSET(prepare_compress), + "asmsemicolcomment", OPT_OFFSET(asmsemicolcomment), + "asmpoundcomment", OPT_OFFSET(asmpoundcomment), + "cplusplus", OPT_OFFSET(cplusplus), + "ecplusplus", OPT_OFFSET(ecplusplus), + "objective_c", OPT_OFFSET(objective_c), + "objc_strict", OPT_OFFSET(objc_strict), + "ARM_conform", OPT_OFFSET(ARM_conform), + "ARM_scoping", OPT_OFFSET(ARM_scoping), + "require_prototypes", OPT_OFFSET(require_prototypes), + "trigraphs", OPT_OFFSET(trigraphs), + "only_std_keywords", OPT_OFFSET(only_std_keywords), + "enumsalwaysint", OPT_OFFSET(enumsalwaysint), + "ANSI_strict", OPT_OFFSET(ANSI_strict), + "mpwc_relax", OPT_OFFSET(mpwc_relax), + "mpwc_newline", OPT_OFFSET(mpwc_newline), + "ignore_oldstyle", OPT_OFFSET(ignore_oldstyle), + "cpp_extensions", OPT_OFFSET(cpp_extensions), + "pointercast_lvalue", OPT_OFFSET(pointercast_lvalue), + "RTTI", OPT_OFFSET(useRTTI), + "delete_exception", OPT_OFFSET(delete_exception), + "oldalignment", OPT_OFFSET(oldalignment), + "multibyteaware", OPT_OFFSET(multibyteaware), + "unsigned_char", OPT_OFFSET(unsignedchars), + "auto_inline", OPT_OFFSET(autoinline), + "inline_bottom_up", OPT_OFFSET(inline_bottom_up), + "defer_codegen", OPT_OFFSET(defer_codegen), + "direct_to_som", OPT_OFFSET(direct_to_som), + "SOMCheckEnvironment", OPT_OFFSET(som_env_check), + "SOMCallOptimization", OPT_OFFSET(som_call_opt), + "bool", OPT_OFFSET(booltruefalse), + "old_enum_mangler", OPT_OFFSET(old_enum_mangler), + "longlong_enums", OPT_OFFSET(longlong_enums), + "no_tfuncinline", OPT_OFFSET(no_tfuncinline), + "flat_include", OPT_OFFSET(flat_include), + "syspath_once", OPT_OFFSET(syspath_once), + "always_import", OPT_OFFSET(always_import), + "simple_class_byval", OPT_OFFSET(simple_class_byval), + "wchar_type", OPT_OFFSET(wchar_type), + "vbase_ctor_offset", OPT_OFFSET(vbase_ctor_offset), + "vbase_abi_v2", OPT_OFFSET(vbase_abi_v2), + "def_inherited", OPT_OFFSET(def_inherited), + "template_patch", OPT_OFFSET(template_patch), + "template_friends", OPT_OFFSET(template_friends), + "faster_pch_gen", OPT_OFFSET(faster_pch_gen), + "array_new_delete", OPT_OFFSET(array_new_delete), + "dollar_identifiers", OPT_OFFSET(dollar_identifiers), + "def_inline_tfuncs", OPT_OFFSET(def_inline_tfuncs), + "arg_dep_lookup", OPT_OFFSET(arg_dep_lookup), + "simple_prepdump", OPT_OFFSET(simple_prepdump), + "line_prepdump", OPT_OFFSET(line_prepdump), + "fullpath_prepdump", OPT_OFFSET(fullpath_prepdump), + "old_mtemplparser", OPT_OFFSET(old_mtemplparser), + "suppress_init_code", OPT_OFFSET(suppress_init_code), + "reverse_bitfields", OPT_OFFSET(reverse_bitfields), + "c9x", OPT_OFFSET(c9x), + "float_constants", OPT_OFFSET(float_constants), + "no_static_dtors", OPT_OFFSET(no_static_dtors), + "longlong_prepeval", OPT_OFFSET(longlong_prepeval), + "const_strings", OPT_OFFSET(const_strings), + "dumpir", OPT_OFFSET(dumpir), + "experimental", OPT_OFFSET(experimental), + "gcc_extensions", OPT_OFFSET(gcc_extensions), + "stdc_fp_contract", OPT_OFFSET(stdc_fp_contract), + "stdc_fenv_access", OPT_OFFSET(stdc_fenv_access), + "stdc_cx_limitedr", OPT_OFFSET(stdc_cx_limitedr), + "old_argmatch", OPT_OFFSET(old_argmatch), + "optEH", OPT_OFFSET(optEH), + "optEH2", OPT_OFFSET(optEH2), + "new_mangler", OPT_OFFSET(new_mangler), + "microsoft_exceptions", OPT_OFFSET(microsoft), + "microsoft_RTTI", OPT_OFFSET(microsoft), + "warning_errors", OPT_OFFSET(warningerrors), + "extended_errorcheck", OPT_OFFSET(pedantic), + "check_header_flags", OPT_OFFSET(check_header_flags), + "supress_warnings", OPT_OFFSET(supress_warnings), + "warn_illpragma", OPT_OFFSET(warn_illpragma), + "warn_emptydecl", OPT_OFFSET(warn_emptydecl), + "warn_possunwant", OPT_OFFSET(warn_possunwant), + "warn_unusedvar", OPT_OFFSET(warn_unusedvar), + "warn_unusedarg", OPT_OFFSET(warn_unusedarg), + "warn_extracomma", OPT_OFFSET(warn_extracomma), + "warn_hidevirtual", OPT_OFFSET(warn_hidevirtual), + "warn_largeargs", OPT_OFFSET(warn_largeargs), + "warn_implicitconv", OPT_OFFSET(warn_implicitconv), + "warn_notinlined", OPT_OFFSET(warn_notinlined), + "warn_structclass", OPT_OFFSET(warn_structclass), + "warn_padding", OPT_OFFSET(warn_padding), + "warn_no_side_effect", OPT_OFFSET(warn_no_side_effect), + "warn_resultnotused", OPT_OFFSET(warn_resultnotused), + "warn_ptr_int_conv", OPT_OFFSET(warn_ptr_int_conv), + "align_array_members", OPT_OFFSET(align_array_members), + "dont_reuse_strings", OPT_OFFSET(dont_reuse_strings), + "pool_strings", OPT_OFFSET(pool_strings), + "explicit_zero_data", OPT_OFFSET(explicit_zero_data), + "readonly_strings", OPT_OFFSET(readonly_strings), + "opt_common_subs", OPT_OFFSET(opt_common_subs), + "opt_loop_invariants", OPT_OFFSET(opt_loop_invariants), + "opt_propagation", OPT_OFFSET(opt_propagation), + "opt_unroll_loops", OPT_OFFSET(opt_unroll_loops), + "opt_lifetimes", OPT_OFFSET(opt_lifetimes), + "opt_strength_reduction", OPT_OFFSET(opt_strength_reduction), + "opt_strength_reduction_strict", OPT_OFFSET(opt_strength_reduction_strict), + "opt_dead_code", OPT_OFFSET(opt_dead_code), + "opt_dead_assignments", OPT_OFFSET(opt_dead_assignments), + "opt_vectorize_loops", OPT_OFFSET(opt_vectorize_loops), + "opt_pointer_analysis", OPT_OFFSET(opt_pointer_analysis), + "exceptions", OPT_OFFSET(exceptions), + "dont_inline", OPT_OFFSET(dont_inline), + "always_inline", OPT_OFFSET(always_inline), + "optimize_for_size", OPT_OFFSET(optimize_for_size), + "peephole", OPT_OFFSET(peephole), + "global_optimizer", OPT_OFFSET(global_optimizer), + "side_effects", OPT_OFFSET(side_effects), + "internal", OPT_FLAG_2000 | OPT_OFFSET(internal), + "import", OPT_FLAG_2000 | OPT_OFFSET(import), + "export", OPT_FLAG_2000 | OPT_OFFSET(export), + "lib_export", OPT_FLAG_2000 | OPT_OFFSET(lib_export), + "nosyminline", OPT_OFFSET(nosyminline), + "force_active", OPT_OFFSET(force_active), + "sym", OPT_OFFSET(isGeneratingDebugInfo), + NULL, 0 +}; + +CParams *cparamblkptr; +short tk; +CInt64 tkintconst; +Float tkfloatconst; +char *tkstring; +HashNameNode *tkidentifier; +SInt32 tksize; +short ispascalstring; +short nlflag; +SInt32 lines; +Boolean spaceskip; +Macro **macrohashtable; +Boolean cprep_nomem_exit; +Boolean cprep_nostring; +Boolean cprep_eoltokens; +static void *ifstack[100]; // TODO type+size +static short iflevel; +TokenStack tokenstack[128]; +short tokenstacklevel; +SInt32 cprep_cursymfile; // might be a ptr? +char *pos; +char *macropos; +char *nextcharpos; +char CPrep_SkipNewCommentChar; +Boolean preprocessing_only; +Handle stringmem; +SInt32 maxstringsize; +char cprep_idarray[256]; +Boolean was_escchar; +Boolean macrocheck; +Boolean widestring; +Boolean at_linestart; +char *prep_file_start; +char *prep_file_end; +char *macrostart; +Boolean cprep_strconcat; +CPrepFileInfo *prep_file; +short filesp; +SInt32 linenumber; +static CPrepFileInfo *filestack[32]; +static void *cprep_files; // TODO type +static SInt32 linetick; +static Boolean waslockedmacro; +static Boolean include_once; +static time_t now_time; +static SInt32 lineoffset; +static Boolean was_prep_error; +static Boolean cprep_hasprepline; +static Boolean cprep_incondexpr; +static void *cprep_packstack[100]; // TODO type+size +static short cprep_packstackp; +static Macro lineM; +static Macro fileM; +static Macro dateM; +static Macro timeM; +static Macro stdcM; +static Macro stcvM; +static Macro stchM; +static Macro casmM; +static Macro cpplM; +static Macro MWRSM; +static Macro dtsomM; +static Macro ecppM; +static Macro optiM; +static Macro trgtM; +GList pplist; +struct COptsPush { + struct COptsPush *next; + COpts opts; +}; +static struct COptsPush *coptpushs; +static void *coptpush; // TODO type +static void *coptssave; // TODO type +static Boolean dofreeaheap; +static GList mlist; +static Handle ts_buffer; +static TStreamElement *ts_first; +static TStreamElement *ts_last; +TStreamElement *ts_current; +static SInt32 ts_elements; +SInt32 ts_preread_elements; +static SInt32 gDirectiveStart; +static SInt32 high_mem_mark; +// static TStreamElement dummyelement; // in CPrep_CurStreamElement +static short exprtk; + +static void cannotopenerror(StringPtr filename, Boolean err) { + static char fname[64]; + + short len = filename[0]; + if (len > 63) + len = 63; + memcpy(fname, filename + 1, len); + fname[len] = 0; + + CError_ResetErrorSkip(); + + if (prep_file) { + was_prep_error = 1; + CError_Error(151, fname); + if (err) + longjmp(errorreturn, 1); + } else { + CError_CannotOpen(); + } +} + +static void insertmacro(Macro *macro) { + macro->next = macrohashtable[macro->name->hashval]; + macrohashtable[macro->name->hashval] = macro; + macro->xF = 0; +} + +void CPrep_InsertSpecialMacro(Macro *macro, char *name) { + macro->name = GetHashNameNodeExport(name); + macro->is_special = 1; + insertmacro(macro); +} + +void CPrep_InsertSpecialMacros() { + CPrep_InsertSpecialMacro(&lineM, "__LINE__"); + CPrep_InsertSpecialMacro(&fileM, "__FILE__"); + CPrep_InsertSpecialMacro(&dateM, "__DATE__"); + CPrep_InsertSpecialMacro(&timeM, "__TIME__"); + CPrep_InsertSpecialMacro(&stdcM, "__STDC__"); + CPrep_InsertSpecialMacro(&stcvM, "__STDC_VERSION__"); + CPrep_InsertSpecialMacro(&stchM, "__STDC_HOSTED__"); + CPrep_InsertSpecialMacro(&casmM, "__CASM__"); + CPrep_InsertSpecialMacro(&cpplM, "__cplusplus"); + CPrep_InsertSpecialMacro(&MWRSM, "__MWERKS__"); + CPrep_InsertSpecialMacro(&dtsomM, "__SOM_ENABLED__"); + CPrep_InsertSpecialMacro(&ecppM, "__embedded_cplusplus"); + CPrep_InsertSpecialMacro(&optiM, "__option"); + CPrep_InsertSpecialMacro(&trgtM, "__ide_target"); + CodeGen_InsertSpecialMacros(); +} + +void CPrep_RemoveSpecialMacros() { + Macro **scan; + int x; + + for (x = 0; x < 2048; x++) { + scan = ¯ohashtable[x]; + while (*scan) { + if ((*scan)->is_special) { + *scan = (*scan)->next; + } else { + scan = &(*scan)->next; + } + } + } +} + +static void CPrep_Reconfig() { + cprep_idarray['$'] = copts.dollar_identifiers != 0; +} + +Boolean setupprep() { + int x; + + now_time = time(NULL); + lineoffset = 0; + include_once = 0; + cprep_eoltokens = 0; + cprep_nostring = 0; + cprep_incondexpr = 0; + filesp = -1; + linetick = 0; + lines = 0; + dofreeaheap = 1; + macrocheck = 1; + maxstringsize = 256; + iflevel = 0; + tokenstacklevel = 0; + cprep_cursymfile = 0; + cprep_files = 0; + CLT_filesp = &filesp; + CLT_filestack = filestack; + anyerrors = 0; + fatalerrors = 0; + was_prep_error = 0; + cprep_strconcat = 0; + + GListErrorProc = CError_NoMem; + mlist.data = NULL; + pplist.data = NULL; + if (InitGList(&mlist, 10000)) + CError_NoMem(); + + stringmem = COS_NewHandle(256); + if (!stringmem) + CError_NoMem(); + ts_buffer = COS_NewHandle(1024 * sizeof(TStreamElement)); + if (!ts_buffer) + CError_NoMem(); + COS_LockHandleHi(ts_buffer); + ts_first = (TStreamElement *) *ts_buffer; + ts_last = ts_first + 1023; + ts_current = ts_first; + ts_elements = 1024; + ts_preread_elements = 0; + + macrohashtable = galloc(sizeof(Macro *) * 2048); + memclrw(macrohashtable, sizeof(Macro *) * 2048); + CPrep_InsertSpecialMacros(); + + for (x = 0; x < 256; x++) + cprep_idarray[x] = 0; + + for (x = 'a'; ; x++) { + cprep_idarray[x] = 1; + if (x == 'z') break; + } + + for (x = 'A'; ; x++) { + cprep_idarray[x] = 1; + if (x == 'Z') break; + } + + for (x = '0'; ; x++) { + cprep_idarray[x] = 2; + if (x == '9') break; + } + + cprep_idarray['_'] = 1; + + CPrep_Reconfig(); + return 0; +} + +void cleanupprep() { + while (filesp >= 0) + popfile(); + + high_mem_mark = CTool_TotalHeapSize(); + releaseheaps(); + GListErrorProc = NULL; + FreeGList(&mlist); + FreeGList(&pplist); + + if (stringmem) { + COS_FreeHandle(stringmem); + stringmem = NULL; + } + + if (ts_buffer) { + COS_FreeHandle(ts_buffer); + ts_buffer = NULL; + } + ts_current = NULL; + ts_first = ts_last = NULL; +} + +static char *getfiledata(FSSpec *spec) { + const char *text; + SInt32 textlength; + short filedatatype; + + if (CWGetFileText(cparamblkptr->context, spec, &text, &textlength, &filedatatype) != cwNoErr) { + Str255 filename; + COS_FileGetFSSpecInfo(spec, NULL, NULL, filename); + cannotopenerror(filename, 1); + return NULL; + } else { + return (char *) text; + } +} + +static Boolean setupfile(StringPtr filename, Boolean flag1, Boolean flag2) { + CPrepFileInfo prepinfo; + CWFileInfo fileinfo; + Str255 file_filename; + char myfilename[256]; + OSType file_type; + SInt32 file_size; + SInt32 file_dirid; + CWMemHandle cache_hnd; + void *cache; + SInt16 refnum; + SInt16 file_vrefnum; + char *extpos; + + if (filesp >= 31) { + was_prep_error = 1; + CError_ErrorTerm(243); + return 0; + } + + memclrw(&prepinfo, sizeof(CPrepFileInfo)); + prepinfo.unkfield126 = !flag1; // may be wrong field! + if (filename) { + memclrw(&fileinfo, sizeof(CWFileInfo)); + fileinfo.fullsearch = flag2; + fileinfo.dependencyType = cwNormalDependency; + fileinfo.isdependentoffile = -1; + memcpy(myfilename, &filename[1], filename[0]); + myfilename[filename[0]] = 0; + + if (CWFindAndLoadFile(cparamblkptr->context, myfilename, &fileinfo) != cwNoErr) { + if (filename[0] + strlen(".framework/Headers") < 255) { + if ((extpos = strchr(myfilename, '/'))) { + // Do Me! 37D8C + } else { + cannotopenerror(filename, 0); + return 0; + } + } else { + cannotopenerror(filename, 0); + return 0; + } + } + + if ((flag2 || include_once) && fileinfo.alreadyincluded) + return 1; + + prepinfo.textfile = fileinfo.filespec; + prepinfo.nameNode = CTool_GetPathName(&fileinfo.filespec, &prepinfo.fileModDate); + if (fileinfo.filedata) { + if (fileinfo.filedatatype == cwFileTypeText) { + prepinfo.textbuffer = (char *) fileinfo.filedata; + prepinfo.textlength = fileinfo.filedatalength; + prepinfo.fileID = fileinfo.fileID; + prepinfo.recordbrowseinfo = fileinfo.recordbrowseinfo; + } else if (fileinfo.filedatatype == cwFileTypePrecompiledHeader) { + PrecompilerRead(0, (void *) fileinfo.filedata); + return 1; + } else { + cannotopenerror(filename, 0); + return 0; + } + } else { + COS_FileGetFSSpecInfo(&prepinfo.textfile, &file_vrefnum, &file_dirid, file_filename); + if (COS_FileOpen(&prepinfo.textfile, &refnum)) { + cannotopenerror(filename, 0); + return 0; + } + if (COS_FileGetType(&prepinfo.textfile, &file_type) || COS_FileGetSize(refnum, &file_size)) { + COS_FileClose(refnum); + cannotopenerror(filename, 0); + return 0; + } + if (file_type == copts.pchType) { + if (cparamblkptr->isCachingPrecompiledHeaders) { + if (CWAllocMemHandle(cparamblkptr->context, file_size, 1, &cache_hnd) != cwNoErr) { + if (CWAllocMemHandle(cparamblkptr->context, file_size, 0, &cache_hnd) != cwNoErr) { + COS_FileClose(refnum); + CError_NoMem(); + } + } + + CWLockMemHandle(cparamblkptr->context, cache_hnd, 0, &cache); + if (COS_FileRead(refnum, cache, file_size)) { + COS_FileClose(refnum); + CWFreeMemHandle(cparamblkptr->context, cache_hnd); + cannotopenerror(filename, 0); + return 0; + } + COS_FileClose(refnum); + CWCachePrecompiledHeader(cparamblkptr->context, &prepinfo.textfile, cache_hnd); + PrecompilerRead(0, cache); + CWUnlockMemHandle(cparamblkptr->context, cache_hnd); + return 1; + } else { + PrecompilerRead(refnum, 0); + COS_FileClose(refnum); + return 1; + } + } else { + COS_FileClose(refnum); + cannotopenerror(filename, 0); + return 0; + } + } + } else { + if (!cparamblkptr->mainFileText) { + COS_FileGetFSSpecInfo(&cparamblkptr->mainFileSpec, &file_vrefnum, &file_dirid, file_filename); + cannotopenerror(file_filename, 1); + return 0; + } + + prepinfo.textfile = cparamblkptr->mainFileSpec; + prepinfo.textbuffer = (char *) cparamblkptr->mainFileText; + prepinfo.textlength = cparamblkptr->mainFileTextLength; + prepinfo.fileID = cparamblkptr->mainFileID; + prepinfo.recordbrowseinfo = cparamblkptr->field276; + } + + if (filesp >= 0) { + filestack[filesp]->linenumber = linenumber; + filestack[filesp]->hasprepline = cprep_hasprepline; + filestack[filesp]->pos = pos - filestack[filesp]->textbuffer; + } + + pos = prepinfo.textbuffer; + linenumber = 1; + at_linestart = 1; + filestack[++filesp] = galloc(sizeof(CPrepFileInfo)); + *filestack[filesp] = prepinfo; + prep_file = filestack[filesp]; + prep_file_start = prep_file->textbuffer; + prep_file_end = prep_file->textbuffer + prep_file->textlength; + if (preprocessing_only && !copts.simple_prepdump) + CPrep_PreprocessDumpFileInfo(1); + + return 1; +} + +void CPrep_TSBufferGrow(int amount) { + int current_offset = ts_current - ts_first; + COS_UnlockHandle(ts_buffer); + if (!COS_ResizeHandle(ts_buffer, sizeof(TStreamElement) * (ts_elements + amount))) + CError_NoMem(); + COS_LockHandleHi(ts_buffer); + ts_elements += amount; + ts_first = (TStreamElement *) *ts_buffer; + ts_last = ts_first + (ts_elements - 1); + ts_current = ts_first + current_offset; +} + +void CPrep_TokenStreamGetState(SInt32 *state) { + *state = ts_current - ts_first; +} + +void CPrep_TokenStreamSetState(SInt32 *state) { + ts_preread_elements += ts_current - ts_first - *state; + ts_current = ts_first + *state; +} + +void CPrep_UnLex() { + ++ts_preread_elements; + --ts_current; +#line 900 + CError_ASSERT(ts_current >= ts_first); +} + +void CPrep_TokenStreamSetCurState(SInt32 *state) { + ts_preread_elements += ts_current - ts_first - (*state - 1); + ts_current = ts_first + (*state - 1); + tk = lex(); +} + +static void CPrep_StreamSkipToBrace() {} +static void CPrep_StreamSkipBlock() {} +void CPrep_StreamGetBlock() {} +void CPrep_StreamGetSemicolon() {} +void CPrep_StreamGetTemplate() {} +void CPrep_StreamInsert() {} +void CPrep_StreamRemove() {} +void CPrep_RemoveTokens() {} +void CPrep_TokenStreamFlush() {} +static void CPrep_TokenSize() {} +void CPrep_CurStreamElement() {} + +void CPrep_GetTokenContext(TStreamElement *token, CPrepFileInfo **tokenfile, SInt32 *selectionoffset, short *tokensize, SInt32 *linenumber, char *buf1, short *tokenoffset, short *tokenlength, char *buf2, short *lastarg) { +} + +void CPrep_Error(short code) { + Boolean save = in_assembler; + in_assembler = 0; + if (code == 102 && (tokenstacklevel > 0 || pos < prep_file_end)) + code = 105; + was_prep_error = 1; + CError_Error(code); + in_assembler = save; +} + +void CPrep_ErrorName(short code, const char *name) { + Boolean save = in_assembler; + in_assembler = 0; + was_prep_error = 1; + if (code == 102 && (tokenstacklevel > 0 || pos < prep_file_end)) + CError_Error(105, name); + else + CError_Error(code, name); + in_assembler = save; +} + +void CPrep_Warning(short code) { + Boolean save = in_assembler; + in_assembler = 0; + was_prep_error = 1; + CError_Warning(code); + in_assembler = save; +} + +void CPrep_WarningName(short code, const char *name) { + Boolean save = in_assembler; + in_assembler = 0; + was_prep_error = 1; + CError_Warning(code, name); + in_assembler = save; +} + +void CPrep_ErrorMessage(int errTable, char *str, Boolean flag1, Boolean flag2) { + Boolean save = in_assembler; + in_assembler = 0; + was_prep_error = 1; + CError_ErrorMessage(errTable, str, flag1, flag2); + in_assembler = save; +} + +void CPrep_ErrorMessageVA(int code, const char *format, va_list list, Boolean flag1, Boolean flag2) { + Boolean save = in_assembler; + in_assembler = 0; + was_prep_error = 1; + CError_ErrorMessageVA(code, format, list, flag1, flag2); + in_assembler = save; +} + +void popfile() { + // r5 and r6 are swapped, not sure why + if (filesp >= 0) { + CWReleaseFileText(cparamblkptr->context, prep_file->textbuffer); + prep_file->textbuffer = NULL; + if (--filesp >= 0) { + prep_file = filestack[filesp]; + prep_file_start = prep_file->textbuffer; + prep_file_end = prep_file->textbuffer + prep_file->textlength; + pos = prep_file_start + prep_file->pos; + linenumber = prep_file->linenumber; + cprep_hasprepline = prep_file->hasprepline; + at_linestart = 1; + } + if (preprocessing_only && !copts.simple_prepdump) + CPrep_PreprocessDumpFileInfo(1); + } +} + +static void prepoffset() {} +static void prepoffset2() {} +void CPrep_SetSourceFile() {} +void CPrep_GetSourceFilePath() {} +void CPrep_NewFileOffsetInfo() {} +void CPrep_GetFileOffsetInfo() {} +void CPrep_GetFileOffsetInfo2() {} +void CPrep_ResetFileInfo() {} +void CPrep_GetPrepPos() {} +Boolean C_Compiler(CParams *param) {} + +static void pushtokenseq(Macro *macro) { + if (tokenstacklevel >= 128) { + was_prep_error = 1; + CError_ErrorTerm(111); + } else { + tokenstack[tokenstacklevel].pos = pos; + tokenstack[tokenstacklevel].macrostart = macrostart; + tokenstack[tokenstacklevel].macro = macro; + if (macro) + macro->xF = 1; + tokenstack[tokenstacklevel].macrocheck = macrocheck; + tokenstacklevel++; + } +} + +void poptokenseq() { + if (!--tokenstacklevel && dofreeaheap) + freeaheap(); + + pos = tokenstack[tokenstacklevel].pos; + macrostart = tokenstack[tokenstacklevel].macrostart; + if (tokenstack[tokenstacklevel].macro) + tokenstack[tokenstacklevel].macro->xF = 0; + macrocheck = tokenstack[tokenstacklevel].macrocheck; + spaceskip = 1; +} + +static void is_nextchar() {} +static void ismacroname() {} +static void ismacroname2() {} +static void ismacroname5() {} +static void ismacroname3() {} +static void ismacroname4() {} +void foundnl() {} +void newline() {} +static void gotonexttoken() {} +short notendofline() {} +static void CPrep_MacroRedefError() {} +static void goendofline() {} +static void CPrep_Define() {} +static void prepundefine() {} +static Boolean CPrep_CheckTarget() {} +static Boolean CPrep_CheckOption() {} +static void CPrep_XpandDefinedCheck() {} +static void XpandString() {} +char *CPrep_GetFileName(char *buffer, Boolean flag1, Boolean flag2) { +} + +static char *XpandSpecialMacro(Macro *macro) { + char buf[512]; + char smallbuf[32]; + char *strptr; + struct tm *tm; + + if (macro == &optiM) { + return CPrep_CheckOption() ? "1" : "0"; + } else if (macro == &trgtM) { + return CPrep_CheckTarget() ? "1" : "0"; + } else if (macro == &lineM) { + sprintf(buf, "%ld", linenumber); + do_string: + strptr = aalloc(strlen(buf) + 1); + strcpy(strptr, buf); + return strptr; + } else if (macro == &fileM) { + CPrep_GetFileName(buf, 0, 1); + goto do_string; + } else if (macro == &dateM) { + tm = localtime(&now_time); + strftime(buf, 64, "\"%b ", tm); + strftime(smallbuf, 32, "%d", tm); + if (smallbuf[0] == '0') + smallbuf[0] = ' '; + strcat(buf, smallbuf); + strftime(smallbuf, 32, " %Y\"", tm); + strcat(buf, smallbuf); + goto do_string; + } else if (macro == &timeM) { + strftime(buf, 64, "\"%H:%M:%S\"", localtime(&now_time)); + goto do_string; + } else if (macro == &stdcM) { + return "1"; + } else if (macro == &casmM || macro == &MWRSM) { + return "0x2405"; + } else if (macro == &cpplM) { + return "199711L"; + } else if (macro == &dtsomM) { + return copts.direct_to_som ? "1" : "0"; + } else if (macro == &ecppM) { + return copts.ecplusplus ? "1" : "0"; + } else if (macro == &stcvM) { + return copts.c9x ? "199901L" : "199409L"; + } else if (macro == &stchM) { + return "0"; + } else { + return CodeGen_ExpandSpecialMacro(macro); + } +} + +static void XpandMacro() {} +static void prepmacro() {} +void macrotest() {} +void CPrep_PragmaLex() {} +void CPrep_PushOption() {} +void CPrep_PopOption() {} +static void CPrep_PragmaImExport() {} +static void pragma_on_off_reset() {} +static void CPrep_PragmaOnceName() {} +static void pragma_precompile_target() {} +static void CPrep_DefinePragmaOnceMacro() {} +static void CPrep_PragmaOnce() {} +static void CPrep_PragmaUnused() {} +static void CPrep_PragmaInlineDepth() {} +static void CPrep_PragmaInlineMaxSize() {} +static void CPrep_PragmaInlineMaxTotalSize() {} + +static void pragma_segment() { + short i; + short t; + char name[256]; + + if (notendofline()) { + for (i = 0; i < 255; i++) { + spaceskip = 0; + t = prepskipnextchar(); + if (spaceskip) + break; + if (t <= ' ') + break; + name[i] = t; + pos = nextcharpos; + } + name[i] = 0; + + if (!i || i >= 255) + CPrep_Warning(186); + + copts.forcedSegment = GetHashNameNodeExport(name); + ObjGen_SegmentName(); + } else { + if (copts.warn_illpragma) + CPrep_Warning(186); + } +} + +static void pragma_options() {} + +static void pragma_push() { + struct COptsPush *push; + + push = galloc(sizeof(struct COptsPush)); + push->next = coptpushs; + coptpushs = push; + + push->opts = copts; +} + +static void pragma_pop() { + if (coptpushs) { + copts = coptpushs->opts; + coptpushs = coptpushs->next; + CMach_Configure(); + } else { + CPrep_Error(237); + } +} + +static void pragma_overload() {} +static void pragma_optimization_level() {} +static void pragma_opt_unroll_count() {} +static void pragma_opt_unroll_instr_count() {} +static void pragma_pack() {} +static void pragma_comment() {} +static void pragma_message() {} +static void preppragma() {} +static void prepinclude() {} +static void prepline() {} +static void CPrep_GetPrepType() {} +static void CPrep_ParseUnary() {} +static void CPrep_ParseBinary() {} +static void CPrep_ParseCond() {} +static void doevalconstexpr() {} +static void pushifstate() {} +static void popifstate() {} +static void positiveif() {} +static void negativeif() {} +static void prepif() {} +static void prepifdef() {} +static void prepifndef() {} +static void prepelif() {} +static void prepelse() {} +static void prependif() {} +static void prepifskip() {} +void preprocessor() {} +void CPrep_BrowserTokenOffset() {} +void CPrep_BrowserFileOffset() {} + +void CPrep_BrowserFilePosition(CPrepFileInfo **fileinfo, SInt32 *offset) { + CPrepFileInfo *file; + + if (ts_first < ts_current) { + file = ts_current[-1].tokenfile; + *offset = ts_current[-1].tokenoffset + 1; + } else { + file = filestack[filesp]; + if (tokenstacklevel) { + *offset = tokenstack[0].pos - filestack[filesp]->textbuffer; + } else { + *offset = pos - filestack[filesp]->textbuffer; + } + } + + if (file && file->fileID > 0 && (file->recordbrowseinfo || gForceSourceLoc)) { + *fileinfo = file; + } else { + *fileinfo = NULL; + *offset = 0; + } +} + +CPrepFileInfo *CPrep_BrowserCurrentFile() { + return prep_file; +} diff --git a/compiler_and_linker/FrontEnd/C/CPrepTokenizer.c b/compiler_and_linker/FrontEnd/C/CPrepTokenizer.c new file mode 100644 index 0000000..5b77268 --- /dev/null +++ b/compiler_and_linker/FrontEnd/C/CPrepTokenizer.c @@ -0,0 +1,166 @@ +#include "compiler.h" +#include "compiler/tokens.h" + +static Boolean prepnextstringchar_foundnl; + +short prepskipnextchar() { + +} + +short prepnextchar() { + +} + +short prepnextstringchar(char *str, Boolean flag) { + +} + +void CPrep_MatchChar(char ch, Boolean flag) { + +} + +char *CPrep_MatchChar2(char *str, char ch, Boolean flag) { + +} + +short prepcurchar() { + +} + +static short prepcurstringchar(char *str) { +} + +static void prepcurstringchar_skip() { +} + +char *ReadIdentifier(char *str) { +} + +static short intsuffix(short token, Boolean flag) { +} + +static short floatsuffix(short token) { +} + +static short tohex(short token) { +} + +static short nextchar(char *str) { +} + +char *CPrep_SkipNewComment(char *str) { + +} + +Boolean skipendoflinematch(char *str, Boolean flag) { +} + +void skipendofline() { +} + +void CPrep_SkipAsmComment() { +} + +static short tille() {} +static short tcret() {} +static short tapos() {} +static short tquot() {} +static short thash() {} +static short tmult() {} +static short tcolo() {} +static short tless() {} +static short tequa() {} +static short tgrea() {} +static short tatsg() {} +static short tperc() {} +static short texcl() {} +static short tplus() {} +static short tminu() {} +static short torrr() {} +static short tampe() {} +static short tpowe() {} +static short tdivi() {} +static short tzero() {} +static short tpoin() {} +static short tnumb() {} +static short tiden() {} +static short tchrL() {} +static short tchra() {} +static short tchrb() {} +static short tchrc() {} +static short tchrd() {} +static short tchre() {} +static short tchrf() {} +static short tchrg() {} +static short tchri() {} +static short tchrl() {} +static short tchrm() {} +static short tchrn() {} +static short tchro() {} +static short tchrp() {} +static short tchrr() {} +static short tchrs() {} +static short tchrt() {} +static short tchru() {} +static short tchrv() {} +static short tchrw() {} +static short tchrx() {} +static short tchr_() {} +static short token() {} +static short tdoll() {} +static short tisid() {} +static short tnull() {} +static short t0x1a() {} + +static short (*cprep_tokenize[256])() = { + &tnull, &tille, &tille, &tille, &tisid, &tisid, &tille, &tille, + &tille, &tille, &tille, &tille, &tille, &tcret, &tille, &tille, + &tille, &tille, &tille, &tille, &tille, &tille, &tille, &tille, + &tille, &tille, &t0x1a, &tille, &tille, &tille, &tille, &tille, + &tille, &texcl, &tquot, &thash, &tdoll, &tperc, &tampe, &tapos, + &token, &token, &tmult, &tplus, &token, &tminu, &tpoin, &tdivi, + &tzero, &tnumb, &tnumb, &tnumb, &tnumb, &tnumb, &tnumb, &tnumb, + &tnumb, &tnumb, &tcolo, &token, &tless, &tequa, &tgrea, &token, + &tatsg, &tiden, &tiden, &tiden, &tiden, &tiden, &tiden, &tiden, + &tiden, &tiden, &tiden, &tiden, &tchrL, &tiden, &tchrn, &tiden, + &tchrp, &tiden, &tiden, &tiden, &tiden, &tiden, &tiden, &tiden, + &tchrx, &tiden, &tiden, &token, &token, &token, &tpowe, &tchr_, + &token, &tchra, &tchrb, &tchrc, &tchrd, &tchre, &tchrf, &tchrg, + &tiden, &tchri, &tiden, &tiden, &tchrl, &tchrm, &tchrn, &tchro, + &tchrp, &tiden, &tchrr, &tchrs, &tchrt, &tchru, &tchrv, &tchrw, + &tchrx, &tiden, &tiden, &token, &torrr, &token, &token, &tille, + &tille, &tille, &tille, &tille, &tille, &tille, &tille, &tille, + &tille, &tille, &tille, &tille, &tille, &tille, &tille, &tille, + &tille, &tille, &tille, &tille, &tille, &tille, &tille, &tille, + &tille, &tille, &tille, &tille, &tille, &tille, &tille, &tille, + &tille, &tille, &tille, &tille, &tille, &tille, &tille, &tille, + &tille, &tille, &tille, &tille, &tille, &tille, &tille, &tille, + &tille, &tille, &tille, &tille, &tille, &tille, &tille, &tille, + &tille, &tille, &tille, &tille, &tille, &tille, &tille, &tille, + &tille, &tille, &tille, &tille, &tille, &tille, &tille, &tille, + &tille, &tille, &tille, &tille, &tille, &tille, &tille, &tille, + &tille, &tille, &tille, &tille, &tille, &tille, &tille, &tille, + &tille, &tille, &tille, &tille, &tille, &tille, &tille, &tille, + &tille, &tille, &tille, &tille, &tille, &tille, &tille, &tille, + &tille, &tille, &tille, &tille, &tille, &tille, &tille, &tille, + &tille, &tille, &tille, &tille, &tille, &tille, &tille, &tille, + &tille, &tille, &tille, &tille, &tille, &tille, &tille, &tille +}; + +short lookahead() { +} + +short lookahead_noeol() { +} + +static void CPrep_StringConCat(Boolean flag) { +} + +short lex() { +} + +short plex() { +} + +short lexidentifier() { +} diff --git a/compiler_and_linker/FrontEnd/C/CScope.c b/compiler_and_linker/FrontEnd/C/CScope.c new file mode 100644 index 0000000..7423c07 --- /dev/null +++ b/compiler_and_linker/FrontEnd/C/CScope.c @@ -0,0 +1,2690 @@ +#include "compiler.h" +#include "compiler/CError.h" +#include "compiler/enode.h" +#include "compiler/objects.h" +#include "compiler/scopes.h" +#include "compiler/templates.h" +#include "compiler/types.h" + +static Boolean cscope_isambig; +static UInt8 cscope_lookuptype; +static SInt32 cscope_foundclassoffset; +static TemplClass *cscope_foundtemplate; +static TypeClass *cscope_foundclass; +static HashNameNode *cscope_name; +static TypeClass *cscope_mostderived; +Boolean cscope_is_member_func; +Object *cscope_currentfunc; +TypeClass *cscope_currentclass; +NameSpace *cscope_current; +NameSpace *cscope_root; + +void CScope_Setup() { + cscope_current = cscope_root = CScope_NewHashNameSpace(0); + cscope_currentclass = NULL; + cscope_currentfunc = NULL; + cscope_is_member_func = 0; +} + +void CScope_Cleanup() { +} + +void CScope_GetScope(CScopeSave *save) { + save->current = cscope_current; + save->currentclass = cscope_currentclass; + save->currentfunc = cscope_currentfunc; + save->is_member_func = cscope_is_member_func; +} + +void CScope_SetNameSpaceScope(NameSpace *nspace, CScopeSave *save) { + save->current = cscope_current; + save->currentclass = cscope_currentclass; + save->currentfunc = cscope_currentfunc; + save->is_member_func = cscope_is_member_func; + + cscope_current = nspace; + cscope_currentclass = nspace->theclass; + cscope_currentfunc = NULL; + cscope_is_member_func = 0; +} + +void CScope_SetClassScope(TypeClass *cls, CScopeSave *save) { + save->current = cscope_current; + save->currentclass = cscope_currentclass; + save->currentfunc = cscope_currentfunc; + save->is_member_func = cscope_is_member_func; + + cscope_current = cls->nspace; + cscope_currentclass = cls; + cscope_currentfunc = NULL; + cscope_is_member_func = 0; +} + +void CScope_SetClassDefScope(TypeClass *cls, CScopeSave *save) { + save->current = cscope_current; + save->currentclass = cscope_currentclass; + save->currentfunc = cscope_currentfunc; + save->is_member_func = cscope_is_member_func; + + cscope_current = cls->nspace; + cscope_currentclass = cls; +} + +void CScope_SetFunctionScope(Object *function, CScopeSave *save) { + save->current = cscope_current; + save->currentclass = cscope_currentclass; + save->currentfunc = cscope_currentfunc; + save->is_member_func = cscope_is_member_func; + + cscope_currentfunc = function; + cscope_currentclass = NULL; + cscope_is_member_func = 0; + + if (TYPE_FUNC(function->type)->flags & FUNC_FLAGS_METHOD) { + cscope_currentclass = TYPE_METHOD(function->type)->theclass; + cscope_current = cscope_currentclass->nspace; + cscope_is_member_func = TYPE_METHOD(function->type)->x26 == 0; + } else { + cscope_current = function->nspace; + } +} + +void CScope_SetMethodScope(Object *function, TypeClass *cls, Boolean unknownFlag, CScopeSave *save) { + save->current = cscope_current; + save->currentclass = cscope_currentclass; + save->currentfunc = cscope_currentfunc; + save->is_member_func = cscope_is_member_func; + + cscope_currentfunc = function; + cscope_currentclass = cls; + cscope_current = cls->nspace; + cscope_is_member_func = !unknownFlag; +} + +void CScope_RestoreScope(CScopeSave *saved) { + cscope_current = saved->current; + cscope_currentclass = saved->currentclass; + cscope_currentfunc = saved->currentfunc; + cscope_is_member_func = saved->is_member_func; +} + +static Boolean CScope_ObjectIsFunction(Object *obj) { + return obj->otype == OT_OBJECT && obj->type->type == TYPEFUNC; +} + +Boolean CScope_IsEmptySymTable() { + NameSpaceObjectList *scan; + NameSpaceName *nsname; + int i; + +#line 232 + CError_ASSERT(cscope_root->is_hash); + + i = 0; + do { + for (nsname = cscope_root->data.hash[i]; nsname; nsname = nsname->next) { + for (scan = &nsname->first; scan; scan = scan->next) { + if (scan->object->otype != OT_OBJECT || !CParser_IsPublicRuntimeObject(OBJECT(scan->object))) + return 0; + } + } + } while (++i < 1024); + + return 1; +} + +Boolean CScope_IsInLocalNameSpace(NameSpace *nspace) { + while (nspace) { + if (!nspace->is_global && !nspace->is_templ) + return 1; + nspace = nspace->parent; + } + return 0; +} + +static void CScope_AppendNameSpaceName(NameSpaceName *nsn) { + if (nsn->next) + CScope_AppendNameSpaceName(nsn->next); + if (nsn->name) { + AppendGListName(&name_mangle_list, nsn->name->name); + AppendGListName(&name_mangle_list, "::"); + } +} + +static void CScope_AmbigNameError(NameSpace *nspace1, NameSpace *nspace2, HashNameNode *name) { + if (name && nspace1 != nspace2) { + CError_Error(319, CError_GetNameString(nspace1, name), CError_GetNameString(nspace2, name)); + } else { + CError_Error(188, nspace2); + } +} + +NameSpaceObjectList *CScope_FindName(NameSpace *nspace, HashNameNode *name) { + NameSpaceName *scan; + + for (scan = nspace->tparams; scan; scan = scan->next) { + if (scan->name == name) + return &scan->first; + } + + if (!nspace->is_hash) + scan = nspace->data.list; + else + scan = nspace->data.hash[name->hashval & 1023]; + + for (; scan; scan = scan->next) { + if (scan->name == name) + return &scan->first; + } + + return NULL; +} + +static NameSpaceObjectList *CScope_FindQualName(NameSpace *nspace, HashNameNode *name) { + NameSpaceName *scan; + + if (!nspace->is_hash) + scan = nspace->data.list; + else + scan = nspace->data.hash[name->hashval & 1023]; + + for (; scan; scan = scan->next) { + if (scan->name == name) + return &scan->first; + } + + return NULL; +} + +NameSpaceName *CScope_FindNameSpaceName(NameSpace *nspace, HashNameNode *name) { + NameSpaceName *scan; + + for (scan = nspace->tparams; scan; scan = scan->next) { + if (scan->name == name) + return scan; + } + + if (!nspace->is_hash) + scan = nspace->data.list; + else + scan = nspace->data.hash[name->hashval & 1023]; + + for (; scan; scan = scan->next) { + if (scan->name == name) + return scan; + } + + return NULL; +} + +NameSpaceObjectList *CScope_InsertName(NameSpace *nspace, HashNameNode *name) { + NameSpaceName **nsnptr; + NameSpaceName *nsname; + if (nspace->is_global) + nsname = galloc(sizeof(NameSpaceName)); + else + nsname = lalloc(sizeof(NameSpaceName)); + + nsname->name = name; + nsname->first.next = NULL; + nsname->first.object = NULL; + if (nspace->is_hash) { + nsnptr = &nspace->data.hash[name->hashval & 0x3FF]; + nsname->next = *nsnptr; + *nsnptr = nsname; + } else { + nsname->next = nspace->data.list; + nspace->data.list = nsname; + } + nspace->names++; + + return &nsname->first; +} + +static NameSpaceObjectList *CScope_AppendName(NameSpace *nspace, HashNameNode *name) { + NameSpaceName *nsname; + NameSpaceName *scan; +#line 387 + CError_ASSERT(!nspace->is_hash); + + if (nspace->is_global) + nsname = galloc(sizeof(NameSpaceName)); + else + nsname = lalloc(sizeof(NameSpaceName)); + + nsname->next = NULL; + nsname->name = name; + nsname->first.next = NULL; + nsname->first.object = NULL; + if (nspace->data.list) { + scan = nspace->data.list; + while (scan->next) + scan = scan->next; + scan->next = nsname; + } else { + nspace->data.list = nsname; + } + nspace->names++; + + return &nsname->first; +} + +static NameSpaceList *CScope_AddNameSpaceToList(NameSpaceList *list, NameSpace *nspace) { + NameSpaceList *scan; + NameSpaceList *newlist; + ClassList *clslist; + + for (scan = list; scan; scan = scan->next) { + if (scan->nspace == nspace) + return list; + } + + newlist = lalloc(sizeof(NameSpaceList)); + newlist->next = list; + newlist->nspace = nspace; + list = newlist; + + if (nspace->theclass) { + list = CScope_AddNameSpaceToList(list, nspace->parent); + for (clslist = nspace->theclass->bases; clslist; clslist = clslist->next) + list = CScope_AddNameSpaceToList(list, clslist->base->nspace); + } + + return list; +} + +static NameSpaceList *CScope_BuildTypeAssociatedNameSpaceList(NameSpaceList *list, Type *type) { + FuncArg *arg; + +restart: + switch (type->type) { + case TYPEVOID: + case TYPEINT: + case TYPEFLOAT: + case TYPESTRUCT: + case TYPEBITFIELD: + case TYPETEMPLATE: + case TYPETEMPLDEPEXPR: + break; + case TYPEPOINTER: + case TYPEARRAY: + type = TYPE_POINTER(type)->target; + goto restart; + case TYPEENUM: + list = CScope_AddNameSpaceToList(list, TYPE_ENUM(type)->nspace); + break; + case TYPEFUNC: + for (arg = TYPE_FUNC(type)->args; arg; arg = arg->next) { + if (arg->type) + list = CScope_BuildTypeAssociatedNameSpaceList(list, arg->type); + } + type = TYPE_FUNC(type)->functype; + goto restart; + case TYPEMEMBERPOINTER: + list = CScope_BuildTypeAssociatedNameSpaceList(list, TYPE_MEMBER_POINTER(type)->ty1); + type = TYPE_MEMBER_POINTER(type)->ty2; + if (type->type != TYPECLASS) + break; + case TYPECLASS: + list = CScope_AddNameSpaceToList(list, TYPE_CLASS(type)->nspace); + break; + default: +#line 494 + CError_FATAL(); + } + + return list; +} + +static NameSpaceList *CScope_BuildAssociatedNameSpaceList(ENodeList *enodeList) { + // not 100% sure about the type for this but i think it's right?? + NameSpaceList *nslist = NULL; + while (enodeList) { + nslist = CScope_BuildTypeAssociatedNameSpaceList(nslist, enodeList->node->rtype); + enodeList = enodeList->next; + } + return nslist; +} + +static Boolean CScope_IsSameObject(Object *a, Object *b) { + if (a == b) + return 1; + return (a->nspace == b->nspace) && (a->name == b->name) && is_typesame(a->type, b->type); +} + +NameSpaceObjectList *CScope_ArgumentDependentNameLookup(NameSpaceObjectList *list, HashNameNode *name, ENodeList *argNodes, Boolean flag) { + NameSpaceList *scan; + NameSpaceObjectList *iscan; + NameSpaceObjectList *iiscan; + NameSpaceObjectList *newlist; + + for (scan = CScope_BuildAssociatedNameSpaceList(argNodes); scan; scan = scan->next) { + for (iscan = CScope_FindQualName(scan->nspace, name); iscan; iscan = iscan->next) { + if (iscan->object->otype != OT_OBJECT) + continue; + if (OBJECT(iscan->object)->type->type != TYPEFUNC) + continue; + if (flag && (TYPE_FUNC(OBJECT(iscan->object)->type)->flags & FUNC_FLAGS_METHOD)) + continue; + + for (iiscan = list; iiscan; iiscan = iiscan->next) { + if (iiscan->object->otype == OT_OBJECT && CScope_IsSameObject(OBJECT(iiscan->object), OBJECT(iscan->object))) + break; + } + + if (!iiscan) { + newlist = lalloc(sizeof(NameSpaceObjectList)); + newlist->object = iscan->object; + newlist->next = list; + list = newlist; + } + } + } + + return list; +} + +NameSpace *CScope_NewHashNameSpace(HashNameNode *name) { + NameSpace *nspace; + void *buffer; + + buffer = galloc(0x400 * sizeof(void *)); + memclrw(buffer, 0x400 * sizeof(void *)); + nspace = galloc(sizeof(NameSpace)); + memclrw(nspace, sizeof(NameSpace)); + nspace->name = name; + nspace->data.hash = buffer; + nspace->is_hash = 1; + nspace->is_global = 1; + return nspace; +} + +NameSpace *CScope_NewListNameSpace(HashNameNode *name, Boolean is_global) { + NameSpace *nspace; + if (is_global) { + nspace = galloc(sizeof(NameSpace)); + memclrw(nspace, sizeof(NameSpace)); + } else { + nspace = lalloc(sizeof(NameSpace)); + memclrw(nspace, sizeof(NameSpace)); + } + nspace->name = name; + nspace->is_hash = 0; + nspace->is_global = is_global; + return nspace; +} + +NameSpace *CScope_FindNonClassNonFunctionNS(NameSpace *nspace) { + while (nspace) { + if (!nspace->theclass && !nspace->is_templ) + return nspace; + nspace = nspace->parent; + } + return cscope_root; +} + +NameSpace *CScope_FindGlobalNS(NameSpace *nspace) { + while (nspace) { + if (nspace->name && !nspace->theclass && nspace->is_global) + return nspace; + nspace = nspace->parent; + } + return cscope_root; +} + +Boolean CScope_IsStdNameSpace(NameSpace *nspace) { + return nspace && !nspace->theclass && (nspace->parent == cscope_root) && nspace->name && !strcmp(nspace->name->name, "std"); +} + +Boolean CScope_IsEmptyNameSpace(NameSpace *nspace) { +#line 664 + CError_ASSERT(!nspace->is_hash); + return !nspace->data.list; +} + +void CScope_MergeNameSpace(NameSpace *dst, NameSpace *src) { + NameSpaceName *nsname; + +#line 678 + CError_ASSERT(!dst->is_hash && !src->is_hash); + + if ((nsname = dst->data.list)) { + while (nsname->next) + nsname = nsname->next; + nsname->next = src->data.list; + } else { + dst->data.list = src->data.list; + } +} + +void CScope_AddObject(NameSpace *nspace, HashNameNode *name, ObjBase *obj) { + NameSpaceObjectList *objlist; + NameSpaceObjectList *newlist; + + objlist = CScope_FindQualName(nspace, name); + if (objlist) { + if (nspace->is_global) + newlist = galloc(sizeof(NameSpaceObjectList)); + else + newlist = lalloc(sizeof(NameSpaceObjectList)); + + if (obj->otype == OT_NAMESPACE || objlist->object->otype == OT_NAMESPACE) { + CError_Error(322/*, objlist->object*/); + return; + } + + if (obj->otype == OT_TYPETAG) { + do { + if (objlist->object->otype == OT_TYPETAG) { + CError_Error(322/*, objlist->object*/); + return; + } + + if (copts.cplusplus && objlist->object->otype == OT_TYPE && !is_typesame(OBJ_TYPE_TAG(obj)->type, OBJ_TYPE(objlist->object)->type)) { + CError_Error(332); + return; + } + + if (!objlist->next) { + objlist->next = newlist; + newlist->next = NULL; + newlist->object = obj; + return; + } + objlist = objlist->next; + } while (1); + } + + if (objlist->object->otype == OT_TYPETAG) { + if (copts.cplusplus && obj->otype == OT_TYPE && !is_typesame(OBJ_TYPE(obj)->type, OBJ_TYPE_TAG(objlist->object)->type)) { + CError_Error(332); + return; + } + +#line 739 + CError_ASSERT(!objlist->next); + + newlist->object = objlist->object; + newlist->next = NULL; + objlist->object = obj; + objlist->next = newlist; + return; + } + + if (!copts.cplusplus || !CScope_ObjectIsFunction(OBJECT(obj))) { + CError_Error(322); + return; + } + + do { + if (objlist->object->otype == OT_TYPETAG) { + objlist->next = galloc(sizeof(NameSpaceObjectList)); + objlist->next->next = NULL; + objlist->next->object = objlist->object; + objlist->object = obj; + return; + } + + if (!CScope_ObjectIsFunction(OBJECT(objlist->object))) { + CError_Error(322); + return; + } + + if (!objlist->next) { + objlist->next = galloc(sizeof(NameSpaceObjectList)); + objlist->next->next = NULL; + objlist->next->object = obj; + return; + } + + objlist = objlist->next; + } while (1); + } else if (nspace->theclass && TYPE_CLASS(nspace->theclass)->flags & CLASS_FLAGS_900) { + CScope_AppendName(nspace, name)->object = obj; + } else { + CScope_InsertName(nspace, name)->object = obj; + } +} + +void CScope_AddGlobalObject(Object *obj) { + obj->nspace = cscope_root; + CScope_AddObject(cscope_root, obj->name, OBJ_BASE(obj)); +} + +NameSpaceLookupList *CScope_BuildNameSpaceLookupList(NameSpace *nspace) { + NameSpaceLookupList *lookup; + NameSpaceList list; + NameSpaceList *current; + NameSpaceList *current2; + NameSpaceList *current3; + NameSpaceList *newlist; + NameSpaceLookupList *currentL; + NameSpace *currentNS; + + lookup = lalloc(sizeof(NameSpaceLookupList)); + memclrw(lookup, sizeof(NameSpaceLookupList)); + lookup->nspace = nspace; + + if (nspace->parent) + lookup->next = CScope_BuildNameSpaceLookupList(nspace->parent); + + if (nspace->usings) { + list.nspace = nspace; + list.next = NULL; + for (current2 = &list; current2; current2 = current2->next) { + for (current = current2->nspace->usings; current; current = current->next) { + for (current3 = &list; current3; current3 = current3->next) { + if (current3->nspace == current->nspace) + break; + } + if (!current3) { + newlist = lalloc(sizeof(NameSpaceList)); + newlist->nspace = current->nspace; + newlist->next = current2->next; + current2->next = newlist; + } + } + } + + for (current = list.next; current; current = current->next) { + for (currentL = lookup; currentL; currentL = currentL->next) { + for (currentNS = current->nspace; currentNS; currentNS = currentNS->parent) { + if (currentL->nspace == currentNS) + goto foundIt; + } + } +#line 853 + CError_FATAL(); + foundIt: + for (current2 = currentL->namespaces; current2; current2 = current2->next) { + if (current2->nspace == current->nspace) + break; + } + if (!current2) { + newlist = lalloc(sizeof(NameSpaceList)); + newlist->nspace = current->nspace; + newlist->next = currentL->namespaces; + currentL->namespaces = newlist; + } + } + } + + return lookup; +} + +static Boolean CScope_IsInLookup(NameSpaceLookupList *list, NameSpace *nspace) { + NameSpaceLookupList *scan; + NameSpaceList *iscan; + + for (scan = list; scan; scan = scan->next) { + if (scan->nspace == nspace) + return 1; + for (iscan = scan->namespaces; iscan; iscan = iscan->next) { + if (iscan->nspace == nspace) + return 1; + } + } + + return 0; +} + +static NameSpaceLookupList *CScope_BuildNameSpaceMemberLookupList(NameSpace *nspace) { + NameSpaceLookupList list; + NameSpaceLookupList *current; + NameSpaceList *scan; + NameSpaceList *oscan; + NameSpaceList *newlist; + + list.nspace = nspace; + list.namespaces = NULL; + list.next = NULL; + + for (current = &list; current; current = current->next) { + if (current->nspace) { + for (scan = current->nspace->usings; scan; scan = scan->next) { + if (!CScope_IsInLookup(&list, scan->nspace)) { + if (!current->next) { + current->next = lalloc(sizeof(NameSpaceLookupList)); + current->next->nspace = NULL; + current->next->namespaces = NULL; + current->next->next = NULL; + } + newlist = lalloc(sizeof(NameSpaceList)); + newlist->nspace = scan->nspace; + newlist->next = current->next->namespaces; + current->next->namespaces = newlist; + } + } + } + + for (oscan = current->namespaces; oscan; oscan = oscan->next) { + for (scan = oscan->nspace->usings; scan; scan = scan->next) { + if (!CScope_IsInLookup(&list, scan->nspace)) { + if (!current->next) { + current->next = lalloc(sizeof(NameSpaceLookupList)); + current->next->nspace = NULL; + current->next->namespaces = NULL; + current->next->next = NULL; + } + newlist = lalloc(sizeof(NameSpaceList)); + newlist->nspace = scan->nspace; + newlist->next = current->next->namespaces; + current->next->namespaces = newlist; + } + } + } + } + + return list.next; +} + +static NameSpaceObjectList *CScope_CopyNameSpaceObjectList(NameSpaceObjectList *list) { + NameSpaceObjectList *first, *current; + + first = current = lalloc(sizeof(NameSpaceObjectList)); + do { + current->object = list->object; + list = list->next; + if (!list) { + current->next = NULL; + break; + } else { + current->next = lalloc(sizeof(NameSpaceObjectList)); + current = current->next; + } + } while (1); + + return first; +} + +static NameSpace *CScope_ExtractNameSpace(NameSpaceObjectList *list, Boolean *fail) { + Type *type; + +restart: + if (!list) + return NULL; + + switch (list->object->otype) { + case OT_TYPE: + type = OBJ_TYPE(list->object)->type; + break; + case OT_TYPETAG: + type = OBJ_TYPE_TAG(list->object)->type; + break; + case OT_NAMESPACE: + return OBJ_NAMESPACE(list->object)->nspace; + default: +#line 1052 + CError_FATAL(); + break; + case OT_ENUMCONST: + case OT_MEMBERVAR: + case OT_OBJECT: + list = list->next; + goto restart; + } + + if (type->type != TYPECLASS) { + if (type->type == TYPETEMPLATE) + return NULL; + CError_Error(320); + if (fail) + *fail = 1; + return NULL; + } else { + return TYPE_CLASS(type)->nspace; + } +} + +static BClassList *CScope_RecFindClassMember(CScopeParseResult *result, TypeClass *tclass, SInt32 offset) { + // does not match, r24 and r23 are swapped at the end x.x + Boolean fail; + NameSpace *nspace; + NameSpaceObjectList *list; + ClassList *base; + TypeClass *bestClass; + BClassList *bestBase, *n; + BClassList *candidate; + SInt32 thisoffset; + BClassList *newlist; + + if ((list = CScope_FindName(tclass->nspace, cscope_name))) { + if (cscope_foundclass) { + if (CClass_ClassDominates(cscope_foundclass, tclass)) + return NULL; + if (CClass_ClassDominates(tclass, cscope_foundclass)) + cscope_foundclass = NULL; + } + + switch (cscope_lookuptype) { + case 2: + fail = 0; + if ((nspace = CScope_ExtractNameSpace(list, &fail))) { + if (cscope_foundclass) { + if (cscope_foundclass != tclass) { + CScope_AmbigNameError(cscope_foundclass->nspace, tclass->nspace, cscope_name); + return NULL; + } + if (cscope_foundclassoffset != offset) + cscope_isambig = 1; + return NULL; + } + + cscope_foundclass = tclass; + cscope_foundclassoffset = offset; + result->nspace_0 = nspace; + + newlist = lalloc(sizeof(BClassList)); + newlist->next = NULL; + newlist->type = (Type *) tclass; + return newlist; + } + + if (fail) + return NULL; + break; + case 0: + if (cscope_foundclass) { + if ( + list->object->otype == OT_TYPETAG + && result->nsol_14->object->otype == OT_TYPETAG + && OBJ_TYPE_TAG(list->object)->type->type == TYPECLASS + && OBJ_TYPE_TAG(result->nsol_14->object)->type->type == TYPECLASS + && (TYPE_CLASS(OBJ_TYPE_TAG(list->object)->type)->flags & CLASS_FLAGS_800) + && (TYPE_CLASS(OBJ_TYPE_TAG(result->nsol_14->object)->type)->flags & CLASS_FLAGS_800) + && TEMPL_CLASS_INST(OBJ_TYPE_TAG(list->object)->type)->templ == TEMPL_CLASS_INST(OBJ_TYPE_TAG(result->nsol_14->object)->type)->templ + ) { + cscope_foundtemplate = TEMPL_CLASS_INST(OBJ_TYPE_TAG(result->nsol_14->object)->type)->templ; + } else { + if (cscope_foundclass != tclass) { + CScope_AmbigNameError(cscope_foundclass->nspace, tclass->nspace, cscope_name); + return NULL; + } + if (cscope_foundclassoffset != offset) { + cscope_isambig = 1; + return NULL; + } + } + } + + cscope_foundclass = tclass; + cscope_foundclassoffset = offset; + result->nsol_14 = list; + newlist = lalloc(sizeof(BClassList)); + newlist->next = NULL; + newlist->type = (Type *) tclass; + return newlist; + case 1: + for (; list; list = list->next) { + if (list->object->otype == OT_TYPETAG) { + if (cscope_foundclass) { + if (cscope_foundclass != tclass) { + CScope_AmbigNameError(cscope_foundclass->nspace, tclass->nspace, cscope_name); + return NULL; + } + if (cscope_foundclassoffset != offset) + cscope_isambig = 1; + return NULL; + } + + cscope_foundclass = tclass; + cscope_foundclassoffset = offset; + result->x8 = OBJ_TYPE_TAG(list->object)->type; + newlist = lalloc(sizeof(BClassList)); + newlist->next = NULL; + newlist->type = (Type *) tclass; + return newlist; + } + } + break; + default: +#line 1202 + CError_FATAL(); + } + } + + for (base = tclass->bases, bestBase = NULL; base; base = base->next) { + thisoffset = base->is_virtual ? CClass_VirtualBaseOffset(cscope_mostderived, base->base) : offset + base->offset; + if ((candidate = CScope_RecFindClassMember(result, base->base, thisoffset))) { + n = lalloc(sizeof(BClassList)); + n->next = candidate; + n->type = (Type *) tclass; + if (bestBase && bestClass == cscope_foundclass) { + if (CClass_IsMoreAccessiblePath(n, bestBase)) + bestBase = n; + } else { + bestClass = cscope_foundclass; + bestBase = n; + } + } + } + + return bestBase; +} + +static Boolean CScope_FindClassMember(CScopeParseResult *result, NameSpace *nspace, HashNameNode *name, UInt8 lookupType) { + BClassList *bcl; + BClassList *scan; + + cscope_mostderived = nspace->theclass; + cscope_foundclass = NULL; + cscope_foundtemplate = NULL; + cscope_name = name; + cscope_lookuptype = lookupType; + cscope_isambig = 0; + + if ((bcl = CScope_RecFindClassMember(result, cscope_mostderived, 0))) { + if (cscope_foundtemplate) + return 1; + + if ((scan = result->bcl_18)) { + while (scan->next) + scan = scan->next; + if (TYPE_CLASS(scan->type) != cscope_mostderived) + scan->next = bcl; + else + scan->next = bcl->next; + } else { + result->bcl_18 = bcl; + } + + if (cscope_isambig) + result->isambig = 1; + return 1; + } else { + return 0; + } +} + +static BClassList *CScope_GetAccessPathRec(TypeClass *src, TypeClass *dest, SInt32 offset) { + BClassList *list; + BClassList *best; + ClassList *base; + + if (src == dest) { + if (cscope_foundclass && cscope_foundclassoffset != offset) + CError_Error(188); + + list = lalloc(sizeof(BClassList)); + list->next = NULL; + list->type = (Type *) src; + cscope_foundclass = src; + cscope_foundclassoffset = offset; + return list; + } + + for (base = src->bases, best = NULL; base; base = base->next) { + if ((list = CScope_GetAccessPathRec(base->base, dest, base->is_virtual ? CClass_VirtualBaseOffset(cscope_mostderived, base->base) : (offset + base->offset)))) + best = list; + } + + if (best) { + list = lalloc(sizeof(BClassList)); + list->next = best; + list->type = (Type *) src; + return list; + } + + return NULL; +} + +static BClassList *CScope_GetAccessPath(TypeClass *src, TypeClass *dest) { + cscope_mostderived = src; + cscope_foundclass = NULL; + return CScope_GetAccessPathRec(src, dest, 0); +} + +static NameSpace *CScope_FindLookupNameSpace(CScopeNSIterator *iterator, NameSpaceLookupList *lookup, HashNameNode *name) { + NameSpaceObjectList *list; + NameSpaceList *scan; + NameSpace *retnspace = NULL; + NameSpace *candidate; + Boolean fail = 0; + + if (lookup->nspace->theclass) { + if (CScope_FindClassMember(iterator->result, lookup->nspace, name, 2)) { + retnspace = iterator->result->nspace_0; + iterator->result->nspace_0 = NULL; + return retnspace; + } else { + return NULL; + } + } + + if ((list = CScope_FindName(lookup->nspace, name))) { + fail = 0; + retnspace = CScope_ExtractNameSpace(list, &fail); + if (fail) + return NULL; + } + + for (scan = lookup->namespaces; scan; scan = scan->next) { + fail = 0; + if ((list = CScope_FindName(scan->nspace, name)) && (candidate = CScope_ExtractNameSpace(list, &fail))) { + if (retnspace) { + if (retnspace != candidate) + CScope_AmbigNameError(retnspace, candidate, NULL); + } else { + retnspace = candidate; + } + } + if (fail) + return NULL; + } + + return retnspace; +} + +static NameSpaceObjectList *CScope_FindLookupName(NameSpaceLookupList *list, HashNameNode *name, NameSpace **foundnspace) { + NameSpaceName *scanname; + NameSpaceObjectList *tmpOL; + NameSpaceObjectList *r31; + NameSpaceObjectList *r30; + NameSpaceList *r29; + NameSpace *r28; + Boolean r27; + NameSpaceObjectList *r6; + NameSpaceObjectList *scanOL; + NameSpaceObjectList *newlist; + + if (list->nspace) { + for (scanname = list->nspace->tparams; scanname; scanname = scanname->next) { + if (scanname->name == name) + return &scanname->first; + } + + if ((tmpOL = CScope_FindName(list->nspace, name))) { + r31 = tmpOL; + r28 = list->nspace; + } else { + r31 = NULL; + r28 = NULL; + } + } else { + r31 = NULL; + r28 = NULL; + } + + r27 = 0; + for (r29 = list->namespaces; r29; r29 = r29->next) { + if ((tmpOL = CScope_FindName(r29->nspace, name))) { + if (r31) { + for (r30 = tmpOL; r30; r30 = r30->next) { + for (r6 = r31; r6; r6 = r6->next) { + if (r6->object == r30->object) + break; + if (r6->object->otype == r30->object->otype) { + switch (r6->object->otype) { + case OT_TYPE: + if ((OBJ_TYPE(r6->object)->type == OBJ_TYPE(r30->object)->type) && (OBJ_TYPE(r6->object)->unk6 == OBJ_TYPE(r30->object)->unk6)) + goto break1; + break; + case OT_TYPETAG: + if (OBJ_TYPE_TAG(r6->object)->type == OBJ_TYPE_TAG(r30->object)->type) + goto break1; + break; + case OT_ENUMCONST: + if (OBJ_ENUM_CONST(r6->object)->type == OBJ_ENUM_CONST(r30->object)->type) + goto break1; + break; + case OT_OBJECT: + if (OBJECT(r6->object)->datatype == DALIAS) { + if (OBJECT(r30->object)->datatype == DALIAS) { + if (OBJECT(r6->object)->u.alias.object == OBJECT(r30->object)->u.alias.object) + goto break1; + } else { + if (OBJECT(r6->object)->u.alias.object == OBJECT(r30->object)) + goto break1; + } + } else { + if ((OBJECT(r30->object)->datatype == DALIAS) && OBJECT(r6->object) == OBJECT(r30->object)->u.alias.object) + goto break1; + } + break; + } + } + } + break1: + if (!r6) { + if (!r27) { + r31 = CScope_CopyNameSpaceObjectList(r31); + r27 = 1; + } + if (CScope_ObjectIsFunction(OBJECT(r30->object))) { + for (scanOL = r31; scanOL; scanOL = scanOL->next) { + if (!CScope_ObjectIsFunction(OBJECT(scanOL->object))) { + if (scanOL->object->otype != OT_TYPETAG) { + CScope_AmbigNameError(r28, r29->nspace, name); + break; + } + } + } + } else if (r30->object->otype == OT_TYPETAG) { + for (scanOL = r31; scanOL; scanOL = scanOL->next) { + if (scanOL->object->otype == OT_TYPETAG) { + CScope_AmbigNameError(r28, r29->nspace, name); + break; + } + } + } else { + for (scanOL = r31; scanOL; scanOL = scanOL->next) { + if (scanOL->object->otype != OT_TYPETAG) { + CScope_AmbigNameError(r28, r29->nspace, name); + break; + } + } + } + + if (!scanOL) { + newlist = lalloc(sizeof(NameSpaceObjectList)); + newlist->object = r30->object; + newlist->next = r31; + r31 = newlist; + } + } + } + } else { + r31 = tmpOL; + r28 = r29->nspace; + } + } + } + + if (foundnspace) + *foundnspace = r28; + return r31; +} + +static NameSpaceObjectList *CScope_NSIteratorFind(CScopeNSIterator *iterator, HashNameNode *name) { + NameSpaceObjectList *list; + + if (iterator->lookup) { + if (iterator->lookup->namespaces) + return CScope_FindLookupName(iterator->lookup, name, NULL); + if (iterator->lookup->nspace->theclass) { + if (CScope_FindClassMember(iterator->result, iterator->lookup->nspace, name, 0)) { + list = iterator->result->nsol_14; + iterator->result->nsol_14 = NULL; + return list; + } else { + return NULL; + } + } + + if ((list = CScope_FindName(iterator->lookup->nspace, name))) + return list; + } else { + if (iterator->nspace->theclass) { + if (CScope_FindClassMember(iterator->result, iterator->nspace, name, 0)) { + list = iterator->result->nsol_14; + iterator->result->nsol_14 = NULL; + return list; + } else { + return NULL; + } + } + + if ((list = CScope_FindName(iterator->nspace, name))) + return list; + } + + return NULL; +} + +static NameSpaceObjectList *CScope_NSIteratorNonClassFind(CScopeNSIterator *iterator, HashNameNode *name) { + NameSpaceObjectList *list; + + if (iterator->lookup) { + if (iterator->lookup->namespaces) + return CScope_FindLookupName(iterator->lookup, name, NULL); + if (iterator->lookup->nspace->theclass) + return NULL; + if ((list = CScope_FindName(iterator->lookup->nspace, name))) + return list; + } else { + if (iterator->nspace->theclass) + return NULL; + if ((list = CScope_FindName(iterator->nspace, name))) + return list; + } + + return NULL; +} + +static NameSpace *CScope_NSIteratorFindNameSpace(CScopeNSIterator *iterator, HashNameNode *name) { + NameSpace *nspace; + NameSpaceObjectList *list; + + if (iterator->lookup) { + if (iterator->lookup->namespaces) + return CScope_FindLookupNameSpace(iterator, iterator->lookup, name); + if (iterator->lookup->nspace->theclass) { + if (CScope_FindClassMember(iterator->result, iterator->lookup->nspace, name, 2)) { + nspace = iterator->result->nspace_0; + iterator->result->nspace_0 = NULL; + return nspace; + } else { + return NULL; + } + } + + if ((list = CScope_FindName(iterator->lookup->nspace, name))) + return CScope_ExtractNameSpace(list, NULL); + } else { + if (iterator->nspace->theclass) { + if (CScope_FindClassMember(iterator->result, iterator->nspace, name, 2)) { + nspace = iterator->result->nspace_0; + iterator->result->nspace_0 = NULL; + return nspace; + } else { + return NULL; + } + } + + if ((list = CScope_FindName(iterator->nspace, name))) + return CScope_ExtractNameSpace(list, NULL); + } + + return NULL; +} + +static Boolean CScope_SetupParseNameResult(CScopeParseResult *result, NameSpaceObjectList *list, HashNameNode *name) { + if (!list->next || list->next->object->otype == OT_TYPETAG) { + switch (list->object->otype) { + case OT_NAMESPACE: + CError_Error(321); + return 0; + case OT_TYPE: + result->x8 = OBJ_TYPE(list->object)->type; + result->xC = OBJ_TYPE(list->object)->unk6; + result->obj_10 = list->object; + result->name_4 = name; + result->x20 = 1; + break; + case OT_TYPETAG: + result->x8 = OBJ_TYPE_TAG(list->object)->type; + result->xC = NULL; + result->obj_10 = list->object; + result->name_4 = name; + result->x20 = 1; + break; + default: + result->obj_10 = list->object; + } + } else { + result->nsol_14 = list; + } + + return 1; +} + +Boolean CScope_FindQualifiedClassMember(CScopeParseResult *result, TypeClass *tclass, HashNameNode *name) { + NameSpaceObjectList *list; + + memclrw(result, sizeof(CScopeParseResult)); + CDecl_CompleteType((Type *) tclass); + + if (CScope_FindClassMember(result, tclass->nspace, name, 0)) { + list = result->nsol_14; +#line 1780 + CError_ASSERT(list); + result->nsol_14 = NULL; + + if (CScope_SetupParseNameResult(result, list, name) && !result->x8) + return 1; + else + CError_Error(340, name->name); + } + + return 0; +} + +static NameSpace *CScope_FindQualifiedNameSpace(CScopeParseResult *result, NameSpace *nspace, HashNameNode *name) { + NameSpaceObjectList *list; + NameSpace *cand; + NameSpace *found; + NameSpaceList *scan; + NameSpaceLookupList *lookup; + Boolean fail = 0; + + if (nspace->theclass) { + if (CScope_FindClassMember(result, nspace, name, 2)) { + nspace = result->nspace_0; + result->nspace_0 = NULL; + return nspace; + } else { + return NULL; + } + } + + if ((list = CScope_FindQualName(nspace, name)) && CScope_ExtractNameSpace(list, &fail)) + return nspace; + + if (!fail && nspace->usings) { + found = NULL; + for (lookup = CScope_BuildNameSpaceMemberLookupList(nspace); lookup; lookup = lookup->next) { + for (scan = lookup->namespaces; scan; scan = scan->next) { + if ((list = CScope_FindQualName(scan->nspace, name)) && (cand = CScope_ExtractNameSpace(list, &fail))) { + if (found && cand != found) + CScope_AmbigNameError(found, cand, NULL); + found = cand; + } + + if (fail) + return NULL; + } + + if (found) + return found; + } + } + + return NULL; +} + +static NameSpaceObjectList *CScope_FindQualifiedName(CScopeParseResult *result, NameSpace *nspace, HashNameNode *name, NameSpace **foundnspace) { + NameSpaceObjectList *list; + NameSpaceLookupList *lookup; + + if (nspace->theclass) { + CDecl_CompleteType((Type *) nspace->theclass); + if (CScope_FindClassMember(result, nspace, name, 0)) { + list = result->nsol_14; + result->nsol_14 = NULL; + return list; + } else { + return NULL; + } + } + + if ((list = CScope_FindQualName(nspace, name))) { + *foundnspace = nspace; + return list; + } + + if (nspace->usings) { + for (lookup = CScope_BuildNameSpaceMemberLookupList(nspace); lookup; lookup = lookup->next) { + if ((list = CScope_FindLookupName(lookup, name, foundnspace))) + return list; + } + } + + return NULL; +} + +static Boolean CScope_FindQualifiedTag(CScopeParseResult *result, NameSpace *nspace, HashNameNode *name) { + NameSpaceObjectList *list; + NameSpaceLookupList *lookup; + Type *best; + NameSpace *bestnspace; + NameSpaceList *scan; + + if (nspace->theclass) { + CDecl_CompleteType((Type *) nspace->theclass); + return CScope_FindClassMember(result, nspace, name, 1) != 0; + } + + if ((list = CScope_FindQualName(nspace, name))) { + for (; list; list = list->next) { + if (list->object->otype == OT_TYPETAG) { + result->x8 = OBJ_TYPE_TAG(list->object)->type; + return 1; + } + } + } + + if (nspace->usings) { + best = NULL; + for (lookup = CScope_BuildNameSpaceMemberLookupList(nspace); lookup; lookup = lookup->next) { + for (scan = lookup->namespaces; scan; scan = scan->next) { + for (list = CScope_FindQualName(scan->nspace, name); list; list = list->next) { + if (list->object->otype == OT_TYPETAG) { + if (best && best != OBJ_TYPE_TAG(list->object)->type) + CScope_AmbigNameError(scan->nspace, bestnspace, name); + best = OBJ_TYPE_TAG(list->object)->type; + bestnspace = scan->nspace; + break; + } + } + } + + if (best) { + result->x8 = best; + return 1; + } + } + } + + return 0; +} + +inline void CScope_NSIteratorInit(CScopeNSIterator *iterator, NameSpace *nspace, CScopeParseResult *result) { + // assumed name + if (nspace->usings) { + iterator->nspace = NULL; + iterator->lookup = CScope_BuildNameSpaceLookupList(nspace); + } else { + iterator->nspace = nspace; + iterator->lookup = NULL; + } + iterator->result = result; +} + +inline Boolean CScope_NSIteratorNext(CScopeNSIterator *iterator) { + // assumed name + if (iterator->lookup) + return (iterator->lookup = iterator->lookup->next) != NULL; + if (iterator->result->x1D) + return 0; + + if ((iterator->nspace = iterator->nspace->parent)) { + if (iterator->nspace->usings && !iterator->result->x1D) { + iterator->lookup = CScope_BuildNameSpaceLookupList(iterator->nspace); + iterator->nspace = NULL; + } + return 1; + } else { + return 0; + } +} + +Type *CScope_GetType(NameSpace *nspace, HashNameNode *name, void **unk6) { + CScopeParseResult result; + CScopeNSIterator iterator; + NameSpaceObjectList *list; + Boolean ok; + + memclrw(&result, sizeof(result)); + CScope_NSIteratorInit(&iterator, nspace, &result); + + do { + for (list = CScope_NSIteratorFind(&iterator, name); list; list = list->next) { + if (list->object->otype == OT_TYPETAG) { + if (unk6) + *unk6 = NULL; + return OBJ_TYPE_TAG(list->object)->type; + } + if (list->object->otype == OT_TYPE) { + if (unk6) + *unk6 = OBJ_TYPE(list->object)->unk6; + return OBJ_TYPE(list->object)->type; + } + } + } while (CScope_NSIteratorNext(&iterator)); + + return NULL; +} + +Type *CScope_GetTagType(NameSpace *nspace, HashNameNode *name) { + CScopeParseResult result; + CScopeNSIterator iterator; + NameSpaceObjectList *list; + Boolean ok; + + memclrw(&result, sizeof(result)); + CScope_NSIteratorInit(&iterator, nspace, &result); + + do { + for (list = CScope_NSIteratorFind(&iterator, name); list; list = list->next) { + if (list->object->otype == OT_TYPETAG) + return OBJ_TYPE_TAG(list->object)->type; + } + } while (CScope_NSIteratorNext(&iterator)); + + return NULL; +} + +static Boolean CScope_DependentTemplateMember(CScopeParseResult *result, TypeTemplDep *ttempldep, Boolean flag1, Boolean flag2) { + // does not match, sign extension/caching mishap + SInt32 streamstate; + short token; + short token2; + TypeTemplDep *newtype; + TypeTemplDep *newtype2; + + CPrep_TokenStreamGetState(&streamstate); +#line 2026 + CError_ASSERT(lex() == TK_COLON_COLON); + + do { + token = lex(); + if (token == TK_OPERATOR && flag1) { + if (!CParser_ParseOperatorName(NULL, 1, 1)) + return 0; + newtype = CDecl_NewTemplDepType(TEMPLDEP_QUALNAME); + newtype->u.qual.type = ttempldep; + newtype->u.qual.name = tkidentifier; + CPrep_TokenStreamSetState(&streamstate); + lex(); + tk = lex(); + result->x8 = (Type *) newtype; + return 1; + } else if (token == TK_TEMPLATE) { + if (lex() != TK_IDENTIFIER) { + CError_Error(107); + return 0; + } + + CPrep_TokenStreamGetState(&streamstate); + newtype = CDecl_NewTemplDepType(TEMPLDEP_QUALNAME); + newtype->u.qual.type = ttempldep; + newtype->u.qual.name = tkidentifier; + if ((token2 = lex()) != '<') { + CError_Error(230); + return 0; + } + tk = token2; + newtype2 = CDecl_NewTemplDepType(TEMPLDEP_QUALTEMPL); + newtype2->u.qualtempl.type = newtype; + newtype2->u.qualtempl.args = CTempl_ParseUncheckTemplArgs(NULL, 1); + CPrep_TokenStreamGetState(&streamstate); + if (lex() == TK_COLON_COLON) { + ttempldep = newtype2; + continue; + } else { + CPrep_TokenStreamSetState(&streamstate); + result->x8 = (Type *) newtype2; + return 1; + } + } else if (token == TK_IDENTIFIER) { + newtype = CDecl_NewTemplDepType(TEMPLDEP_QUALNAME); + newtype->u.qual.type = ttempldep; + newtype->u.qual.name = tkidentifier; + tk = token; + + CPrep_TokenStreamGetState(&streamstate); + token2 = lex(); + tkidentifier = newtype->u.qual.name; + if (token2 == TK_COLON_COLON) { + ttempldep = newtype; + continue; + } + + if ((token2 == '<') && !flag2) { + tk = token2; + newtype2 = newtype; + newtype = CDecl_NewTemplDepType(TEMPLDEP_QUALTEMPL); + newtype->u.qualtempl.type = newtype2; + newtype->u.qualtempl.args = CTempl_ParseUncheckTemplArgs(NULL, 1); + + CPrep_TokenStreamGetState(&streamstate); + if (lex() == TK_COLON_COLON) { + ttempldep = newtype; + continue; + } + } + + CPrep_TokenStreamSetState(&streamstate); + result->x8 = (Type *) newtype; + return 1; + } else { + CPrep_TokenStreamSetState(&streamstate); + result->x8 = (Type *) ttempldep; + return 1; + } + } while (1); +} + +static Boolean CScope_CheckDtorName(TypeClass *tclass, Boolean *flag) { + if ((tk = lex()) != TK_IDENTIFIER) + CError_Error(107); + + if (tclass) { + *flag = 0; + if ((tclass->classname == tkidentifier) || (CScope_GetType(tclass->nspace, tkidentifier, NULL) == (Type *) tclass) || (CScope_GetType(cscope_current, tkidentifier, NULL) == (Type *) tclass)) { + if (!CClass_Destructor(tclass)) + *flag = 1; + if ((tclass->flags & CLASS_FLAGS_800) && (lookahead() == '<')) { + tk = lex(); + if (!CTemplTool_EqualArgs(TEMPL_CLASS_INST(tclass)->inst_args, CTempl_ParseUncheckTemplArgs(NULL, 0))) + CError_Error(374); + } + return 1; + } + } + + CError_Error(141); + return 0; +} + +static Boolean CScope_ParseQualifiedName(CScopeParseResult *result, NameSpace *nspace) { + NameSpaceObjectList *list; + HashNameNode *saveidentifier; + TypeClass *tclass; + Boolean flag = 0; + + do { + switch (tk) { + case TK_TEMPLATE: + if ((tk = lex()) != TK_IDENTIFIER) { + CError_Error(107); + return 0; + } + case TK_IDENTIFIER: + saveidentifier = tkidentifier; + if (lookahead() == TK_COLON_COLON) { + tk = lex(); + nspace = CScope_FindQualifiedNameSpace(result, nspace, saveidentifier); + if (!nspace) + return 0; + result->x1D = 1; + tk = lex(); + continue; + } + break; + case TK_OPERATOR: + if (!CParser_ParseOperatorName(NULL, 1, 1)) + return 0; + CPrep_UnLex(); + saveidentifier = tkidentifier; + break; + case '~': + if (!CScope_CheckDtorName(nspace->theclass, &flag)) + return 0; + saveidentifier = destructor_name_node; + flag = 1; + break; + default: + CError_Error(107); + return 0; + } + + if (!(list = CScope_FindQualifiedName(result, nspace, saveidentifier, &result->nspace_0)) || !CScope_SetupParseNameResult(result, list, saveidentifier)) { + if (flag) { + result->x1C = 1; + return 1; + } + if (nspace->theclass && !(nspace->theclass->flags & CLASS_FLAGS_2)) + CError_Error(136, nspace->theclass, 0); + else + CError_Error(140, saveidentifier->name); + return 0; + } + + if (result->x8 && (result->x8->type == TYPECLASS) && (lookahead() == '<')) { + tclass = TYPE_CLASS(result->x8); + if (tclass->flags & CLASS_FLAGS_800) + tclass = TYPE_CLASS(TEMPL_CLASS_INST(tclass)->templ); + else if (!(tclass->flags & CLASS_FLAGS_100)) + return 1; + + tk = lex(); + result->x8 = CTempl_ClassGetType(tclass); + if ((result->x8->type == TYPECLASS) && (lookahead() == TK_COLON_COLON)) { + lex(); + tk = lex(); + result->x1D = 1; + nspace = TYPE_CLASS(result->x8)->nspace; + result->x8 = NULL; + result->obj_10 = NULL; + continue; + } + } + + return 1; + } while (1); +} + +Boolean CScope_ParseExprName(CScopeParseResult *result) { + CScopeNSIterator iterator; + HashNameNode *name; + NameSpaceObjectList *list; + Boolean flag; + + if (!copts.cplusplus) { + memclrw(result, sizeof(CScopeParseResult)); + if (tk != TK_IDENTIFIER) { + CError_Error(107); + return 0; + } + + name = tkidentifier; + CScope_NSIteratorInit(&iterator, cscope_current, result); + do { + if ((list = CScope_NSIteratorFind(&iterator, name)) && (list->object->otype != OT_TYPETAG)) { + result->nspace_0 = iterator.lookup ? iterator.lookup->nspace : iterator.nspace; + return CScope_SetupParseNameResult(result, list, name); + } + } while (CScope_NSIteratorNext(&iterator)); + + result->nspace_0 = cscope_current; + result->name_4 = name; + return 1; + } else { + if ((tk == TK_COLON_COLON || tk == TK_IDENTIFIER) && CScope_ParseQualifiedNameSpace(result, 1, 1)) { + if (result->x8) + return 1; +#line 2313 + CError_ASSERT(result->nspace_0); + } else { + memclrw(result, sizeof(CScopeParseResult)); + result->nspace_0 = cscope_current; + } + + switch (tk) { + case TK_TEMPLATE: + if (!result->x1D) + CError_Error(373); + + if ((tk = lex()) != TK_IDENTIFIER) { + CError_Error(107); + return 0; + } + case TK_IDENTIFIER: + name = tkidentifier; + break; + case TK_OPERATOR: + if (!CParser_ParseOperatorName(NULL, 1, 1)) + return 0; + name = tkidentifier; + CPrep_UnLex(); + break; + case '~': + if (!CScope_CheckDtorName(result->nspace_0->theclass, &flag)) + return 0; + if (flag) { + result->x1C = 1; + return 1; + } + name = destructor_name_node; + break; + default: + CError_Error(107); + return 0; + } + + if (result->x1D) { + if (!(list = CScope_FindQualifiedName(result, result->nspace_0, name, &result->nspace_0))) { + CError_Error(140, CError_GetNameString(result->nspace_0, name)); + return 0; + } else { + return CScope_SetupParseNameResult(result, list, name); + } + } + + CScope_NSIteratorInit(&iterator, result->nspace_0, result); + do { + if ((list = CScope_NSIteratorFind(&iterator, name))) { + result->nspace_0 = iterator.lookup ? iterator.lookup->nspace : iterator.nspace; + return CScope_SetupParseNameResult(result, list, name); + } + } while (CScope_NSIteratorNext(&iterator)); + + if (result->x1D) { + CError_Error(140, name->name); + return 0; + } else { + result->nspace_0 = cscope_current; + result->name_4 = name; + return 1; + } + } +} + +Boolean CScope_ParseDeclName(CScopeParseResult *result) { + CScopeNSIterator iterator; + HashNameNode *name; + NameSpaceObjectList *list; + NameSpace *nspace; + Boolean flag; + CScopeSave save; + short op; + + if (!copts.cplusplus) { + non_cpp_mode: + if (tk != TK_IDENTIFIER) { + CError_Error(107); + return 0; + } + memclrw(result, sizeof(CScopeParseResult)); + + name = tkidentifier; + CScope_NSIteratorInit(&iterator, cscope_current, result); + do { + if ((list = CScope_NSIteratorFind(&iterator, name)) && (copts.cplusplus || (list->object->otype != OT_TYPETAG))) { + result->nspace_0 = iterator.lookup ? iterator.lookup->nspace : iterator.nspace; + return CScope_SetupParseNameResult(result, list, name); + } + } while (CScope_NSIteratorNext(&iterator)); + + result->nspace_0 = cscope_current; + result->name_4 = name; + return 0; + } else { + if ((tk != TK_COLON_COLON) && (tk != TK_IDENTIFIER)) { + CError_Error(107); + return 0; + } + + if (!CScope_ParseQualifiedNameSpace(result, 0, 0)) + goto non_cpp_mode; + + if (result->x8) + return 1; + + nspace = result->nspace_0; +#line 2435 + CError_ASSERT(nspace); + + switch (tk) { + case TK_OPERATOR: + CScope_SetNameSpaceScope(nspace, &save); + if (!CParser_ParseOperatorName(&op, 1, 1)) { + CScope_RestoreScope(&save); + return 0; + } + CScope_RestoreScope(&save); + if (op) + CError_Error(121); + result->x21 = 1; + return 1; + case TK_IDENTIFIER: + name = tkidentifier; + if (nspace->theclass && nspace->theclass->classname == tkidentifier) + name = constructor_name_node; + break; + case '~': + if (!nspace->theclass) { + CError_Error(121); + return 0; + } + tk = lex(); + if (tk != TK_IDENTIFIER) { + CError_Error(107); + return 0; + } + if (nspace->theclass->classname != tkidentifier) + CError_Error(121); + name = destructor_name_node; + break; + default: + CError_Error(107); + return 0; + } + + if (result->x1D) { + if (!(list = CScope_FindQualifiedName(result, result->nspace_0, name, &result->nspace_0))) { + CError_Error(140, name->name); + return 0; + } else { + return CScope_SetupParseNameResult(result, list, name); + } + } + + CScope_NSIteratorInit(&iterator, nspace, result); + do { + if ((list = CScope_NSIteratorFind(&iterator, name))) { + result->nspace_0 = iterator.lookup ? iterator.lookup->nspace : iterator.nspace; + return CScope_SetupParseNameResult(result, list, name); + } + } while (CScope_NSIteratorNext(&iterator)); + + CError_Error(140, name->name); + return 0; + } +} + +Boolean CScope_ParseQualifiedNameSpace(CScopeParseResult *result, Boolean flag1, Boolean flag2) { + // mostly matches, some registers are awkwardly swapped + HashNameNode *name; // r25 + NameSpace *nspace; // r24 + short t; // r23 + Type *type; // r28? + Type *type2; // r21? + NameSpaceObjectList *list; // r21 + CScopeNSIterator iterator; + + memclrw(result, sizeof(CScopeParseResult)); + nspace = NULL; + if (tk == TK_COLON_COLON) { + result->nspace_0 = nspace = cscope_root; + result->x1D = 1; + tk = lex(); + } + + restart: + if (tk != TK_IDENTIFIER) { + if (tk != TK_TEMPLATE) + return nspace != NULL; + if (!result->x1D) + CError_Error(373); + if ((tk = lex()) != TK_IDENTIFIER) { + CError_Error(107); + return 0; + } + } + + name = tkidentifier; + t = lookahead(); + tkidentifier = name; + + if (t != TK_COLON_COLON && t != '<') + return nspace != NULL; + + CScope_NSIteratorInit(&iterator, nspace ? nspace : cscope_current, result); + // r28 = r23 ??? + do { + // list = r21 + for (list = CScope_NSIteratorFind(&iterator, name); list; list = list->next) { + if (list->object->otype == OT_NAMESPACE) { +#line 2565 + CError_ASSERT(!nspace || !nspace->theclass); + + result->nspace_0 = nspace = OBJ_NAMESPACE(list->object)->nspace; + if ((tk = lex()) != TK_COLON_COLON) { + CError_Error(321); + return 0; + } + + result->x1D = 1; + tk = lex(); + goto restart; + } + if (list->object->otype == OT_TYPETAG) { + type = OBJ_TYPE_TAG(list->object)->type; + if (type->type != TYPECLASS) { + if (t == '<') { + result->x8 = type; + return 1; + } else { + CError_Error(121); + return 0; + } + } + parse_thing: + if (t == '<') { + if (TYPE_CLASS(type)->flags & CLASS_FLAGS_800) { + type = (Type *) TEMPL_CLASS_INST(type)->templ; + } else if (!(TYPE_CLASS(type)->flags & CLASS_FLAGS_100)) { + result->x8 = type; + return 1; + } + } + if ((tk = lex()) == '<') { +#line 2609 + CError_ASSERT(TYPE_CLASS(type)->flags & CLASS_FLAGS_100); + type2 = CTempl_ClassGetType(TYPE_CLASS(type)); + if (type2->type == TYPETEMPLATE) { + if (lookahead() != TK_COLON_COLON) { + result->x8 = type2; + return 1; + } + return CScope_DependentTemplateMember(result, TYPE_TEMPLATE(type2), flag1, flag2); + } else if (type2->type != TYPECLASS) { + return 0; + } + + result->nspace_0 = nspace = TYPE_CLASS(type2)->nspace; + if (lookahead() != TK_COLON_COLON) { + result->x8 = type2; + return 1; + } + tk = lex(); + CDecl_CompleteType(type2); + } else { +#line 2632 + CError_ASSERT(tk == TK_COLON_COLON); + if (!(TYPE_CLASS(type)->flags & CLASS_FLAGS_100) || CParser_CheckTemplateClassUsage(TEMPL_CLASS(type), 1)) + result->nspace_0 = nspace = TYPE_CLASS(type)->nspace; + CDecl_CompleteType(type); + } + + result->x1D = 1; + tk = lex(); + goto restart; + } + if (list->object->otype == OT_TYPE) { + type2 = OBJ_TYPE(list->object)->type; + if (type2->type != TYPECLASS) { + if (type2->type == TYPETEMPLATE) { + if (TYPE_TEMPLATE(type2)->dtype == TEMPLDEP_ARGUMENT && TYPE_TEMPLATE(type2)->u.pid.type == TPT_TEMPLATE) { + type2 = CTempl_ParseTemplTemplParam(type2); + if ((type2->type != TYPETEMPLATE) || ((t = lookahead()) != TK_COLON_COLON)) { + result->x8 = type2; + return 1; + } + } + if (t == TK_COLON_COLON) + return CScope_DependentTemplateMember(result, TYPE_TEMPLATE(type2), flag1, flag2); + } + if (t == '<') { + result->x8 = type2; + return 1; + } else { + CError_Error(121); + return 0; + } + } else { + if ((t == '<') && (TYPE_CLASS(type2)->flags & CLASS_FLAGS_100)) { + type = type2; + goto parse_thing; + } + if ((tk = lex()) == '<') { + result->x8 = type2; + return 1; + } +#line 2686 + CError_ASSERT(tk == TK_COLON_COLON); + if (!type2->size) + CDecl_CompleteType(type2); + result->nspace_0 = nspace = TYPE_CLASS(type2)->nspace; + result->x1D = 1; + tk = lex(); + goto restart; + } + } + if (t == '<') + return nspace != NULL; + } + } while (CScope_NSIteratorNext(&iterator)); + + CError_Error(140, name->name); + return 0; +} + +Boolean CScope_ParseElaborateName(CScopeParseResult *result) { + CScopeNSIterator iterator; + HashNameNode *name; + NameSpaceObjectList *list; + Boolean flag; + + if (!copts.cplusplus) { + memclrw(result, sizeof(CScopeParseResult)); + if (tk != TK_IDENTIFIER) { + CError_Error(107); + return 0; + } + + name = tkidentifier; + CScope_NSIteratorInit(&iterator, cscope_current, result); + do { + for (list = CScope_NSIteratorFind(&iterator, name); list; list = list->next) { + if (list->object->otype == OT_TYPETAG) { + result->nspace_0 = iterator.lookup ? iterator.lookup->nspace : iterator.nspace; + return CScope_SetupParseNameResult(result, list, name); + } + } + } while (CScope_NSIteratorNext(&iterator)); + + result->name_4 = name; + return 1; + } else { + if ((tk != TK_COLON_COLON) && (tk != TK_IDENTIFIER)) { + CError_Error(107); + return 0; + } + + if (!CScope_ParseQualifiedNameSpace(result, 0, 0)) { + result->nspace_0 = cscope_current; + if (tk != TK_IDENTIFIER) { + CError_Error(107); + return 0; + } + name = tkidentifier; + } else { + if (result->x8) + return 1; +#line 2760 + CError_ASSERT(result->nspace_0); + + if (tk != TK_IDENTIFIER) { + CError_Error(107); + return 0; + } + name = tkidentifier; + + if (result->x1D) { + if (result->nspace_0->theclass) + return CScope_FindClassMember(result, result->nspace_0, name, 1) != 0; + else + return CScope_FindQualifiedTag(result, result->nspace_0, name); + } + } + + CScope_NSIteratorInit(&iterator, result->nspace_0, result); + do { + for (list = CScope_NSIteratorFind(&iterator, name); list; list = list->next) { + if (list->object->otype == OT_TYPETAG || list->object->otype == OT_TYPE) { + result->nspace_0 = iterator.lookup ? iterator.lookup->nspace : iterator.nspace; + return CScope_SetupParseNameResult(result, list, name); + } + } + } while (CScope_NSIteratorNext(&iterator)); + + result->name_4 = name; + return 1; + } +} + +Boolean CScope_FindObject(NameSpace *nspace, CScopeParseResult *result, HashNameNode *name) { + CScopeNSIterator iterator; + NameSpaceObjectList *list; + + memclrw(result, sizeof(CScopeParseResult)); + CScope_NSIteratorInit(&iterator, nspace, result); + do { + for (list = CScope_NSIteratorFind(&iterator, name); list; list = list->next) { + if (copts.cplusplus || list->object->otype != OT_TYPETAG) { + result->nspace_0 = iterator.lookup ? iterator.lookup->nspace : iterator.nspace; + return CScope_SetupParseNameResult(result, list, name); + } + } + } while (CScope_NSIteratorNext(&iterator)); + + return 0; +} + +Boolean CScope_FindNonClassObject(NameSpace *nspace, CScopeParseResult *result, HashNameNode *name) { + CScopeNSIterator iterator; + NameSpaceObjectList *list; + + memclrw(result, sizeof(CScopeParseResult)); + CScope_NSIteratorInit(&iterator, nspace, result); + do { + for (list = CScope_NSIteratorNonClassFind(&iterator, name); list; list = list->next) { + if (copts.cplusplus || list->object->otype != OT_TYPETAG) { + result->nspace_0 = iterator.lookup ? iterator.lookup->nspace : iterator.nspace; + return CScope_SetupParseNameResult(result, list, name); + } + } + } while (CScope_NSIteratorNext(&iterator)); + + return 0; +} + +NameSpaceObjectList *CScope_FindObjectList(CScopeParseResult *result, HashNameNode *name) { + CScopeNSIterator iterator; + NameSpaceObjectList *list; + + memclrw(result, sizeof(CScopeParseResult)); + CScope_NSIteratorInit(&iterator, cscope_current, result); + do { + for (list = CScope_NSIteratorFind(&iterator, name); list; list = list->next) { + if (copts.cplusplus || list->object->otype != OT_TYPETAG) { + result->nspace_0 = iterator.lookup ? iterator.lookup->nspace : iterator.nspace; + return list; + } + } + } while (CScope_NSIteratorNext(&iterator)); + + return 0; +} + +Boolean CScope_PossibleTypeName(HashNameNode *name) { + CScopeParseResult result; + CScopeNSIterator iterator; + NameSpaceObjectList *list; + + memclrw(&result, sizeof(CScopeParseResult)); + CScope_NSIteratorInit(&iterator, cscope_current, &result); + do { + if ((list = CScope_NSIteratorFind(&iterator, name))) { + switch (list->object->otype) { + case OT_TYPE: + case OT_NAMESPACE: + return 1; + case OT_TYPETAG: + if (copts.cplusplus) + return 1; + break; + default: + return 0; + } + } + } while (CScope_NSIteratorNext(&iterator)); + + return 0; +} + +Boolean CScope_FindClassMemberObject(TypeClass *tclass, CScopeParseResult *result, HashNameNode *name) { + NameSpaceObjectList *list; + + memclrw(result, sizeof(CScopeParseResult)); + + if (CScope_FindClassMember(result, tclass->nspace, name, 0)) { + list = result->nsol_14; + result->nsol_14 = NULL; + if (list && list->object->otype == OT_OBJECT) + return CScope_SetupParseNameResult(result, list, name); + } + + return 0; +} + +void CScope_InitObjectIterator(CScopeObjectIterator *iterator, NameSpace *nspace) { + memclrw(iterator, sizeof(CScopeObjectIterator)); + iterator->nspace = nspace; + if (!iterator->nspace->is_hash) + iterator->nextname = nspace->data.list; + else + iterator->nextname = nspace->data.hash[0]; +} + +ObjBase *CScope_NextObjectIteratorObject(CScopeObjectIterator *iterator) { + ObjBase *obj; + + do { + if (iterator->currlist) { + do { + obj = iterator->currlist->object; + if (obj->otype == OT_OBJECT) { + iterator->currlist = iterator->currlist->next; + return obj; + } + } while ((iterator->currlist = iterator->currlist->next)); + } + + if (iterator->nextname) { + iterator->currlist = &iterator->nextname->first; + iterator->nextname = iterator->nextname->next; + } else { + if (!iterator->nspace->is_hash || ++iterator->hashindex >= 1024) + return NULL; + iterator->nextname = iterator->nspace->data.hash[iterator->hashindex]; + } + } while (1); +} + +NameSpaceObjectList *CScope_NextObjectIteratorObjectList(CScopeObjectIterator *iterator) { + NameSpaceName *nsname; + + do { + if ((nsname = iterator->nextname)) { + iterator->nextname = nsname->next; + return &nsname->first; + } else { + if (!iterator->nspace->is_hash || ++iterator->hashindex >= 1024) + return NULL; + iterator->nextname = iterator->nspace->data.hash[iterator->hashindex]; + } + } while (1); +} + +void CScope_DefineTypeTag(NameSpace *nspace, HashNameNode *name, Type *type) { + ObjTypeTag *ott; + + ott = galloc(sizeof(ObjTypeTag)); + memclrw(ott, sizeof(ObjTypeTag)); + ott->otype = OT_TYPETAG; + ott->access = nspace->theclass ? global_access : ACCESSPUBLIC; + ott->type = type; + CScope_AddObject(nspace, name, OBJ_BASE(ott)); +} + +Type *CScope_GetLocalTagType(NameSpace *nspace, HashNameNode *name) { + NameSpaceObjectList *list; + + for (list = CScope_FindQualName(nspace, name); list; list = list->next) { + if (list->object->otype == OT_TYPETAG) + return OBJ_TYPE_TAG(list->object)->type; + } + + return NULL; +} + +Boolean CScope_FindTypeName(NameSpace *nspace, HashNameNode *name, CScopeParseResult *result) { + CScopeNSIterator iterator; + NameSpaceObjectList *list; + NameSpaceObjectList *scan; + + memclrw(result, sizeof(CScopeParseResult)); + CScope_NSIteratorInit(&iterator, nspace, result); + + do { + list = CScope_NSIteratorFind(&iterator, name); + for (scan = list; scan; scan = scan->next) { + switch (scan->object->otype) { + case OT_NAMESPACE: + result->nspace_0 = OBJ_NAMESPACE(scan->object)->nspace; + return 1; + case OT_TYPE: + case OT_TYPETAG: + return CScope_SetupParseNameResult(result, scan, name); + default: + return 0; + } + } + } while (CScope_NSIteratorNext(&iterator)); + + return 0; +} + +static NameSpaceObjectList *CScope_GetLocalObjects(NameSpaceObjectList *objs) { + NameSpaceObjectList *list; + NameSpaceObjectList **ptr; + + list = objs; + while (list) { + if (list->object->otype == OT_OBJECT && OBJECT(list->object)->datatype == DALIAS) { + list = CScope_CopyNameSpaceObjectList(objs); + ptr = &list; + while (*ptr) { + if ((*ptr)->object->otype == OT_OBJECT && OBJECT((*ptr)->object)->datatype == DALIAS) + *ptr = (*ptr)->next; + else + ptr = &(*ptr)->next; + } + return list; + } else { + list = list->next; + } + } + + return objs; +} + +NameSpaceObjectList *CScope_GetLocalObject(NameSpace *nspace, HashNameNode *name) { + NameSpaceObjectList *list; + + if ((list = CScope_FindQualName(nspace, name))) { + switch (list->object->otype) { + case OT_OBJECT: + return CScope_GetLocalObjects(list); + default: + CError_Error(122, name->name); + return NULL; + case OT_TYPETAG: + break; + } + } + + return NULL; +} + +static BClassList *CScope_GetBaseAccessPathEnd(BClassList *list) { + BClassList *best = list; + ClassList *scan; + + do { + if (!list->next) + return best; + + for (scan = TYPE_CLASS(list->type)->bases; scan; scan = scan->next) { + if (TYPE_CLASS(list->next->type) == scan->base) + break; + } + + if (!scan) + best = list->next; + list = list->next; + } while (1); +} + +BClassList *CScope_GetClassAccessPath(BClassList *list, TypeClass *tclass) { + BClassList *scan; + BClassList *list2; + + if (!list) + return NULL; + + list = CScope_GetBaseAccessPathEnd(list); + for (scan = list; scan; scan = scan->next) { + if (scan->type == (Type *) tclass) + return scan; + } + + if ((list2 = CScope_GetAccessPath(tclass, TYPE_CLASS(list->type)))) { + for (scan = list2; scan; scan = scan->next) { + if (scan->type == list->type) { + scan->next = list->next; + return list2; + } + } +#line 3217 + CError_FATAL(); + } + + return NULL; +} + +static Boolean CScope_FixMemberResult(TypeClass *tclass, CScopeParseResult *result) { + if (!(result->bcl_18 = CScope_GetClassAccessPath(result->bcl_18, tclass))) { + if (result->name_4) + CError_Error(150, result->name_4->name); + else + CError_Error(328); + return 0; + } else { + return 1; + } +} + +Boolean CScope_ParseMemberName(TypeClass *tclass, CScopeParseResult *result, Boolean flag) { + HashNameNode *name; + NameSpaceObjectList *list; + short t; + Boolean dtorflag; + + if (tk == TK_COLON_COLON) { + restart: + if (!CScope_ParseExprName(result)) + return 0; + + if (result->x8 && result->x8->type == TYPETEMPLATE && TYPE_TEMPLATE(result->x8)->dtype == TEMPLDEP_QUALNAME) { + if (flag) + return 1; + CError_Error(340, TYPE_TEMPLATE(result->x8)->u.qual.name->name); + result->x8 = NULL; + return 0; + } + + if (result->x1C) + return 1; + else + return CScope_FixMemberResult(tclass, result); + } + + if (tk == TK_IDENTIFIER) { + name = tkidentifier; + t = lookahead(); + tkidentifier = name; + switch (t) { + case TK_COLON_COLON: + memclrw(result, sizeof(CScopeParseResult)); + if (!CScope_FindClassMember(result, tclass->nspace, name, 2)) + goto restart; + break; + case '<': + if (flag) + goto restart; + break; + } + } else if (tk == '~') { + memclrw(result, sizeof(CScopeParseResult)); + if (CScope_CheckDtorName(tclass, &dtorflag)) { + if (dtorflag) { + result->x1C = 1; + return 1; + } + + if (!(list = CScope_FindQualifiedName(result, tclass->nspace, destructor_name_node, &result->nspace_0))) { + CError_Error(140, CError_GetNameString(result->nspace_0, destructor_name_node)); + return 0; + } else { + return CScope_SetupParseNameResult(result, list, destructor_name_node); + } + } + return 0; + } + + memclrw(result, sizeof(CScopeParseResult)); + return CScope_ParseQualifiedName(result, tclass->nspace); +} + +static void CScope_AddUsingObject(BClassList *bcl, NameSpace *nspace, ObjBase *obj, HashNameNode *name, AccessType access) { + NameSpaceObjectList *list; + BClassList *pathcopy; + TypeClass *tclass; + ObjBase *copy; + Object *objscan; + + if (bcl) { + if (!nspace->theclass) + CError_Error(200); + else + CClass_CheckPathAccess(bcl, NULL, obj->access); + } + + if (obj->otype == OT_TYPE) { + if (!nspace->theclass) { + if ((list = CScope_FindQualName(nspace, name)) && (list->object->otype == OT_TYPE) && + (OBJ_TYPE(obj)->type == OBJ_TYPE(list->object)->type) && + (OBJ_TYPE(obj)->unk6 == OBJ_TYPE(list->object)->unk6)) + return; + } + copy = galloc(sizeof(ObjType)); + *OBJ_TYPE(copy) = *OBJ_TYPE(obj); + copy->access = access; + CScope_AddObject(nspace, name, copy); + } else if (obj->otype == OT_TYPETAG) { + if (!nspace->theclass) { + if ((list = CScope_FindQualName(nspace, name)) && (list->object->otype == OT_TYPETAG) && + (OBJ_TYPE_TAG(obj)->type == OBJ_TYPE_TAG(list->object)->type)) + return; + } + copy = galloc(sizeof(ObjTypeTag)); + *OBJ_TYPE_TAG(copy) = *OBJ_TYPE_TAG(obj); + copy->access = access; + CScope_AddObject(nspace, name, copy); + } else if (obj->otype == OT_ENUMCONST) { + copy = galloc(sizeof(ObjEnumConst)); + *OBJ_ENUM_CONST(copy) = *OBJ_ENUM_CONST(obj); + copy->access = access; + CScope_AddObject(nspace, OBJ_ENUM_CONST(copy)->name, copy); + } else if (obj->otype == OT_MEMBERVAR) { + if (nspace->theclass) { + copy = galloc(sizeof(ObjMemberVarPath)); + *OBJ_MEMBER_VAR(copy) = *OBJ_MEMBER_VAR(obj); + copy->access = access; + pathcopy = CScope_GetClassAccessPath(CClass_GetPathCopy(bcl, 1), nspace->theclass); + if (pathcopy && pathcopy->type == (Type *) nspace->theclass) { + OBJ_MEMBER_VAR_PATH(copy)->has_path = 1; + OBJ_MEMBER_VAR_PATH(copy)->path = pathcopy; + } else { + CError_Error(221); + } + CScope_AddObject(nspace, OBJ_MEMBER_VAR(copy)->name, copy); + } else { + CError_Error(221); + } + } else if (obj->otype == OT_OBJECT) { + if (!nspace->theclass) { + for (list = CScope_FindQualName(nspace, OBJECT(obj)->name); list; list = list->next) { + if (list->object->otype == OT_OBJECT) { + objscan = OBJECT(list->object); + while (objscan->datatype == DALIAS) + objscan = objscan->u.alias.object; + if (OBJECT(obj) == objscan) + return; + } + } + } + + copy = galloc(sizeof(Object)); + *OBJECT(copy) = *OBJECT(obj); + copy->access = access; + OBJECT(copy)->datatype = DALIAS; + OBJECT(copy)->u.alias.object = OBJECT(obj); + OBJECT(copy)->u.alias.member = NULL; + OBJECT(copy)->u.alias.offset = 0; + + if (OBJECT(copy)->type->type == TYPEFUNC && (TYPE_FUNC(OBJECT(copy)->type)->flags & FUNC_FLAGS_METHOD) && !TYPE_METHOD(OBJECT(copy)->type)->x26) { + if (!(tclass = nspace->theclass) || !(OBJECT(copy)->u.alias.member = CScope_GetClassAccessPath( + CClass_GetPathCopy(bcl, 1), tclass)) || (OBJECT(copy)->u.alias.member->type != (Type *) nspace->theclass)) { + CError_Error(221); + OBJECT(copy)->u.alias.member = NULL; + } + } + + CScope_AddObject(nspace, OBJECT(copy)->name, copy); + } else { + CError_Error(200); + } +} + +void CScope_AddClassUsingDeclaration(TypeClass *tclass, TypeClass *tclass2, HashNameNode *name, AccessType access) { + CScopeParseResult result; + NameSpaceObjectList *scan; + + memclrw(&result, sizeof(CScopeParseResult)); + if (!CScope_FindClassMember(&result, tclass2->nspace, name, 0) || !CScope_FixMemberResult(tclass, &result)) { + CError_Error(340, name->name); + return; + } + + if (result.nsol_14) { + for (scan = result.nsol_14; scan; scan = scan->next) { + switch (scan->object->otype) { + case OT_ENUMCONST: + case OT_MEMBERVAR: + case OT_OBJECT: + CScope_AddUsingObject(result.bcl_18, tclass->nspace, scan->object, result.name_4, access); + break; + } + } + } else { + if (result.obj_10) + CScope_AddUsingObject(result.bcl_18, tclass->nspace, result.obj_10, result.name_4, access); + else + CError_Error(340, name->name); + } +} + +void CScope_ParseUsingDeclaration(NameSpace *nspace, AccessType access) { + // almost matches, slight bit of register weirdness + CScopeParseResult result; + + if (nspace->theclass) { + Boolean flag_r27 = (TYPE_CLASS(nspace->theclass)->flags & CLASS_FLAGS_100) ? 1 : 0; + Boolean flag_r26 = 0; + if (tk == TK_TYPENAME) { + if (!flag_r27) + CError_Error(200); + flag_r26 = 1; + tk = lex(); + } + + if (!CScope_ParseMemberName(nspace->theclass, &result, flag_r27)) { + CError_Error(200); + return; + } + + if (result.x8 && result.x8->type == TYPETEMPLATE && TYPE_TEMPLATE(result.x8)->dtype == TEMPLDEP_QUALNAME) { +#line 3578 + CError_ASSERT(flag_r27); + + if (flag_r26) { + ObjType *objtype = galloc(sizeof(ObjType)); + memclrw(objtype, sizeof(ObjType)); + objtype->otype = OT_TYPE; + objtype->access = access; + objtype->type = result.x8; + CScope_AddObject(nspace, TYPE_TEMPLATE(result.x8)->u.qual.name, OBJ_BASE(objtype)); + } else { + CTemplClass_RegisterUsingDecl(TEMPL_CLASS(nspace->theclass), result.x8, access); + } + + if ((tk = lex()) != ';') + CError_Error(123); + return; + } + + if (!result.x1D) { + CError_Error(200); + return; + } + } else { + NameSpace *savenspace = cscope_current; + cscope_current = nspace; + if (!CScope_ParseExprName(&result) || !result.x1D) { + cscope_current = savenspace; + CError_Error(200); + return; + } else { + cscope_current = savenspace; + } + } + + if (result.nsol_14) { + NameSpaceObjectList *scan; + for (scan = result.nsol_14; scan; scan = scan->next) { + if (scan->object->otype == OT_OBJECT) + CScope_AddUsingObject(result.bcl_18, nspace, scan->object, result.name_4, access); + } + } else { + if (result.obj_10) + CScope_AddUsingObject(result.bcl_18, nspace, result.obj_10, result.name_4, access); + else + CError_Error(200); + } + + if ((tk = lex()) != ';') + CError_Error(123); +} + +static NameSpace *CScope_ParseQualifiedNamespaceSpecifier(NameSpace *nspace) { + CScopeParseResult result; + CScopeNSIterator iterator; + NameSpaceObjectList *list; + + memclrw(&result, sizeof(CScopeParseResult)); + if (tk == TK_COLON_COLON) { + nspace = cscope_root; + result.x1D = 1; + tk = lex(); + } + + do { + if (tk != TK_IDENTIFIER) { + CError_Error(107); + break; + } + + CScope_NSIteratorInit(&iterator, nspace, &result); + do { + if ((list = CScope_NSIteratorFind(&iterator, tkidentifier)) && list->object->otype == OT_NAMESPACE) { + nspace = OBJ_NAMESPACE(list->object)->nspace; + goto some_goto; + } + } while (CScope_NSIteratorNext(&iterator)); + CError_Error(140, tkidentifier->name); + some_goto: + if ((tk = lex()) != TK_COLON_COLON) + break; + result.x1D = 1; + tk = lex(); + } while (1); + + return nspace; +} + +void CScope_ParseNameSpaceAlias(HashNameNode *name) { + NameSpaceObjectList *list; + ObjNameSpace *objns; + + list = CScope_FindQualName(cscope_current, name); + if (!list) { + tk = lex(); + objns = galloc(sizeof(ObjNameSpace)); + memclrw(objns, sizeof(ObjNameSpace)); + objns->otype = OT_NAMESPACE; + objns->access = ACCESSPUBLIC; + objns->nspace = CScope_ParseQualifiedNamespaceSpecifier(cscope_current); + CScope_AddObject(cscope_current, name, OBJ_BASE(objns)); + } else if (list->object->otype != OT_NAMESPACE) { + CError_Error(320); + tk = lex(); + CScope_ParseQualifiedNamespaceSpecifier(cscope_current); + } else { + tk = lex(); + if (CScope_ParseQualifiedNamespaceSpecifier(cscope_current) != OBJ_NAMESPACE(list->object)->nspace) + CError_Error(122, name->name); + } + + if (tk != ';') + CError_Error(123); +} + +void CScope_ParseUsingDirective(NameSpace *nspace) { + NameSpace *target; + NameSpaceList *list; + + target = CScope_ParseQualifiedNamespaceSpecifier(nspace); + if (target != nspace) { + for (list = nspace->usings; list; list = list->next) { + if (list->nspace == target) + break; + } + if (!list) { + list = galloc(sizeof(NameSpaceList)); + list->next = nspace->usings; + list->nspace = target; + nspace->usings = list; + } + } else { + CError_Error(321); + } + + if (tk != ';') + CError_Error(123); +} diff --git a/compiler_and_linker/FrontEnd/Common/CompilerTools.c b/compiler_and_linker/FrontEnd/Common/CompilerTools.c new file mode 100644 index 0000000..3eae51d --- /dev/null +++ b/compiler_and_linker/FrontEnd/Common/CompilerTools.c @@ -0,0 +1,1216 @@ +#include "compiler/CompilerTools.h" +#include "cos.h" + +extern Boolean systemHandles; + +UInt32 bit_masks[32] = { + 0, 1, 3, 7, + 0xF, 0x1F, 0x3F, 0x7F, + 0xFF, 0x1FF, 0x3FF, 0x7FF, + 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF, + 0xFFFF, 0x1FFFF, 0x3FFFF, 0x7FFFF, + 0xFFFFF, 0x1FFFFF, 0x3FFFFF, 0x7FFFFF, + 0xFFFFFF, 0x1FFFFFF, 0x3FFFFFF, 0x7FFFFFF, + 0xFFFFFFF, 0x1FFFFFFF, 0x3FFFFFFF, 0x7FFFFFFF +}; + +static short lheaplockcount; +static void (*heaperror)(); +static HeapMem bheap; +static HeapMem oheap; +static HeapMem aheap; +static HeapMem lheap; +static HeapMem gheap; +long hash_name_id; +HashNameNode **name_hash_nodes; +void (*GListErrorProc)(); + +void CompilerGetPString(short index, unsigned char *string) { + COS_GetPString(string, 10100, index); +} + +void CompilerGetCString(short index, char *string) { + COS_GetString(string, 10100, index); +} + +unsigned char *CTool_CtoPstr(char *cstr) { + char *cp = cstr; + int length = 0; + int i; + + while (*cp) { + ++length; + ++cp; + } + + for (i = length; i > 0; i--) { + cp[0] = cp[-1]; + --cp; + } + + cstr[0] = length; + return (unsigned char *) cstr; +} + +static void GListError() { + if (GListErrorProc) + GListErrorProc(); +} + +short InitGList(GList *gl, SInt32 size) { + if ((gl->data = COS_NewOSHandle(size)) == 0) + if ((gl->data = COS_NewHandle(size)) == 0) + return -1; + gl->size = 0; + gl->growsize = size >> 1; + gl->hndlsize = size; + return 0; +} + +void FreeGList(GList *gl) { + if (gl->data != 0) { + COS_FreeHandle(gl->data); + gl->data = 0; + } + gl->hndlsize = 0; + gl->size = 0; +} + +void LockGList(GList *gl) { + COS_LockHandleHi(gl->data); +} + +void UnlockGList(GList *gl) { + COS_UnlockHandle(gl->data); +} + +void ShrinkGList(GList *gl) { + COS_ResizeHandle(gl->data, gl->hndlsize = gl->size); +} + +void AppendGListData(GList *gl, const void *data, SInt32 size) { + if ((gl->size + size) > gl->hndlsize) { + if (!COS_ResizeHandle(gl->data, gl->hndlsize += size + gl->growsize)) + GListError(); + } + + memcpy(*gl->data + gl->size, data, size); + gl->size += size; +} + +void AppendGListNoData(GList *gl, SInt32 size) { + if ((gl->size + size) > gl->hndlsize) { + if (!COS_ResizeHandle(gl->data, gl->hndlsize += size + gl->growsize)) + GListError(); + } + + gl->size += size; +} + +void AppendGListByte(GList *gl, SInt8 thebyte) { + if ((gl->size + 1) > gl->hndlsize) { + if (!COS_ResizeHandle(gl->data, gl->hndlsize += 1 + gl->growsize)) + GListError(); + } + + (*gl->data)[gl->size++] = thebyte; +} + +void AppendGListWord(GList *gl, SInt16 theword) { + char *ptr; + + if ((gl->size + 2) > gl->hndlsize) { + if (!COS_ResizeHandle(gl->data, gl->hndlsize += 2 + gl->growsize)) + GListError(); + } + + ptr = *gl->data + gl->size; + gl->size += 2; + *(ptr++) = ((unsigned char *) &theword)[0]; + *(ptr++) = ((unsigned char *) &theword)[1]; +} + +void AppendGListTargetEndianWord(GList *gl, SInt16 theword) { + char *ptr; + + if ((gl->size + 2) > gl->hndlsize) { + if (!COS_ResizeHandle(gl->data, gl->hndlsize += 2 + gl->growsize)) + GListError(); + } + + ptr = *gl->data + gl->size; + gl->size += 2; + *(ptr++) = ((unsigned char *) &theword)[0]; + *(ptr++) = ((unsigned char *) &theword)[1]; +} + +void AppendGListLong(GList *gl, SInt32 theword) { + char *ptr; + + if ((gl->size + 4) > gl->hndlsize) { + if (!COS_ResizeHandle(gl->data, gl->hndlsize += 4 + gl->growsize)) + GListError(); + } + + ptr = *gl->data + gl->size; + gl->size += 4; + *(ptr++) = ((unsigned char *) &theword)[0]; + *(ptr++) = ((unsigned char *) &theword)[1]; + *(ptr++) = ((unsigned char *) &theword)[2]; + *(ptr++) = ((unsigned char *) &theword)[3]; +} + +void AppendGListTargetEndianLong(GList *gl, SInt32 theword) { + char *ptr; + + if ((gl->size + 4) > gl->hndlsize) { + if (!COS_ResizeHandle(gl->data, gl->hndlsize += 4 + gl->growsize)) + GListError(); + } + + ptr = *gl->data + gl->size; + gl->size += 4; + *(ptr++) = ((unsigned char *) &theword)[0]; + *(ptr++) = ((unsigned char *) &theword)[1]; + *(ptr++) = ((unsigned char *) &theword)[2]; + *(ptr++) = ((unsigned char *) &theword)[3]; +} + +void AppendGListID(GList *gl, const char *name) { + UInt32 n = strlen(name) + 1; + if ((gl->size + n) > gl->hndlsize) { + if (!COS_ResizeHandle(gl->data, gl->hndlsize += n + gl->growsize)) + GListError(); + } + + memcpy(*gl->data + gl->size, name, n); + gl->size += n; +} + +void AppendGListName(GList *gl, const char *name) { + UInt32 n = strlen(name); + if ((gl->size + n) > gl->hndlsize) { + if (!COS_ResizeHandle(gl->data, gl->hndlsize += n + gl->growsize)) + GListError(); + } + + memcpy(*gl->data + gl->size, name, n); + gl->size += n; +} + +void RemoveGListData(GList *gl, SInt32 size) { + gl->size -= size; + if (gl->hndlsize > (gl->size + gl->growsize * 2)) + COS_ResizeHandle(gl->data, gl->hndlsize = gl->size + gl->growsize); +} + +SInt16 GetGListByte(GList *gl) { + return (*gl->data)[gl->size++]; +} + +SInt16 GetGListWord(GList *gl) { + char *ptr; + union { unsigned char bytes[2]; short s; } data; + + // according to stabs, this one just uses a local short called 'n', not a union + ptr = *gl->data + gl->size; + gl->size += 2; + data.bytes[0] = ptr[0]; + data.bytes[1] = ptr[1]; + return data.s; +} + +SInt32 GetGListLong(GList *gl) { + char *ptr; + union { unsigned char bytes[4]; long l; } data; + + // according to stabs, this one just uses a local long called 'n', not a union + ptr = *gl->data + gl->size; + gl->size += 4; + data.bytes[0] = ptr[0]; + data.bytes[1] = ptr[1]; + data.bytes[2] = ptr[2]; + data.bytes[3] = ptr[3]; + return data.l; +} + +short GetGListID(GList *gl, char *name) { + short n; + char *a; + char *b; + + n = 1; + a = *gl->data + gl->size; + b = name; + while (*a) { + *(b++) = *(a++); + n++; + } + + *b = *a; + gl->size += n; + return n; +} + +void GetGListData(GList *gl, char *where, SInt32 size) { + memcpy(where, *gl->data + gl->size, size); + gl->size += size; +} + +static UInt32 hashpjw(const char *p) { + UInt32 h = 0; + UInt32 g; + + while (*p) { + h = (h << 4) + *p; + g = h & 0xF0000000; + if (g) { + h ^= (g >> 24); + h ^= g; + } + p++; + } + + return h % 0xFFFFFD; +} + +static SInt16 PHash(const unsigned char *string) { + SInt16 i; + SInt16 hashval; + UInt8 u; + + if ((hashval = *(string++))) { + i = hashval; + u = 0; + while (i > 0) { + u = (u >> 3) | (u << 5); + u += *(string++); + --i; + } + + hashval = (hashval << 8) | u; + } + + return hashval & 0x7FF; +} + +SInt16 CHash(const char *string) { + SInt16 i; + SInt16 hashval; + UInt8 u; + + if ((hashval = (UInt8) strlen(string))) { + i = hashval; + u = 0; + while (i > 0) { + u = (u >> 3) | (u << 5); + u += *(string++); + --i; + } + hashval = (hashval << 8) | u; + } + + return hashval & 0x7FF; +} + +HashNameNode *GetHashNameNode(const char *name) { + HashNameNode *node; + SInt16 n; + + if ((node = name_hash_nodes[n = CHash(name)]) == NULL) { + node = galloc(strlen(name) + sizeof(HashNameNode)); + name_hash_nodes[n] = node; + node->next = NULL; + node->id = hash_name_id++; + node->hashval = n; + strcpy(node->name, name); + return node; + } else { + for (;;) { + if (strcmp(name, node->name) == 0) { + if (node->id < 0) + node->id = hash_name_id++; + return node; + } + + if (node->next == NULL) { + node->next = galloc(strlen(name) + sizeof(HashNameNode)); + node = node->next; + node->next = NULL; + node->id = hash_name_id++; + node->hashval = n; + strcpy(node->name, name); + return node; + } else { + node = node->next; + } + } + } +} + +HashNameNode *GetHashNameNodeHash(const char *name, SInt16 hashval) { + HashNameNode *node; + + if ((node = name_hash_nodes[hashval]) == NULL) { + node = galloc(strlen(name) + sizeof(HashNameNode)); + name_hash_nodes[hashval] = node; + node->next = NULL; + node->id = hash_name_id++; + node->hashval = hashval; + strcpy(node->name, name); + return node; + } else { + for (;;) { + if (strcmp(name, node->name) == 0) + return node; + + if (node->next == NULL) { + node->next = galloc(strlen(name) + sizeof(HashNameNode)); + node = node->next; + node->next = NULL; + node->id = hash_name_id++; + node->hashval = hashval; + strcpy(node->name, name); + return node; + } else { + node = node->next; + } + } + } +} + +HashNameNode *GetHashNameNodeHash2(const char *name, SInt16 hashval) { + HashNameNode *node; + + if ((node = name_hash_nodes[hashval]) == NULL) { + node = galloc(strlen(name) + sizeof(HashNameNode)); + name_hash_nodes[hashval] = node; + node->next = NULL; + node->id = -1; + node->hashval = hashval; + strcpy(node->name, name); + return node; + } else { + for (;;) { + if (strcmp(name, node->name) == 0) + return node; + + if (node->next == NULL) { + node->next = galloc(strlen(name) + sizeof(HashNameNode)); + node = node->next; + node->next = NULL; + node->id = -1; + node->hashval = hashval; + strcpy(node->name, name); + return node; + } else { + node = node->next; + } + } + } +} + +HashNameNode *GetHashNameNodeExport(const char *name) { + HashNameNode *node; + SInt16 n; + + if ((node = name_hash_nodes[n = CHash(name)]) == NULL) { + node = galloc(strlen(name) + sizeof(HashNameNode)); + name_hash_nodes[n] = node; + node->next = NULL; + node->id = -1; + node->hashval = n; + strcpy(node->name, name); + return node; + } else { + for (;;) { + if (strcmp(name, node->name) == 0) + return node; + + if (node->next == NULL) { + node->next = galloc(strlen(name) + sizeof(HashNameNode)); + node = node->next; + node->next = NULL; + node->id = -1; + node->hashval = n; + strcpy(node->name, name); + return node; + } else { + node = node->next; + } + } + } +} + +SInt32 GetHashNameNodeExportID(HashNameNode *node) { + if (node->id < 0) + node->id = hash_name_id++; + return node->id; +} + +HashNameNode *GetHashNameNodeByID(SInt32 id) { + HashNameNode *node; + short i; + + for (i = 0; i < 2048; i++) { + for (node = name_hash_nodes[i]; node; node = node->next) { + if (id == node->id) + return node; + } + } + + return NULL; +} + +void NameHashExportReset() { + HashNameNode *node; + short i; + + for (i = 0; i < 2048; i++) { + node = name_hash_nodes[i]; + while (node) { + node->id = -1; + node = node->next; + } + } + + hash_name_id = 1; +} + +void NameHashWriteNameTable(GList *glist) { + HashNameNode *node; + HashNameNode **nodes; + short i; + SInt32 n; + + nodes = galloc(sizeof(HashNameNode *) * hash_name_id); + + for (i = 0; i < 2048; i++) { + node = name_hash_nodes[i]; + while (node) { + if (node->id > 0) + nodes[node->id] = node; + node = node->next; + } + } + + for (n = 1; n < hash_name_id; n++) { + node = nodes[n]; + AppendGListWord(glist, node->hashval); + AppendGListID(glist, node->name); + } + + if (glist->size & 1) + AppendGListByte(glist, 0); +} + +void NameHashWriteTargetEndianNameTable(GList *glist) { + HashNameNode *node; + HashNameNode **nodes; + short i; + SInt32 n; + + nodes = galloc(sizeof(HashNameNode *) * hash_name_id); + memclrw(nodes, sizeof(HashNameNode *) * hash_name_id); + + for (i = 0; i < 2048; i++) { + node = name_hash_nodes[i]; + while (node) { + if (node->id > 0) + nodes[node->id] = node; + node = node->next; + } + } + + for (n = 1; n < hash_name_id; n++) { + node = nodes[n]; + if (node == NULL) { + AppendGListTargetEndianWord(glist, 0); + AppendGListID(glist, ""); + } else { + AppendGListTargetEndianWord(glist, node->hashval); + AppendGListID(glist, node->name); + } + } + + if (glist->size & 1) + AppendGListByte(glist, 0); +} + +void InitNameHash() { + name_hash_nodes = galloc(2048 * sizeof(HashNameNode *)); + memclrw(name_hash_nodes, 2048 * sizeof(HashNameNode *)); + hash_name_id = 1; +} + +SInt32 CTool_TotalHeapSize() { + HeapBlock *blockp; + SInt32 size = 0; + + for (blockp = gheap.blocks; blockp; blockp = blockp->next) { + size += blockp->blocksize; + } + for (blockp = lheap.blocks; blockp; blockp = blockp->next) { + size += blockp->blocksize; + } + for (blockp = aheap.blocks; blockp; blockp = blockp->next) { + size += blockp->blocksize; + } + for (blockp = oheap.blocks; blockp; blockp = blockp->next) { + size += blockp->blocksize; + } + for (blockp = bheap.blocks; blockp; blockp = blockp->next) { + size += blockp->blocksize; + } + + return size; +} + +static void getheapinfo(HeapInfo *result, HeapMem *heap) { + HeapBlock *block; + + result->allocsize = heap->allocsize; + for (block = heap->blocks; block; block = block->next) { + result->total_size += block->blocksize - sizeof(HeapBlock); + result->total_free += block->blockfree; + result->blocks++; + if (block->blockfree > result->largest_free_block) + result->largest_free_block = block->blockfree; + } + + result->average_block_size = result->total_size / result->blocks; + result->average_block_free = result->total_free / result->blocks; +} + +void CTool_GetHeapInfo(HeapInfo *result, unsigned char heapID) { + memclrw(result, sizeof(HeapInfo)); + + switch (heapID) { + case 0: + getheapinfo(result, &gheap); + break; + case 1: + getheapinfo(result, &lheap); + break; + case 2: + getheapinfo(result, &aheap); + break; + case 3: + getheapinfo(result, &oheap); + break; + case 4: + getheapinfo(result, &bheap); + break; + case 5: + getheapinfo(result, &gheap); + getheapinfo(result, &lheap); + getheapinfo(result, &aheap); + getheapinfo(result, &oheap); + getheapinfo(result, &bheap); + break; + } +} + +static void MoreHeapSpace(HeapMem *heapp, SInt32 size) { + HeapBlock *blockp; + Handle hndl; + + blockp = heapp->blocks; + if (blockp) { + heapp->curblock->blockfree = heapp->curfree; + while (blockp) { + if (blockp->blockfree >= size) + goto gotBlock; + blockp = blockp->next; + } + } + + /* create new block */ + size += heapp->allocsize; + if (systemHandles) { + hndl = COS_NewOSHandle(size << 1); + if (hndl != 0) + goto createdTempDoubleBlock; + hndl = COS_NewOSHandle(size); + if (hndl != 0) + goto createdBlock; + } + hndl = COS_NewHandle(size); + if (hndl != 0) + goto createdBlock; + + if (heaperror) + heaperror(); + return; + + createdTempDoubleBlock: + size <<= 1; + goto createdBlock; + createdBlock: + COS_LockHandleHi(hndl); + blockp = (HeapBlock *) *hndl; + blockp->next = heapp->blocks; + heapp->blocks = blockp; + blockp->blockhandle = hndl; + blockp->blocksize = size; + blockp->blockfree = size - sizeof(HeapBlock); + gotBlock: + heapp->curblock = blockp; + heapp->curfree = blockp->blockfree; + heapp->curfreep = ((char *) blockp) + blockp->blocksize - blockp->blockfree; +} + +short initheaps(heaperror_t heaperrorproc) { + heaperror = NULL; + lheaplockcount = 0; + + memclrw(&gheap, sizeof(HeapMem)); + memclrw(&lheap, sizeof(HeapMem)); + memclrw(&aheap, sizeof(HeapMem)); + memclrw(&oheap, sizeof(HeapMem)); + memclrw(&bheap, sizeof(HeapMem)); + + gheap.allocsize = 0x38000; + lheap.allocsize = 0x10000; + aheap.allocsize = 0x4000; + oheap.allocsize = 0x40000; + bheap.allocsize = 0x4000; + + MoreHeapSpace(&gheap, 0); + MoreHeapSpace(&lheap, 0); + MoreHeapSpace(&aheap, 0); + MoreHeapSpace(&oheap, 0); + MoreHeapSpace(&bheap, 0); + + gheap.allocsize = 0x8000; + lheap.allocsize = 0x8000; + + heaperror = heaperrorproc; + + if (!gheap.curblock || !lheap.curblock || !aheap.curblock || !oheap.curblock || !bheap.curblock) + return -1; + else + return 0; +} + +short initgheap(heaperror_t heaperrorproc) { + heaperror = NULL; + lheaplockcount = 0; + + memclrw(&gheap, sizeof(HeapMem)); + memclrw(&lheap, sizeof(HeapMem)); + memclrw(&aheap, sizeof(HeapMem)); + memclrw(&oheap, sizeof(HeapMem)); + memclrw(&bheap, sizeof(HeapMem)); + + gheap.allocsize = 0x38000; + MoreHeapSpace(&gheap, 0); + gheap.allocsize = 0x8000; + + heaperror = heaperrorproc; + + if (!gheap.curblock) + return -1; + else + return 0; +} + +heaperror_t getheaperror() { + return heaperror; +} + +void setheaperror(heaperror_t heaperrorproc) { + heaperror = heaperrorproc; +} + +static void relheap(HeapMem *heapp) { + HeapBlock *blockp; + Handle hndl; + + blockp = heapp->blocks; + while (blockp) { + hndl = blockp->blockhandle; + blockp = blockp->next; + COS_FreeHandle(hndl); + } + + memclrw(heapp, sizeof(HeapMem)); +} + +void releaseheaps() { + relheap(&gheap); + relheap(&lheap); + relheap(&aheap); + relheap(&oheap); + relheap(&bheap); +} + +void releasegheap() { + relheap(&gheap); +} + +void releaseoheap() { + relheap(&gheap); + oheap.allocsize = 0x40000; + MoreHeapSpace(&oheap, 0); +} + +void *galloc(SInt32 s) { + char *cp; + + s = (s & ~7) + 8; + if (gheap.curfree < s) + MoreHeapSpace(&gheap, s); + + gheap.curfree -= s; + cp = gheap.curfreep; + gheap.curfreep = cp + s; + return cp; +} + +void *lalloc(SInt32 s) { + char *cp; + + s = (s & ~7) + 8; + if (lheap.curfree < s) + MoreHeapSpace(&lheap, s); + + lheap.curfree -= s; + cp = lheap.curfreep; + lheap.curfreep = cp + s; + return cp; +} + +void *aalloc(SInt32 s) { + char *cp; + + s = (s & ~7) + 8; + if (aheap.curfree < s) + MoreHeapSpace(&aheap, s); + + aheap.curfree -= s; + cp = aheap.curfreep; + aheap.curfreep = cp + s; + return cp; +} + +void *oalloc(SInt32 s) { + char *cp; + + s = (s & ~7) + 8; + if (oheap.curfree < s) + MoreHeapSpace(&oheap, s); + + oheap.curfree -= s; + cp = oheap.curfreep; + oheap.curfreep = cp + s; + return cp; +} + +void *balloc(SInt32 s) { + char *cp; + + s = (s & ~7) + 8; + if (bheap.curfree < s) + MoreHeapSpace(&bheap, s); + + bheap.curfree -= s; + cp = bheap.curfreep; + bheap.curfreep = cp + s; + return cp; +} + +void locklheap() { + lheaplockcount++; +} + +void unlocklheap() { + if (lheaplockcount > 0) + --lheaplockcount; +} + +void freelheap() { + // possible inline or macro? + HeapBlock *blockp; + + if (lheaplockcount == 0) { + blockp = lheap.blocks; + lheap.curblock = blockp; + lheap.curfreep = ((char *) blockp) + sizeof(HeapBlock); + lheap.curfree = blockp->blocksize - sizeof(HeapBlock); + + while (blockp) { + blockp->blockfree = blockp->blocksize - sizeof(HeapBlock); + blockp = blockp->next; + } + } +} + +void freeaheap() { + HeapBlock *blockp; + + blockp = aheap.blocks; + aheap.curblock = blockp; + aheap.curfreep = ((char *) blockp) + sizeof(HeapBlock); + aheap.curfree = blockp->blocksize - sizeof(HeapBlock); + + while (blockp) { + blockp->blockfree = blockp->blocksize - sizeof(HeapBlock); + blockp = blockp->next; + } +} + +void freeoheap() { + HeapBlock *blockp; + + blockp = oheap.blocks; + oheap.curblock = blockp; + oheap.curfreep = ((char *) blockp) + sizeof(HeapBlock); + oheap.curfree = blockp->blocksize - sizeof(HeapBlock); + + while (blockp) { + blockp->blockfree = blockp->blocksize - sizeof(HeapBlock); + blockp = blockp->next; + } +} + +void freebheap() { + HeapBlock *blockp; + + blockp = bheap.blocks; + bheap.curblock = blockp; + bheap.curfreep = ((char *) blockp) + sizeof(HeapBlock); + bheap.curfree = blockp->blocksize - sizeof(HeapBlock); + + while (blockp) { + blockp->blockfree = blockp->blocksize - sizeof(HeapBlock); + blockp = blockp->next; + } +} + +char *ScanHex(char *string, UInt32 *result, Boolean *overflow) { + short c; + UInt32 x; + + x = 0; + *overflow = 0; + + for (;;) { + c = *string; + if (c >= '0' && c <= '9') { + c -= '0'; + } else if (c >= 'A' && c <= 'F') { + c -= ('A' - 10); + } else if (c >= 'a' && c <= 'f') { + c -= ('a' - 10); + } else { + break; + } + + if (x & 0xF0000000) + *overflow = 1; + x = (x << 4) | c; + ++string; + } + + *result = x; + return string; +} + +char *ScanOct(char *string, UInt32 *result, Boolean *overflow) { + short c; + UInt32 x; + + x = 0; + *overflow = 0; + + for (;;) { + c = *string - '0'; + if (c >= 0 && c <= 9) { + if (c >= 8) { + *overflow = 1; + ++string; + break; + } + } else { + break; + } + + if (x & 0xE0000000) + *overflow = 1; + x = (x << 3) | c; + ++string; + } + + *result = x; + return string; +} + +char *ScanDec(char *string, UInt32 *result, Boolean *overflow) { + short c; + UInt32 x; + + x = 0; + *overflow = 0; + + for (;;) { + c = *string - '0'; + if (c >= 0 && c <= 9) { + if (x >= 0x19999999 && (x > 0x19999999 || c > 5)) + *overflow = 1; + } else { + break; + } + + x = (x << 3) + (x << 1) + c; + ++string; + } + + *result = x; + return string; +} + +static char *UnmangleClassname(char *name, char **classname, short *classnamesize, char **out, short *outsize, Boolean addclassname) { + char *cp; + short i; + short n; + short os; + + *classnamesize = 0; + if (*(name++) != '_' || *(name++) != '_') + return name; + + n = 0; + while (name[0] >= '0' && name[0] <= '9') { + n = (n * 10) + name[0] - '0'; + ++name; + } + + if (n > 0) { + *classname = name; + *classnamesize = n; + + if (addclassname) { + cp = *out; + os = *outsize; + for (i = 0; i < n && os < 255; i++, os++) { + *(cp++) = name[i]; + } + if (os < 255) { + *(cp++) = ':'; + os++; + } + if (os < 255) { + *(cp++) = ':'; + os++; + } + *out = cp; + *outsize = os; + } + } + + return name + n; +} + +static char *UnmangleAppend(char *name, char namesize, char **out, short *outsize) { + char *cp; + short i; + short os; + + cp = *out; + os = *outsize; + + for (i = 0; i < namesize && os < 255; i++, os++) { + *(cp++) = name[i]; + } + + *out = cp; + *outsize = os; +} + +void OldUnmangle(char *name, char *out, Boolean full) { + short n; + short namesize; + short classnamesize; + char *classname; + char *cptr; + + if (*name == '.') + ++name; + + namesize = 0; + cptr = name; + if (name[0] == '_' && name[1] == '_') { + if (name[2] == 'c' && name[3] == 't') { + cptr = UnmangleClassname(&name[4], &classname, &classnamesize, &out, &namesize, full); + if (classnamesize == 0) + goto invalid; + UnmangleAppend(classname, classnamesize, &out, &namesize); + } else if (name[2] == 'd' && name[3] == 't') { + cptr = UnmangleClassname(&name[4], &classname, &classnamesize, &out, &namesize, full); + if (classnamesize == 0) + goto invalid; + if (namesize <= 255) { + *(out++) = '~'; + namesize++; + } + UnmangleAppend(classname, classnamesize, &out, &namesize); + } else if (name[2] == 'n' && name[3] == 'w') { + cptr = UnmangleClassname(&name[4], &classname, &classnamesize, &out, &namesize, full); + UnmangleAppend("operator new", 15, &out, &namesize); + } else if (name[2] == 'd' && name[3] == 'l') { + cptr = UnmangleClassname(&name[4], &classname, &classnamesize, &out, &namesize, full); + UnmangleAppend("operator delete", 15, &out, &namesize); + } else { + invalid: + strncpy(out, name, 256); + return; + } + } else { + n = 0; + while (*cptr) { + ++cptr; + ++n; + if (cptr[0] == '_' && cptr[1] == '_') { + cptr = UnmangleClassname(cptr, &classname, &classnamesize, &out, &namesize, full); + break; + } + } + UnmangleAppend(name, n, &out, &namesize); + } + + if (full && cptr[0] == 'F') { + if (cptr[1] == 'v') { + UnmangleAppend("(void)", 6, &out, &namesize); + } else { + UnmangleAppend("(...)", 5, &out, &namesize); + } + } + + *out = 0; +} + +short hash(char *a) { + char hash = 0; + + while (*a) { + hash = hash << 1; + hash ^= *(a++); + } + + return hash & 0x7F; +} + +void memclr(void *ptr, SInt32 size) { + memset(ptr, 0, size); +} + +void memclrw(void *ptr, SInt32 size) { + memset(ptr, 0, size); +} + +void CToLowercase(char *a, char *b) { + char ch; + + do { + ch = tolower(*(a++)); + *(b++) = ch; + } while (ch); +} + +short getbit(SInt32 l) { + switch (l) { + case 0: return -1; + case 1: return 0; + case 2: return 1; + case 4: return 2; + case 8: return 3; + case 0x10: return 4; + case 0x20: return 5; + case 0x40: return 6; + case 0x80: return 7; + case 0x100: return 8; + case 0x200: return 9; + case 0x400: return 10; + case 0x800: return 11; + case 0x1000: return 12; + case 0x2000: return 13; + case 0x4000: return 14; + case 0x8000: return 15; + case 0x10000: return 16; + case 0x20000: return 17; + case 0x40000: return 18; + case 0x80000: return 19; + case 0x100000: return 20; + case 0x200000: return 21; + case 0x400000: return 22; + case 0x800000: return 23; + case 0x1000000: return 24; + case 0x2000000: return 25; + case 0x4000000: return 26; + case 0x8000000: return 27; + case 0x10000000: return 28; + case 0x20000000: return 29; + case 0x40000000: return 30; + case 0x80000000: return 31; + default: return -2; + } +} + +void CTool_EndianConvertWord64(CInt64 ci, char *result) { + UInt32 buf[2]; + buf[0] = ci.hi; + buf[1] = ci.lo; + memcpy(result, buf, 8); +} + +UInt16 CTool_EndianConvertInPlaceWord16Ptr(UInt16 *x) { + unsigned short v; + v = *x; + // this probably has a conversion on non-ppc + *x = v; + return v; +} + +UInt32 CTool_EndianConvertInPlaceWord32Ptr(UInt32 *x) { + unsigned long v; + v = *x; + // this probably has a conversion on non-ppc + *x = v; + return v; +} + +void CTool_EndianConvertVector128() { + // not correct but idc +} + +HashNameNode *CTool_GetPathName(const FSSpec *fss, SInt32 *moddateptr) { + char name[256]; + COS_FileGetPathName(name, fss, moddateptr); + return GetHashNameNodeExport(name); +} + +int strcat_safe(char *dest, const char *src, SInt32 len) { + SInt32 dest_len; + char ch; + + dest_len = strlen(dest); + dest += dest_len; + len -= dest_len; + if (len < 0) + return 1; + + while (len != 0) { + ch = *(dest++) = *(src++); + if (ch == 0) + break; + --len; + } + + if (len == 0 && dest[-1]) { + dest[-1] = 0; + return 1; + } else { + return 0; + } +} diff --git a/compiler_and_linker/unsorted/CCompiler.c b/compiler_and_linker/unsorted/CCompiler.c new file mode 100644 index 0000000..d496389 --- /dev/null +++ b/compiler_and_linker/unsorted/CCompiler.c @@ -0,0 +1,255 @@ +#include "compiler/common.h" +#include "compiler.h" +#include "compiler/types.h" +#include "pref_structs.h" +#include "compiler/CompilerTools.h" + +Boolean systemHandles; + +static Boolean using_license_manager; +Boolean crippled; +SInt32 license_cookie; +CParams cparams; + +// TODO move me to CParser.c, or maybe CMachine.c? +Type sttemplexpr = {TYPETEMPLDEPEXPR, 0}; +Type stillegal = {TYPEILLEGAL, 1}; +Type stvoid = {TYPEVOID, 0}; +TypePointer void_ptr = {TYPEPOINTER, 0, &stvoid, 0}; +TypeFunc rt_func = {TYPEFUNC, 0, NULL, NULL, &stvoid, 0, 0}; +// TODO move me to CParser.c + +static void get_extension(ConstStringPtr src, char *dst) { + int ep; + + dst[0] = 0; + for (ep = src[0]; src[ep] != '.'; ep--) {} + + if (ep >= 2) { + int x; + for (x = 0; (x + ep) <= src[0]; x++) + dst[x] = src[x + ep]; + dst[x] = 0; + } +} + +static int setup_param_block(CWPluginContext context) { + static char target_name[128]; + CWTargetInfo tinfo; + + memset(&cparams, 0, sizeof(CParams)); + cparams.context = context; + + if (CWGetPluginRequest(context, &cparams.pluginRequest) != cwNoErr) + return 0; + if (CWGetAPIVersion(context, &cparams.apiVersion) != cwNoErr) + return 0; + if (CWGetProjectFile(context, &cparams.projectFile) != cwNoErr) + return 0; + if (CWGetProjectFileCount(context, &cparams.projectFileCount) != cwNoErr) + return 0; + if (CWGetMainFileNumber(context, &cparams.mainFileNumber) != cwNoErr) + return 0; + if (CWGetMainFileSpec(context, &cparams.mainFileSpec) != cwNoErr) + return 0; + if (CWGetMainFileText(context, &cparams.mainFileText, &cparams.mainFileTextLength) != cwNoErr) + return 0; + if (CWIsPrecompiling(context, &cparams.isPrecompiling) != cwNoErr) + return 0; + if (CWIsAutoPrecompiling(context, &cparams.isAutoPrecompiling) != cwNoErr) + return 0; + if (CWIsPreprocessing(context, &cparams.isPreprocessing) != cwNoErr) + return 0; + if (CWIsGeneratingDebugInfo(context, &cparams.isGeneratingDebugInfo) != cwNoErr) + return 0; + if (CWIsCachingPrecompiledHeaders(context, &cparams.isCachingPrecompiledHeaders) != cwNoErr) + return 0; + if (CWGetBrowseOptions(context, &cparams.browseOptions) != cwNoErr) + return 0; + cparams.field276 = cparams.isPreprocessing == 0; + if (CWGetMainFileID(context, &cparams.mainFileID) != cwNoErr) + return 0; + if (CWGetTargetInfo(context, &tinfo) != cwNoErr) + return 0; + + cparams.targetOS = tinfo.targetOS; + cparams.targetCPU = tinfo.targetCPU; + cparams.targetName = target_name; + return CWGetTargetName(context, target_name, sizeof(target_name)) == cwNoErr; +} + +static short store_compile_results() { + CWResult result; + + if (cparams.objectDataHandle) + CWSecretAttachHandle(cparams.context, cparams.objectDataHandle, &cparams.objectdata.objectdata); + if (cparams.browseDataHandle) + CWSecretAttachHandle(cparams.context, cparams.browseDataHandle, &cparams.objectdata.browsedata); + + if (cparams.isPreprocessing) { + if (cparams.objectdata.objectdata) { + CWNewTextDocumentInfo docinfo; + memset(&docinfo, 0, sizeof(CWNewTextDocumentInfo)); + docinfo.text = cparams.objectdata.objectdata; + cparams.objectdata.objectdata = NULL; + result = CWCreateNewTextDocument(cparams.context, &docinfo); + } + } else { + result = CWStoreObjectData(cparams.context, cparams.mainFileNumber, &cparams.objectdata); + } + + return result; +} + +static void initialize_compiler_options(CParams *params) { + static PFrontEndC pFrontEnd; + PWarningC pWarningC; + PGlobalOptimizer pGlobalOptimizer; + Handle prefsdata; + char extension[256]; + + memclrw(&copts, sizeof(COpts)); + + CWSecretGetNamedPreferences(cparams.context, "C/C++ Compiler", &prefsdata); + pFrontEnd = *((PFrontEndC *) *prefsdata); + + copts.little_endian = 0; + copts.cplusplus = 1; + copts.objective_c = pFrontEnd.objective_c; + get_extension(params->mainFileSpec.name, extension); + if (!strcmp(extension, ".c") || !strcmp(extension, ".h") || !strcmp(extension, ".pch")) { + copts.cplusplus = pFrontEnd.cplusplus; + } else if (!strcmp(extension, ".m")) { + copts.cplusplus = pFrontEnd.cplusplus; + copts.objective_c = 1; + } else if (!strcmp(extension, ".mm") || !strcmp(extension, ".M")) { + copts.cplusplus = 1; + copts.objective_c = 1; + } + + copts.require_prototypes = pFrontEnd.checkprotos; + copts.ARM_conform = pFrontEnd.arm; + copts.ARM_scoping = pFrontEnd.arm; + copts.trigraphs = pFrontEnd.trigraphs; + copts.only_std_keywords = pFrontEnd.onlystdkeywords; + copts.enumsalwaysint = pFrontEnd.enumsalwaysint; + copts.mpwc_relax = pFrontEnd.mpwpointerstyle; + copts.ANSI_strict = pFrontEnd.ansistrict; + copts.mpwc_newline = pFrontEnd.mpwcnewline; + copts.exceptions = pFrontEnd.enableexceptions; + copts.dont_reuse_strings = pFrontEnd.dontreusestrings; + copts.pool_strings = pFrontEnd.poolstrings; + copts.dont_inline = pFrontEnd.dontinline; + copts.useRTTI = pFrontEnd.useRTTI; + copts.oldprefixname = pFrontEnd.oldprefixname; + copts.multibyteaware = pFrontEnd.multibyteaware; + copts.unsignedchars = pFrontEnd.unsignedchars; + copts.autoinline = pFrontEnd.autoinline; + copts.direct_to_som = pFrontEnd.direct_to_som; + copts.som_env_check = pFrontEnd.som_env_check; + copts.booltruefalse = pFrontEnd.booltruefalse; + copts.always_inline = pFrontEnd.alwaysinline; + copts.inlinelevel = pFrontEnd.inlinelevel; + copts.wchar_type = pFrontEnd.wchar_type; + copts.ecplusplus = pFrontEnd.ecplusplus; + copts.defer_codegen = pFrontEnd.defer_codegen; + copts.inline_max_size = 512; + copts.inline_max_total_size = 100000; + + CWSecretGetNamedPreferences(cparams.context, "C/C++ Warnings", &prefsdata); + pWarningC = *((PWarningC *) *prefsdata); + + copts.warn_illpragma = pWarningC.warn_illpragma; + copts.warn_emptydecl = pWarningC.warn_emptydecl; + copts.warn_possunwant = pWarningC.warn_possunwant; + copts.warn_unusedvar = pWarningC.warn_unusedvar; + copts.warn_unusedarg = pWarningC.warn_unusedarg; + copts.warn_extracomma = pWarningC.warn_extracomma; + copts.pedantic = pWarningC.pedantic; + copts.warningerrors = pWarningC.warningerrors; + copts.warn_hidevirtual = pWarningC.warn_hidevirtual; + copts.warn_implicitconv = pWarningC.warn_implicitconv; + copts.warn_notinlined = pWarningC.warn_notinlined; + copts.warn_structclass = pWarningC.warn_structclass; + + CWSecretGetNamedPreferences(cparams.context, "PPC Global Optimizer", &prefsdata); + pGlobalOptimizer = *((PGlobalOptimizer *) *prefsdata); + + copts.optimizationlevel = pGlobalOptimizer.optimizationlevel; + copts.optimize_for_size = (Boolean) (pGlobalOptimizer.optfor == 1); + + copts.crippled = crippled; + copts.loop_unroll_count = 8; + copts.loop_unroll_size_threshold = 100; + copts.isGeneratingDebugInfo = params->isGeneratingDebugInfo; + copts.pchCreator = CWFOURCHAR('C','W','I','E'); + copts.pchType = CWFOURCHAR('M','M','C','H'); + copts.text = CWFOURCHAR('T','E','X','T'); +} + +static void GetLicense() { + if (!license_cookie) { + crippled = 1; + CWCheckoutLicense(cparams.context, "MacOS_Plugins_MacOS_Unlimited", "7", 2, NULL, &license_cookie); + if (license_cookie) { + CWCheckinLicense(cparams.context, license_cookie); + crippled = 0; + } + + CWCheckoutLicense(cparams.context, "MacOS_Plugins_MacOS_Limited", "7", 0, NULL, &license_cookie); + using_license_manager = 1; + } +} + +static void ReleaseLicense() { + if (license_cookie && using_license_manager) + CWCheckinLicense(cparams.context, license_cookie); + using_license_manager = 0; + license_cookie = 0; +} + +CWPLUGIN_ENTRY(MWC_main)(CWPluginContext context) { + CWResult result; + SInt32 request; + + result = cwNoErr; + CWGetPluginRequest(context, &request); + + switch (request) { + case reqInitialize: + cparams.context = context; + license_cookie = 0; + CodeGen_InitCompiler(); + break; + case reqTerminate: + cparams.context = context; + CodeGen_TermCompiler(); + ReleaseLicense(); + break; + case reqCompile: + setup_param_block(context); + GetLicense(); + if (license_cookie) { + initialize_compiler_options(&cparams); + CodeGen_UpdateOptimizerOptions(); + CodeGen_InitBackEndOptions(); + CodeGen_UpdateOptimizerOptions(); + CodeGen_UpdateBackEndOptions(); + if (C_Compiler(&cparams)) + result = store_compile_results(); + else + result = cwErrRequestFailed; + } else { + result = cwErrSilent; + } + break; + } + + return CWDonePluginRequest(context, result); +} + +void PrintProgressFunction(const char *str) { + char buf[96]; + sprintf(buf, "Compiling function:\t%.64s", str); + CWShowStatus(cparams.context, buf, ""); +} diff --git a/compiler_and_linker/unsorted/CError.c b/compiler_and_linker/unsorted/CError.c new file mode 100644 index 0000000..e7493f3 --- /dev/null +++ b/compiler_and_linker/unsorted/CError.c @@ -0,0 +1,1096 @@ +#include "cos.h" +#include "compiler/CError.h" +#include "compiler/CInt64.h" +#include "compiler/CompilerTools.h" +#include "compiler/enode.h" +#include "compiler/objc.h" +#include "compiler/objects.h" +#include "compiler/scopes.h" +#include "compiler/templates.h" +#include "compiler/tokens.h" +#include "compiler.h" + +TStreamElement *cerror_locktoken; +static TStreamElement *cerror_token; +static short cerror_errorcount; +static SInt32 cerror_lasterrorline; +char cerror_synchdata[32]; +short cerror_synchoffset; +int CError_BreakPointcount; + +void CError_Init() { + cerror_errorcount = 0; + cerror_lasterrorline = -1; + cerror_token = 0; + cerror_locktoken = 0; +} + +void CError_SetErrorToken(TStreamElement *token) { + if (token && token->tokenfile) + cerror_token = token; +} + +void CError_SetNullErrorToken() { + cerror_token = (TStreamElement *) -1; +} + +void CError_LockErrorPos(TStreamElement *token, TStreamElement **saved) { + *saved = cerror_locktoken; + if (token && token->tokenfile) + cerror_locktoken = token; +} + +void CError_UnlockErrorPos(TStreamElement **saved) { + cerror_locktoken = *saved; +} + +void CError_ResetErrorSkip() { + cerror_lasterrorline = -1; +} + +void CError_GetErrorString(char *buf, short code) { +#line 142 + CError_ASSERT(code >= CErrorStr100 && code < CErrorStrMAX); + COS_GetString(buf, 10000, code - 99); +} + +void CError_BufferInit(CErrorBuffer *eb, char *buf, SInt32 bufSize) { + eb->start = eb->end = buf; + eb->size = eb->remaining = bufSize - 1; +} + +void CError_BufferGrow(CErrorBuffer *eb, SInt32 amount) { + char *newBuf; + + newBuf = lalloc(eb->size + amount); + memcpy(newBuf, eb->start, eb->size); + eb->start = newBuf; + eb->end = newBuf + eb->size - eb->remaining; + eb->size += amount; + eb->remaining += amount; +} + +void CError_BufferAppendChar(CErrorBuffer *eb, char ch) { + if (eb) { + if (!eb->remaining) + CError_BufferGrow(eb, 256); + *(eb->end++) = ch; + eb->remaining--; + } +} + +void CError_BufferAppendString(CErrorBuffer *eb, const char *str) { + size_t len; + + if (eb) { + len = strlen(str); + if (eb->remaining < len) + CError_BufferGrow(eb, len); + memcpy(eb->end, str, len); + eb->end += len; + eb->remaining -= len; + } +} + +void CError_BufferTerminate(CErrorBuffer *eb) { + if (eb->remaining == 0) + CError_BufferGrow(eb, 1); + *eb->end = 0; + eb->remaining = 0; +} + +void CError_BufferAppendQualifier(CErrorBuffer *eb, UInt32 qual) { + if (qual & Q_PASCAL) + CError_BufferAppendString(eb, "pascal "); + if (qual & Q_CONST) + CError_BufferAppendString(eb, "const "); + if (qual & Q_VOLATILE) + CError_BufferAppendString(eb, "volatile "); + if (qual & Q_EXPLICIT) + CError_BufferAppendString(eb, "explicit "); + if (qual & Q_RESTRICT) + CError_BufferAppendString(eb, "restrict "); +} + +void CError_BufferAppendTemplArgExpr(CErrorBuffer *eb, ENode *node) { + char buf[32]; + + if (node) { + switch (node->type) { + case EINTCONST: + CInt64_PrintDec(buf, node->data.intval); + CError_BufferAppendString(eb, buf); + return; + case EOBJREF: + CError_BufferAppendChar(eb, '&'); + CError_AppendObjectName(eb, node->data.objref); + return; + } + } + + CError_BufferAppendString(eb, "{targ_expr}"); +} + +void CError_BufferAppendTemplArg(CErrorBuffer *eb, TemplArg *targ) { + switch (targ->pid.type) { + case TPT_TYPE: + CError_BufferAppendType(eb, targ->data.typeparam.type, targ->data.typeparam.qual); + break; + case TPT_NONTYPE: + CError_BufferAppendTemplArgExpr(eb, targ->data.paramdecl.expr); + break; + case TPT_TEMPLATE: + CError_BufferAppendType(eb, targ->data.ttargtype, 0); + break; + default: +#line 300 + CError_FATAL(); + } +} + +void CError_BufferAppendTemplArgs(CErrorBuffer *eb, TemplArg *targs) { + if (targs) { + CError_BufferAppendChar(eb, '<'); + while (targs) { + CError_BufferAppendTemplArg(eb, targs); + if (targs->next) + CError_BufferAppendString(eb, ", "); + targs = targs->next; + } + CError_BufferAppendChar(eb, '>'); + } +} + +void CError_BufferAppendNameSpace(CErrorBuffer *eb, NameSpace *nspace) { + while (nspace) { + if (nspace->name) { + CError_BufferAppendNameSpace(eb, nspace->parent); + if (nspace->theclass) { + CError_BufferAppendString(eb, nspace->theclass->classname->name); + if (nspace->theclass->flags & CLASS_FLAGS_800) + CError_BufferAppendTemplArgs( + eb, + !TEMPL_CLASS_INST(nspace->theclass)->oargs ? TEMPL_CLASS_INST(nspace->theclass)->inst_args : TEMPL_CLASS_INST(nspace->theclass)->oargs + ); + } else { + CError_BufferAppendString(eb, nspace->name->name); + } + CError_BufferAppendString(eb, "::"); + return; + } + nspace = nspace->parent; + } +} + +void CError_BufferAppendPType(CErrorBuffer *eb, Type *ty) { + switch (ty->type) { + case TYPEPOINTER: + CError_BufferAppendPType(eb, TYPE_POINTER(ty)->target); + if (TYPE_POINTER(ty)->qual & Q_REFERENCE) + CError_BufferAppendString(eb, "&"); + else + CError_BufferAppendString(eb, "*"); + CError_BufferAppendQualifier(eb, TYPE_POINTER(ty)->qual); + break; + case TYPEMEMBERPOINTER: + CError_BufferAppendPType(eb, TYPE_MEMBER_POINTER(ty)->ty1); + CError_BufferAppendType(eb, TYPE_MEMBER_POINTER(ty)->ty2, 0); + CError_BufferAppendString(eb, "::*"); + CError_BufferAppendQualifier(eb, TYPE_MEMBER_POINTER(ty)->qual); + break; + } +} + +void CError_BufferAppendTemplDepType(CErrorBuffer *eb, TypeTemplDep *type) { + char buf[64]; + switch (type->dtype) { + case TEMPLDEP_ARGUMENT: + if (type->u.pid.nindex) + sprintf(buf, "T%ld_%ld", type->u.pid.nindex, type->u.pid.index); + else + sprintf(buf, "T%ld", type->u.pid.index); + CError_BufferAppendString(eb, buf); + break; + case TEMPLDEP_QUALNAME: + CError_BufferAppendTemplDepType(eb, type->u.qual.type); + CError_BufferAppendString(eb, "::"); + CError_BufferAppendString(eb, type->u.qual.name->name); + break; + case TEMPLDEP_TEMPLATE: + CError_BufferAppendType(eb, (Type *) type->u.templ.templ, 0); + CError_BufferAppendTemplArgs(eb, type->u.templ.args); + break; + case TEMPLDEP_ARRAY: + CError_BufferAppendType(eb, type->u.array.type, 0); + CError_BufferAppendChar(eb, '['); + CError_BufferAppendTemplArgExpr(eb, type->u.array.index); + CError_BufferAppendChar(eb, ']'); + break; + case TEMPLDEP_QUALTEMPL: + CError_BufferAppendTemplDepType(eb, type->u.qualtempl.type); + CError_BufferAppendString(eb, "::"); + CError_BufferAppendTemplArgs(eb, type->u.qualtempl.args); + break; + case TEMPLDEP_BITFIELD: + CError_BufferAppendType(eb, type->u.bitfield.type, 0); + CError_BufferAppendChar(eb, '['); + CError_BufferAppendTemplArgExpr(eb, type->u.bitfield.size); + CError_BufferAppendChar(eb, ']'); + break; + default: +#line 463 + CError_FATAL(); + } +} + +void CError_BufferAppendFuncArgs(CErrorBuffer *eb, TypeFunc *tfunc, Boolean isMethod) { + // not matching - weirdness with referencing string constants + FuncArg *arg; + UInt32 qual; + + qual = 0; + CError_BufferAppendChar(eb, '('); + if ((arg = tfunc->args)) { + if (isMethod) { + qual = arg->qual; + arg = arg->next; + if (arg) + arg = arg->next; + } else if ((tfunc->flags & FUNC_FLAGS_METHOD) && !TYPE_METHOD(tfunc)->x26) { + qual = arg->qual; + arg = arg->next; + if (arg) { + if ((tfunc->flags & FUNC_FLAGS_2000) || ((tfunc->flags & FUNC_FLAGS_1000) && (TYPE_METHOD(tfunc)->theclass->flags & CLASS_FLAGS_20))) + arg = arg->next; + } + } + + while (arg) { + if (arg == &elipsis || arg == &oldstyle) { + CError_BufferAppendString(eb, "..."); + break; + } else { + CError_BufferAppendType(eb, arg->type, arg->qual); + } + + if (!arg->next) { + CError_BufferAppendString(eb, ", "); + break; + } + } + } + CError_BufferAppendChar(eb, ')'); + if (qual) + CError_BufferAppendQualifier(eb, qual); +} + +void CError_BufferAppendType(CErrorBuffer *eb, Type *ty, UInt32 qual) { + // not matching - register issues + char buf[16]; + Type *scan, *scan2; + + switch (ty->type) { + case TYPEVOID: + CError_BufferAppendQualifier(eb, qual); + CError_BufferAppendString(eb, "void"); + break; + case TYPEINT: + case TYPEFLOAT: + CError_BufferAppendQualifier(eb, qual); + switch (TYPE_INTEGRAL(ty)->integral) { + case IT_BOOL: + CError_BufferAppendString(eb, "bool"); + break; + case IT_CHAR: + CError_BufferAppendString(eb, "char"); + break; + case IT_UCHAR: + CError_BufferAppendString(eb, "unsigned char"); + break; + case IT_SCHAR: + CError_BufferAppendString(eb, "signed char"); + break; + case IT_WCHAR_T: + CError_BufferAppendString(eb, "wchar_t"); + break; + case IT_SHORT: + CError_BufferAppendString(eb, "short"); + break; + case IT_USHORT: + CError_BufferAppendString(eb, "unsigned short"); + break; + case IT_INT: + CError_BufferAppendString(eb, "int"); + break; + case IT_UINT: + CError_BufferAppendString(eb, "unsigned int"); + break; + case IT_LONG: + CError_BufferAppendString(eb, "long"); + break; + case IT_ULONG: + CError_BufferAppendString(eb, "unsigned long"); + break; + case IT_LONGLONG: + CError_BufferAppendString(eb, "long long"); + break; + case IT_ULONGLONG: + CError_BufferAppendString(eb, "unsigned long long"); + break; + case IT_FLOAT: + CError_BufferAppendString(eb, "float"); + break; + case IT_SHORTDOUBLE: + CError_BufferAppendString(eb, "short double"); + break; + case IT_DOUBLE: + CError_BufferAppendString(eb, "double"); + break; + case IT_LONGDOUBLE: + CError_BufferAppendString(eb, "long double"); + break; + default: +#line 584 + CError_FATAL(); + } + break; + case TYPEENUM: + CError_BufferAppendQualifier(eb, qual); + CError_BufferAppendNameSpace(eb, TYPE_ENUM(ty)->nspace); + if (TYPE_ENUM(ty)->enumname) + CError_BufferAppendString(eb, TYPE_ENUM(ty)->enumname->name); + else + CError_BufferAppendString(eb, "{unnamed-enum}"); + break; + case TYPESTRUCT: + CError_BufferAppendQualifier(eb, qual); + switch (TYPE_STRUCT(ty)->stype) { + case STRUCT_TYPE_STRUCT: + CError_BufferAppendString(eb, "struct "); + break; + case STRUCT_TYPE_UNION: + CError_BufferAppendString(eb, "struct "); + break; + case STRUCT_TYPE_4: + case STRUCT_TYPE_5: + case STRUCT_TYPE_6: + case STRUCT_TYPE_7: + case STRUCT_TYPE_8: + case STRUCT_TYPE_9: + case STRUCT_TYPE_A: + case STRUCT_TYPE_B: + case STRUCT_TYPE_C: + case STRUCT_TYPE_D: + case STRUCT_TYPE_E: + break; + default: +#line 618 + CError_FATAL(); + } + if (TYPE_STRUCT(ty)->name) + CError_BufferAppendString(eb, TYPE_STRUCT(ty)->name->name); + break; + case TYPECLASS: + CError_BufferAppendQualifier(eb, qual); + CError_BufferAppendNameSpace(eb, TYPE_CLASS(ty)->nspace->parent); + if (TYPE_CLASS(ty)->classname) { + CError_BufferAppendString(eb, TYPE_CLASS(ty)->classname->name); + if (TYPE_CLASS(ty)->flags & CLASS_FLAGS_800) + CError_BufferAppendTemplArgs( + eb, + TEMPL_CLASS_INST(ty)->oargs ? TEMPL_CLASS_INST(ty)->oargs : TEMPL_CLASS_INST(ty)->inst_args + ); + } else { + CError_BufferAppendString(eb, "{unnamed-class}"); + } + break; + case TYPEPOINTER: + case TYPEMEMBERPOINTER: + scan = ty; + next_ptr: + switch (scan->type) { + case TYPEPOINTER: + scan = TYPE_POINTER(scan)->target; + goto next_ptr; + case TYPEMEMBERPOINTER: + scan = TYPE_MEMBER_POINTER(scan)->ty1; + goto next_ptr; + } + + CError_BufferAppendQualifier(eb, qual); + switch (scan->type) { + case TYPEFUNC: + if (TYPE_FUNC(scan)->flags & FUNC_FLAGS_PASCAL) + CError_BufferAppendString(eb, "pascal "); + CError_BufferAppendType(eb, TYPE_FUNC(scan)->functype, 0); + CError_BufferAppendString(eb, " ("); + CError_BufferAppendPType(eb, ty); + CError_BufferAppendChar(eb, ')'); + CError_BufferAppendFuncArgs(eb, TYPE_FUNC(scan), ty->type == TYPEMEMBERPOINTER); + break; + case TYPEARRAY: + scan2 = scan; + while (scan->type == TYPEARRAY) + scan = TYPE_POINTER(scan)->target; + CError_BufferAppendType(eb, scan, 0); + CError_BufferAppendString(eb, " ("); + CError_BufferAppendPType(eb, ty); + CError_BufferAppendChar(eb, ')'); + ty = scan2; + goto append_array_lengths; + default: + CError_BufferAppendType(eb, scan, 0); + CError_BufferAppendChar(eb, ' '); + CError_BufferAppendPType(eb, ty); + break; + } + break; + case TYPEFUNC: + if (TYPE_FUNC(ty)->flags & FUNC_FLAGS_PASCAL) + CError_BufferAppendString(eb, "pascal "); + CError_BufferAppendQualifier(eb, qual); + CError_BufferAppendType(eb, TYPE_FUNC(ty)->functype, 0); + CError_BufferAppendChar(eb, ' '); + CError_BufferAppendFuncArgs(eb, TYPE_FUNC(ty), 0); + break; + case TYPEARRAY: + CError_BufferAppendQualifier(eb, qual); + scan = ty; + while (scan->type == TYPEARRAY) + scan = TYPE_POINTER(scan)->target; + CError_BufferAppendType(eb, scan, 0); + append_array_lengths: + while (ty->type == TYPEARRAY) { + CError_BufferAppendChar(eb, '['); + if (ty->size && TYPE_POINTER(ty)->target->size) { + sprintf(buf, "%ld", ty->size / TYPE_POINTER(ty)->target->size); + CError_BufferAppendString(eb, buf); + } + CError_BufferAppendChar(eb, ']'); + ty = TYPE_POINTER(ty)->target; + } + break; + case TYPETEMPLATE: + CError_BufferAppendQualifier(eb, qual); + CError_BufferAppendTemplDepType(eb, TYPE_TEMPLATE(ty)); + break; + case TYPETEMPLDEPEXPR: + CError_BufferAppendString(eb, "T"); + break; + case TYPEBITFIELD: + sprintf(buf, "bitfield:%ld", TYPE_BITFIELD(ty)->unkB); + CError_BufferAppendString(eb, buf); + break; + default: +#line 752 + CError_FATAL(); + } +} + +char *CError_GetTypeName(Type *ty, UInt32 qual, Boolean useGlobalHeap) { + CErrorBuffer eb; + char buf[256]; + char *ptr; + + CError_BufferInit(&eb, buf, sizeof(buf)); + CError_BufferAppendType(&eb, ty, qual); + CError_BufferTerminate(&eb); + + if (useGlobalHeap) + ptr = galloc(eb.size + 1); + else + ptr = lalloc(eb.size + 1); + + return strcpy(ptr, eb.start); +} + +void CError_AppendUnqualFunctionName(CErrorBuffer *eb, NameSpace *nspace, HashNameNode *name, TypeFunc *tfunc) { + Boolean flag = 0; + char *opname; + + if (nspace && nspace->theclass) { + if (name == constructor_name_node) { + CError_BufferAppendString(eb, nspace->theclass->classname->name); + flag = 1; + } else if (name == destructor_name_node) { + CError_BufferAppendChar(eb, '~'); + CError_BufferAppendString(eb, nspace->theclass->classname->name); + flag = 1; + } + } + + if (!flag) { + opname = CMangler_GetOperator(name); + if (!opname) { + if (tfunc && (tfunc->flags & FUNC_FLAGS_40)) { + CError_BufferAppendString(eb, "operator "); + CError_BufferAppendType(eb, tfunc->functype, tfunc->qual); + } else { + CError_BufferAppendString(eb, name->name); + } + } else { + CError_BufferAppendString(eb, opname); + } + } +} + +void CError_AppendFunctionName(CErrorBuffer *eb, NameSpace *nspace, HashNameNode *name, TemplArg *templargs, TypeFunc *tfunc) { + while (nspace->is_templ && nspace->parent) + nspace = nspace->parent; + + CError_BufferAppendNameSpace(eb, nspace); + CError_AppendUnqualFunctionName(eb, nspace, name, tfunc); + CError_BufferAppendTemplArgs(eb, templargs); + if (tfunc) { + if (!templargs && (tfunc->flags & FUNC_FLAGS_100000)) + CError_BufferAppendString(eb, "<...>"); + CError_BufferAppendFuncArgs(eb, tfunc, 0); + } else { + CError_BufferAppendString(eb, "()"); + } +} + +void CError_AppendObjectName(CErrorBuffer *eb, Object *obj) { + if (obj->type->type == TYPEFUNC) { + CError_AppendFunctionName(eb, obj->nspace, obj->name, obj->u.func.inst ? obj->u.func.inst->args : NULL, TYPE_FUNC(obj->type)); + } else { + CError_BufferAppendNameSpace(eb, obj->nspace); + CError_BufferAppendString(eb, obj->name->name); + } +} + +void CError_AppendMethodName(CErrorBuffer *eb, ObjCMethod *meth) { + ObjCMethodArg *arg; + + CError_BufferAppendChar(eb, meth->is_class_method ? '+' : '-'); + CError_BufferAppendChar(eb, '('); + CError_BufferAppendType(eb, meth->return_type, meth->return_qual); + CError_BufferAppendChar(eb, ')'); + for (arg = meth->selector_args; arg; arg = arg->next) { + if (arg->selector) + CError_BufferAppendString(eb, arg->selector->name); + if (arg->type) { + CError_BufferAppendString(eb, ":("); + CError_BufferAppendType(eb, arg->type, arg->qual); + CError_BufferAppendChar(eb, ')'); + } + } + if (meth->has_valist) + CError_BufferAppendString(eb, ",..."); +} + +char *CError_GetQualifiedName(NameSpace *nspace, HashNameNode *name) { + CErrorBuffer eb; + char buf[256]; + char *ptr; + + CError_BufferInit(&eb, buf, sizeof(buf)); + CError_BufferAppendNameSpace(&eb, nspace); + CError_BufferAppendString(&eb, name->name); + CError_BufferTerminate(&eb); + + ptr = lalloc(eb.size + 1); + return strcpy(ptr, eb.start); +} + +char *CError_GetFunctionName(NameSpace *nspace, HashNameNode *name, TypeFunc *tfunc) { + CErrorBuffer eb; + char buf[256]; + char *ptr; + + CError_BufferInit(&eb, buf, sizeof(buf)); + CError_AppendFunctionName(&eb, nspace, name, 0, tfunc); + CError_BufferTerminate(&eb); + + ptr = lalloc(eb.size + 1); + return strcpy(ptr, eb.start); +} + +char *CError_GetObjectName(Object *obj) { + CErrorBuffer eb; + char buf[256]; + char *ptr; + + CError_BufferInit(&eb, buf, sizeof(buf)); + CError_AppendObjectName(&eb, obj); + CError_BufferTerminate(&eb); + + ptr = lalloc(eb.size + 1); + return strcpy(ptr, eb.start); +} + +char *CError_GetNameString(NameSpace *nspace, HashNameNode *operatorName) { + CErrorBuffer eb; + char buf[256]; + char *ptr; + char *opStr; + +#line 973 + CError_ASSERT(operatorName); + + opStr = CMangler_GetOperator(operatorName); + if (!opStr) + opStr = operatorName->name; + + if (nspace && nspace->name) { + CError_BufferInit(&eb, buf, sizeof(buf)); + CError_BufferAppendNameSpace(&eb, nspace); + CError_BufferAppendString(&eb, opStr); + CError_BufferTerminate(&eb); + ptr = lalloc(eb.size + 1); + return strcpy(ptr, eb.start); + } else { + return opStr; + } +} + +void CError_ErrorMessage(int errTable, char *str, Boolean flag1, Boolean flag2) { + TStreamElement *token; + short tokensize; + CPrepFileInfo *tokenfile; + char buf[128]; + CWMessageRef myref; + CWMessageRef *ref; + unsigned char messagetype; + + if (CWDisplayLines(cparamblkptr->context, lines) != cwNoErr) + CError_UserBreak(); + + if (!in_assembler && !flag1 && cerror_lasterrorline == lines) { + if (cerror_errorcount++ >= 50) { + if (cerror_errorcount > 60) + longjmp(errorreturn, 1); + tk = lex(); + cerror_errorcount = 0; + if (tk == 0) { + CompilerGetCString(1, buf); + CWReportMessage(cparamblkptr->context, NULL, buf, NULL, messagetypeError, errTable); + longjmp(errorreturn, 1); + } + } + } else { + if (!flag2) { + cerror_lasterrorline = lines; + cerror_errorcount = 0; + } + if (copts.warningerrors) + flag2 = 0; + + if (cerror_token) + token = cerror_token; + else if (cerror_locktoken) + token = cerror_locktoken; + else + token = NULL; + //token = cerror_token ? cerror_token : cerror_locktoken ? cerror_locktoken : NULL; + if ((SInt32) token == -1) { + ref = NULL; + } else { + CPrep_GetTokenContext(token, &tokenfile, &myref.selectionoffset, &tokensize, &myref.linenumber, buf, &myref.tokenoffset, &myref.tokenlength, cerror_synchdata, &cerror_synchoffset); + myref.selectionlength = tokensize; + myref.sourcefile = tokenfile->textfile; + ref = &myref; + } + messagetype = flag2 ? messagetypeWarning : messagetypeError; + if (!flag2) { + anyerrors = 1; + fatalerrors = 1; + } + if (CWReportMessage(cparamblkptr->context, ref, str, buf, messagetype, errTable) != cwNoErr) + longjmp(errorreturn, 1); + } + + cerror_token = NULL; +} + +void CError_BufferAppendTemplateStack(CErrorBuffer *eb) { + TemplStack *stack[64]; + TemplStack *scan; + int index; + int indent; + int count; + + scan = ctempl_curinstance; + for (count = 0; scan && count < 64; count++) { + stack[count] = scan; + scan = scan->next; + } + + for (index = count - 1; index >= 0; index--) { + CError_BufferAppendChar(eb, '\n'); + for (indent = index; indent < count; indent++) + CError_BufferAppendChar(eb, ' '); + CError_BufferAppendString(eb, "(instantiating: '"); + if (stack[index]->is_func) + CError_AppendObjectName(eb, stack[index]->u.func); + else + CError_BufferAppendType(eb, (Type *) stack[index]->u.theclass, 0); + CError_BufferAppendString(eb, "')"); + } + + CError_BufferTerminate(eb); +} + +void CError_ErrorMessageVA(int code, const char *format, va_list list, Boolean flag1, Boolean flag2) { + // register allocation is fucked, matches otherwise + CErrorBuffer eb; + char buf[256]; + char unmangleBuf[256]; + SInt32 moddate; + Type *type; + UInt32 qual; + CError_BufferInit(&eb, buf, sizeof(buf)); + + do { + switch (format[0]) { + case 0: + break; + case '%': + switch (format[1]) { + case 'n': + MWUnmangle(va_arg(list, const char *), unmangleBuf, sizeof(unmangleBuf)); + CError_BufferAppendString(&eb, unmangleBuf); + format += 2; + continue; + case 'u': + CError_BufferAppendString(&eb, va_arg(list, const char *)); + format += 2; + continue; + case 'o': + CError_AppendObjectName(&eb, va_arg(list, Object *)); + format += 2; + continue; + case 'm': + CError_AppendMethodName(&eb, va_arg(list, ObjCMethod *)); + format += 2; + continue; + case 't': + type = va_arg(list, Type *); + qual = va_arg(list, UInt32); + CError_BufferAppendType(&eb, type, qual); + format += 2; + continue; + case '%': + CError_BufferAppendChar(&eb, '%'); + format += 2; + continue; + case 'i': + sprintf(unmangleBuf, "%ld", va_arg(list, SInt32)); + CError_BufferAppendString(&eb, unmangleBuf); + format += 2; + continue; + case 'f': + CError_BufferAppendString(&eb, CTool_GetPathName(va_arg(list, FSSpec *), &moddate)->name); + format += 2; + continue; + default: +#line 1174 + CError_FATAL(); + } + break; + default: + CError_BufferAppendChar(&eb, *(format++)); + continue; + } + break; + } while (1); + + CError_BufferAppendTemplateStack(&eb); + CError_ErrorMessage(code, eb.start, flag1, flag2); +} + +void CError_VAErrorMessage(int code, va_list list, Boolean flag1, Boolean flag2) { + char buf[256]; + + CError_GetErrorString(buf, code); + CError_ErrorMessageVA(code + 10000, buf, list, flag1, flag2); +} + +void CError_Error(int code, ...) { + va_list va; + + if (trychain) + longjmp(trychain->jmpbuf, 1); + + va_start(va, code); + CError_VAErrorMessage(code, va, 0, 0); + va_end(va); + + if (in_assembler && !preprocessing_only) + AssemblerError(); +} + +void CError_ErrorTerm(short code) { + CError_GetErrorString(string, code); + CError_ErrorMessage(code + 10000, string, 0, 0); + longjmp(errorreturn, 1); +} + +void CError_ErrorSkip(int code, ...) { + va_list va; + + if (trychain) + longjmp(trychain->jmpbuf, 1); + + va_start(va, code); + CError_VAErrorMessage(code, va, 0, 0); + va_end(va); + + if (tk != ';' && tk != ')' && tk != '}' && tk != ',' && tk != ']') + tk = lex(); +} + +void CError_ErrorFuncCall(short code, NameSpaceObjectList *args, ENodeList *argNodes) { + // does not match - one branch has loop weirdness + CErrorBuffer eb; + char buf[256]; + char *p; + ENodeList *argscan; + + if (trychain) + longjmp(trychain->jmpbuf, 1); + + CError_GetErrorString(string, code); + CError_BufferInit(&eb, buf, sizeof(buf)); + + while (args && args->object->otype != OT_OBJECT) + args = args->next; +#line 1268 + CError_ASSERT(args); + + p = string; + do { + switch (*p) { + case 0: + goto exit_main_loop; + case '*': + if (OBJECT(args->object)->type->type == TYPEFUNC) { + CError_AppendUnqualFunctionName( + &eb, + OBJECT(args->object)->nspace, + OBJECT(args->object)->name, + TYPE_FUNC(OBJECT(args->object)->type)); + if (TYPE_FUNC(OBJECT(args->object)->type)->flags & FUNC_FLAGS_METHOD) + if (TYPE_FUNC(OBJECT(args->object)->type)->flags & FUNC_FLAGS_1000) + if (TYPE_METHOD(OBJECT(args->object)->type)->theclass->flags & CLASS_FLAGS_20) + if (argNodes) + argNodes = argNodes->next; + } else { + CError_BufferAppendString(&eb, OBJECT(args->object)->name->name); + } + CError_BufferAppendChar(&eb, '('); + argscan = argNodes; + while (argscan) { + CError_BufferAppendType(&eb, argscan->node->rtype, argscan->node->flags & ENODE_FLAG_QUALS); + if ((argscan = argscan->next)) + CError_BufferAppendString(&eb, ", "); + } + CError_BufferAppendChar(&eb, ')'); + break; + default: + CError_BufferAppendChar(&eb, *p); + } + p++; + } while (1); + +exit_main_loop: + while (args) { + if (args->object->otype == OT_OBJECT) { + CError_BufferAppendChar(&eb, '\n'); + CError_BufferAppendChar(&eb, '\''); + CError_AppendObjectName(&eb, (Object *) args->object); + CError_BufferAppendChar(&eb, '\''); + } + args = args->next; + } + + CError_BufferAppendTemplateStack(&eb); + CError_ErrorMessage(10000 + code, eb.start, 0, 0); +} + +void CError_OverloadedFunctionError2(Object *obj, ObjectList *olst, ENodeList *argNodes) { + // not sure if the arg is actually ObjectList since it's never called lmao + NameSpaceObjectList first; + NameSpaceObjectList *current; + + first.object = (ObjBase *) obj; + current = &first; + while (olst) { + current->next = lalloc(sizeof(NameSpaceObjectList)); + current = current->next; + current->object = (ObjBase *) olst->object; + olst = olst->next; + } + current->next = NULL; + + CError_ErrorFuncCall(392, &first, argNodes); +} + +void CError_OverloadedFunctionError(Object *obj, ObjectList *olst) { + // not sure if this arg is ObjectList or NameSpaceObjectList + CErrorBuffer eb; + char buf[256]; + + if (trychain) + longjmp(trychain->jmpbuf, 1); + + CError_GetErrorString(string, 199); + CError_BufferInit(&eb, buf, sizeof(buf)); + CError_BufferAppendString(&eb, string); + + if (obj) { + CError_BufferAppendChar(&eb, '\n'); + CError_BufferAppendChar(&eb, '\''); + CError_AppendObjectName(&eb, obj); + CError_BufferAppendChar(&eb, '\''); + } + while (olst) { + CError_BufferAppendChar(&eb, '\n'); + CError_BufferAppendChar(&eb, '\''); + CError_AppendObjectName(&eb, olst->object); + CError_BufferAppendChar(&eb, '\''); + olst = olst->next; + } + CError_BufferAppendTemplateStack(&eb); + CError_ErrorMessage(10199, eb.start, 0, 0); +} + +void CError_AbstractClassError(TypeClass *tclass) { + int result = CClass_CheckPures(tclass); + if (!result) + CError_Error(372, tclass, 0); + else + CError_Error(194, result); +} + +void CError_Warning(int code, ...) { + va_list va; + if (trychain) + return; + + if (copts.supress_warnings) { + va_start(va, code); + } else { + va_start(va, code); + CError_VAErrorMessage(code, va, 0, 1); + } + va_end(va); +} + +void CError_BreakPoint(const char *a, const char *b) { + if (!a || !strcmp(a, b)) + CError_BreakPointcount++; +} + +void CError_Internal(char *filename, int line) { + char tmp[128]; + CompilerGetCString(5, tmp); + sprintf(string, tmp, filename, line); + CError_ErrorMessage(10001, string, 1, 0); + longjmp(errorreturn, 1); + CError_BreakPoint(0, 0); +} + +void CError_ExpressionTooComplex() { + CompilerGetCString(6, string); + CError_ErrorMessage(10002, string, 1, 0); + longjmp(errorreturn, 1); +} + +void CError_NoMem() { + cprep_nomem_exit = 1; + longjmp(errorreturn, 1); +} + +void CError_UserBreak() { + CompilerGetCString(8, string); + longjmp(errorreturn, 1); +} + +void CError_CannotOpen() { + CompilerGetCString(9, string); + CWReportMessage(cparamblkptr->context, NULL, string, NULL, messagetypeError, 0); + longjmp(errorreturn, 1); +} + +void CError_QualifierCheck(UInt32 qual) { + if (qual) { + Boolean anything = 0; + + if (qual & Q_CONST) { + CError_Error(CErrorStr313, "const"); + anything = 1; + } + if (qual & Q_VOLATILE) { + CError_Error(CErrorStr313, "volatile"); + anything = 1; + } + if (qual & Q_RESTRICT) { + CError_Error(CErrorStr313, "restrict"); + anything = 1; + } + if (qual & Q_ASM) { + CError_Error(CErrorStr313, "asm"); + anything = 1; + } + if (qual & Q_PASCAL) { + CError_Error(CErrorStr313, "pascal"); + anything = 1; + } + if (qual & Q_INLINE) { + CError_Error(CErrorStr313, "inline"); + anything = 1; + } + if (qual & Q_REFERENCE) { + CError_Error(CErrorStr313, "& reference type"); + anything = 1; + } + if (qual & Q_EXPLICIT) { + CError_Error(CErrorStr313, "explicit"); + anything = 1; + } + if (qual & Q_MUTABLE) { + CError_Error(CErrorStr313, "mutable"); + anything = 1; + } + if (qual & Q_VIRTUAL) { + CError_Error(CErrorStr313, "virtual"); + anything = 1; + } + if (qual & Q_FRIEND) { + CError_Error(CErrorStr313, "friend"); + anything = 1; + } + if (qual & Q_IN) { + CError_Error(CErrorStr313, "in"); + anything = 1; + } + if (qual & Q_OUT) { + CError_Error(CErrorStr313, "out"); + anything = 1; + } + if (qual & Q_INOUT) { + CError_Error(CErrorStr313, "inout"); + anything = 1; + } + if (qual & Q_BYCOPY) { + CError_Error(CErrorStr313, "bycopy"); + anything = 1; + } + if (qual & Q_BYREF) { + CError_Error(CErrorStr313, "byref"); + anything = 1; + } + if (qual & Q_ONEWAY) { + CError_Error(CErrorStr313, "oneway"); + anything = 1; + } + if (qual & Q_ALIGNED_MASK) { + CError_Error(CErrorStr313, "__attribute__((aligned(?)))"); + anything = 1; + } + + if (!anything) + CError_Error(CErrorStr176); + } +} diff --git a/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) { +} |