summaryrefslogtreecommitdiff
path: root/compiler_and_linker/FrontEnd/C
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/FrontEnd/C
parent685f22a6a0a5403c76316a2390c021a7b0f7597d (diff)
downloadMWCC-d0b9848c54e6f85ab713f059dcd1ddef7e57caa6.tar.gz
MWCC-d0b9848c54e6f85ab713f059dcd1ddef7e57caa6.zip
a bunch of compiler stuff
Diffstat (limited to 'compiler_and_linker/FrontEnd/C')
-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
3 files changed, 3777 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);
+}