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