diff options
author | Ash Wolf <ninji@wuffs.org> | 2022-10-25 20:30:28 +0100 |
---|---|---|
committer | Ash Wolf <ninji@wuffs.org> | 2022-10-25 20:30:28 +0100 |
commit | d0b9848c54e6f85ab713f059dcd1ddef7e57caa6 (patch) | |
tree | 5bdb9dbf6c853780bc444dc92bf6f9fa3a95742a /compiler_and_linker/FrontEnd/C | |
parent | 685f22a6a0a5403c76316a2390c021a7b0f7597d (diff) | |
download | MWCC-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.c | 921 | ||||
-rw-r--r-- | compiler_and_linker/FrontEnd/C/CPrepTokenizer.c | 166 | ||||
-rw-r--r-- | compiler_and_linker/FrontEnd/C/CScope.c | 2690 |
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 = ¯ohashtable[x]; + while (*scan) { + if ((*scan)->is_special) { + *scan = (*scan)->next; + } else { + scan = &(*scan)->next; + } + } + } +} + +static void CPrep_Reconfig() { + cprep_idarray['$'] = copts.dollar_identifiers != 0; +} + +Boolean setupprep() { + int x; + + now_time = time(NULL); + lineoffset = 0; + include_once = 0; + cprep_eoltokens = 0; + cprep_nostring = 0; + cprep_incondexpr = 0; + filesp = -1; + linetick = 0; + lines = 0; + dofreeaheap = 1; + macrocheck = 1; + maxstringsize = 256; + iflevel = 0; + tokenstacklevel = 0; + cprep_cursymfile = 0; + cprep_files = 0; + CLT_filesp = &filesp; + CLT_filestack = filestack; + anyerrors = 0; + fatalerrors = 0; + was_prep_error = 0; + cprep_strconcat = 0; + + GListErrorProc = CError_NoMem; + mlist.data = NULL; + pplist.data = NULL; + if (InitGList(&mlist, 10000)) + CError_NoMem(); + + stringmem = COS_NewHandle(256); + if (!stringmem) + CError_NoMem(); + ts_buffer = COS_NewHandle(1024 * sizeof(TStreamElement)); + if (!ts_buffer) + CError_NoMem(); + COS_LockHandleHi(ts_buffer); + ts_first = (TStreamElement *) *ts_buffer; + ts_last = ts_first + 1023; + ts_current = ts_first; + ts_elements = 1024; + ts_preread_elements = 0; + + macrohashtable = galloc(sizeof(Macro *) * 2048); + memclrw(macrohashtable, sizeof(Macro *) * 2048); + CPrep_InsertSpecialMacros(); + + for (x = 0; x < 256; x++) + cprep_idarray[x] = 0; + + for (x = 'a'; ; x++) { + cprep_idarray[x] = 1; + if (x == 'z') break; + } + + for (x = 'A'; ; x++) { + cprep_idarray[x] = 1; + if (x == 'Z') break; + } + + for (x = '0'; ; x++) { + cprep_idarray[x] = 2; + if (x == '9') break; + } + + cprep_idarray['_'] = 1; + + CPrep_Reconfig(); + return 0; +} + +void cleanupprep() { + while (filesp >= 0) + popfile(); + + high_mem_mark = CTool_TotalHeapSize(); + releaseheaps(); + GListErrorProc = NULL; + FreeGList(&mlist); + FreeGList(&pplist); + + if (stringmem) { + COS_FreeHandle(stringmem); + stringmem = NULL; + } + + if (ts_buffer) { + COS_FreeHandle(ts_buffer); + ts_buffer = NULL; + } + ts_current = NULL; + ts_first = ts_last = NULL; +} + +static char *getfiledata(FSSpec *spec) { + const char *text; + SInt32 textlength; + short filedatatype; + + if (CWGetFileText(cparamblkptr->context, spec, &text, &textlength, &filedatatype) != cwNoErr) { + Str255 filename; + COS_FileGetFSSpecInfo(spec, NULL, NULL, filename); + cannotopenerror(filename, 1); + return NULL; + } else { + return (char *) text; + } +} + +static Boolean setupfile(StringPtr filename, Boolean flag1, Boolean flag2) { + CPrepFileInfo prepinfo; + CWFileInfo fileinfo; + Str255 file_filename; + char myfilename[256]; + OSType file_type; + SInt32 file_size; + SInt32 file_dirid; + CWMemHandle cache_hnd; + void *cache; + SInt16 refnum; + SInt16 file_vrefnum; + char *extpos; + + if (filesp >= 31) { + was_prep_error = 1; + CError_ErrorTerm(243); + return 0; + } + + memclrw(&prepinfo, sizeof(CPrepFileInfo)); + prepinfo.unkfield126 = !flag1; // may be wrong field! + if (filename) { + memclrw(&fileinfo, sizeof(CWFileInfo)); + fileinfo.fullsearch = flag2; + fileinfo.dependencyType = cwNormalDependency; + fileinfo.isdependentoffile = -1; + memcpy(myfilename, &filename[1], filename[0]); + myfilename[filename[0]] = 0; + + if (CWFindAndLoadFile(cparamblkptr->context, myfilename, &fileinfo) != cwNoErr) { + if (filename[0] + strlen(".framework/Headers") < 255) { + if ((extpos = strchr(myfilename, '/'))) { + // Do Me! 37D8C + } else { + cannotopenerror(filename, 0); + return 0; + } + } else { + cannotopenerror(filename, 0); + return 0; + } + } + + if ((flag2 || include_once) && fileinfo.alreadyincluded) + return 1; + + prepinfo.textfile = fileinfo.filespec; + prepinfo.nameNode = CTool_GetPathName(&fileinfo.filespec, &prepinfo.fileModDate); + if (fileinfo.filedata) { + if (fileinfo.filedatatype == cwFileTypeText) { + prepinfo.textbuffer = (char *) fileinfo.filedata; + prepinfo.textlength = fileinfo.filedatalength; + prepinfo.fileID = fileinfo.fileID; + prepinfo.recordbrowseinfo = fileinfo.recordbrowseinfo; + } else if (fileinfo.filedatatype == cwFileTypePrecompiledHeader) { + PrecompilerRead(0, (void *) fileinfo.filedata); + return 1; + } else { + cannotopenerror(filename, 0); + return 0; + } + } else { + COS_FileGetFSSpecInfo(&prepinfo.textfile, &file_vrefnum, &file_dirid, file_filename); + if (COS_FileOpen(&prepinfo.textfile, &refnum)) { + cannotopenerror(filename, 0); + return 0; + } + if (COS_FileGetType(&prepinfo.textfile, &file_type) || COS_FileGetSize(refnum, &file_size)) { + COS_FileClose(refnum); + cannotopenerror(filename, 0); + return 0; + } + if (file_type == copts.pchType) { + if (cparamblkptr->isCachingPrecompiledHeaders) { + if (CWAllocMemHandle(cparamblkptr->context, file_size, 1, &cache_hnd) != cwNoErr) { + if (CWAllocMemHandle(cparamblkptr->context, file_size, 0, &cache_hnd) != cwNoErr) { + COS_FileClose(refnum); + CError_NoMem(); + } + } + + CWLockMemHandle(cparamblkptr->context, cache_hnd, 0, &cache); + if (COS_FileRead(refnum, cache, file_size)) { + COS_FileClose(refnum); + CWFreeMemHandle(cparamblkptr->context, cache_hnd); + cannotopenerror(filename, 0); + return 0; + } + COS_FileClose(refnum); + CWCachePrecompiledHeader(cparamblkptr->context, &prepinfo.textfile, cache_hnd); + PrecompilerRead(0, cache); + CWUnlockMemHandle(cparamblkptr->context, cache_hnd); + return 1; + } else { + PrecompilerRead(refnum, 0); + COS_FileClose(refnum); + return 1; + } + } else { + COS_FileClose(refnum); + cannotopenerror(filename, 0); + return 0; + } + } + } else { + if (!cparamblkptr->mainFileText) { + COS_FileGetFSSpecInfo(&cparamblkptr->mainFileSpec, &file_vrefnum, &file_dirid, file_filename); + cannotopenerror(file_filename, 1); + return 0; + } + + prepinfo.textfile = cparamblkptr->mainFileSpec; + prepinfo.textbuffer = (char *) cparamblkptr->mainFileText; + prepinfo.textlength = cparamblkptr->mainFileTextLength; + prepinfo.fileID = cparamblkptr->mainFileID; + prepinfo.recordbrowseinfo = cparamblkptr->field276; + } + + if (filesp >= 0) { + filestack[filesp]->linenumber = linenumber; + filestack[filesp]->hasprepline = cprep_hasprepline; + filestack[filesp]->pos = pos - filestack[filesp]->textbuffer; + } + + pos = prepinfo.textbuffer; + linenumber = 1; + at_linestart = 1; + filestack[++filesp] = galloc(sizeof(CPrepFileInfo)); + *filestack[filesp] = prepinfo; + prep_file = filestack[filesp]; + prep_file_start = prep_file->textbuffer; + prep_file_end = prep_file->textbuffer + prep_file->textlength; + if (preprocessing_only && !copts.simple_prepdump) + CPrep_PreprocessDumpFileInfo(1); + + return 1; +} + +void CPrep_TSBufferGrow(int amount) { + int current_offset = ts_current - ts_first; + COS_UnlockHandle(ts_buffer); + if (!COS_ResizeHandle(ts_buffer, sizeof(TStreamElement) * (ts_elements + amount))) + CError_NoMem(); + COS_LockHandleHi(ts_buffer); + ts_elements += amount; + ts_first = (TStreamElement *) *ts_buffer; + ts_last = ts_first + (ts_elements - 1); + ts_current = ts_first + current_offset; +} + +void CPrep_TokenStreamGetState(SInt32 *state) { + *state = ts_current - ts_first; +} + +void CPrep_TokenStreamSetState(SInt32 *state) { + ts_preread_elements += ts_current - ts_first - *state; + ts_current = ts_first + *state; +} + +void CPrep_UnLex() { + ++ts_preread_elements; + --ts_current; +#line 900 + CError_ASSERT(ts_current >= ts_first); +} + +void CPrep_TokenStreamSetCurState(SInt32 *state) { + ts_preread_elements += ts_current - ts_first - (*state - 1); + ts_current = ts_first + (*state - 1); + tk = lex(); +} + +static void CPrep_StreamSkipToBrace() {} +static void CPrep_StreamSkipBlock() {} +void CPrep_StreamGetBlock() {} +void CPrep_StreamGetSemicolon() {} +void CPrep_StreamGetTemplate() {} +void CPrep_StreamInsert() {} +void CPrep_StreamRemove() {} +void CPrep_RemoveTokens() {} +void CPrep_TokenStreamFlush() {} +static void CPrep_TokenSize() {} +void CPrep_CurStreamElement() {} + +void CPrep_GetTokenContext(TStreamElement *token, CPrepFileInfo **tokenfile, SInt32 *selectionoffset, short *tokensize, SInt32 *linenumber, char *buf1, short *tokenoffset, short *tokenlength, char *buf2, short *lastarg) { +} + +void CPrep_Error(short code) { + Boolean save = in_assembler; + in_assembler = 0; + if (code == 102 && (tokenstacklevel > 0 || pos < prep_file_end)) + code = 105; + was_prep_error = 1; + CError_Error(code); + in_assembler = save; +} + +void CPrep_ErrorName(short code, const char *name) { + Boolean save = in_assembler; + in_assembler = 0; + was_prep_error = 1; + if (code == 102 && (tokenstacklevel > 0 || pos < prep_file_end)) + CError_Error(105, name); + else + CError_Error(code, name); + in_assembler = save; +} + +void CPrep_Warning(short code) { + Boolean save = in_assembler; + in_assembler = 0; + was_prep_error = 1; + CError_Warning(code); + in_assembler = save; +} + +void CPrep_WarningName(short code, const char *name) { + Boolean save = in_assembler; + in_assembler = 0; + was_prep_error = 1; + CError_Warning(code, name); + in_assembler = save; +} + +void CPrep_ErrorMessage(int errTable, char *str, Boolean flag1, Boolean flag2) { + Boolean save = in_assembler; + in_assembler = 0; + was_prep_error = 1; + CError_ErrorMessage(errTable, str, flag1, flag2); + in_assembler = save; +} + +void CPrep_ErrorMessageVA(int code, const char *format, va_list list, Boolean flag1, Boolean flag2) { + Boolean save = in_assembler; + in_assembler = 0; + was_prep_error = 1; + CError_ErrorMessageVA(code, format, list, flag1, flag2); + in_assembler = save; +} + +void popfile() { + // r5 and r6 are swapped, not sure why + if (filesp >= 0) { + CWReleaseFileText(cparamblkptr->context, prep_file->textbuffer); + prep_file->textbuffer = NULL; + if (--filesp >= 0) { + prep_file = filestack[filesp]; + prep_file_start = prep_file->textbuffer; + prep_file_end = prep_file->textbuffer + prep_file->textlength; + pos = prep_file_start + prep_file->pos; + linenumber = prep_file->linenumber; + cprep_hasprepline = prep_file->hasprepline; + at_linestart = 1; + } + if (preprocessing_only && !copts.simple_prepdump) + CPrep_PreprocessDumpFileInfo(1); + } +} + +static void prepoffset() {} +static void prepoffset2() {} +void CPrep_SetSourceFile() {} +void CPrep_GetSourceFilePath() {} +void CPrep_NewFileOffsetInfo() {} +void CPrep_GetFileOffsetInfo() {} +void CPrep_GetFileOffsetInfo2() {} +void CPrep_ResetFileInfo() {} +void CPrep_GetPrepPos() {} +Boolean C_Compiler(CParams *param) {} + +static void pushtokenseq(Macro *macro) { + if (tokenstacklevel >= 128) { + was_prep_error = 1; + CError_ErrorTerm(111); + } else { + tokenstack[tokenstacklevel].pos = pos; + tokenstack[tokenstacklevel].macrostart = macrostart; + tokenstack[tokenstacklevel].macro = macro; + if (macro) + macro->xF = 1; + tokenstack[tokenstacklevel].macrocheck = macrocheck; + tokenstacklevel++; + } +} + +void poptokenseq() { + if (!--tokenstacklevel && dofreeaheap) + freeaheap(); + + pos = tokenstack[tokenstacklevel].pos; + macrostart = tokenstack[tokenstacklevel].macrostart; + if (tokenstack[tokenstacklevel].macro) + tokenstack[tokenstacklevel].macro->xF = 0; + macrocheck = tokenstack[tokenstacklevel].macrocheck; + spaceskip = 1; +} + +static void is_nextchar() {} +static void ismacroname() {} +static void ismacroname2() {} +static void ismacroname5() {} +static void ismacroname3() {} +static void ismacroname4() {} +void foundnl() {} +void newline() {} +static void gotonexttoken() {} +short notendofline() {} +static void CPrep_MacroRedefError() {} +static void goendofline() {} +static void CPrep_Define() {} +static void prepundefine() {} +static Boolean CPrep_CheckTarget() {} +static Boolean CPrep_CheckOption() {} +static void CPrep_XpandDefinedCheck() {} +static void XpandString() {} +char *CPrep_GetFileName(char *buffer, Boolean flag1, Boolean flag2) { +} + +static char *XpandSpecialMacro(Macro *macro) { + char buf[512]; + char smallbuf[32]; + char *strptr; + struct tm *tm; + + if (macro == &optiM) { + return CPrep_CheckOption() ? "1" : "0"; + } else if (macro == &trgtM) { + return CPrep_CheckTarget() ? "1" : "0"; + } else if (macro == &lineM) { + sprintf(buf, "%ld", linenumber); + do_string: + strptr = aalloc(strlen(buf) + 1); + strcpy(strptr, buf); + return strptr; + } else if (macro == &fileM) { + CPrep_GetFileName(buf, 0, 1); + goto do_string; + } else if (macro == &dateM) { + tm = localtime(&now_time); + strftime(buf, 64, "\"%b ", tm); + strftime(smallbuf, 32, "%d", tm); + if (smallbuf[0] == '0') + smallbuf[0] = ' '; + strcat(buf, smallbuf); + strftime(smallbuf, 32, " %Y\"", tm); + strcat(buf, smallbuf); + goto do_string; + } else if (macro == &timeM) { + strftime(buf, 64, "\"%H:%M:%S\"", localtime(&now_time)); + goto do_string; + } else if (macro == &stdcM) { + return "1"; + } else if (macro == &casmM || macro == &MWRSM) { + return "0x2405"; + } else if (macro == &cpplM) { + return "199711L"; + } else if (macro == &dtsomM) { + return copts.direct_to_som ? "1" : "0"; + } else if (macro == &ecppM) { + return copts.ecplusplus ? "1" : "0"; + } else if (macro == &stcvM) { + return copts.c9x ? "199901L" : "199409L"; + } else if (macro == &stchM) { + return "0"; + } else { + return CodeGen_ExpandSpecialMacro(macro); + } +} + +static void XpandMacro() {} +static void prepmacro() {} +void macrotest() {} +void CPrep_PragmaLex() {} +void CPrep_PushOption() {} +void CPrep_PopOption() {} +static void CPrep_PragmaImExport() {} +static void pragma_on_off_reset() {} +static void CPrep_PragmaOnceName() {} +static void pragma_precompile_target() {} +static void CPrep_DefinePragmaOnceMacro() {} +static void CPrep_PragmaOnce() {} +static void CPrep_PragmaUnused() {} +static void CPrep_PragmaInlineDepth() {} +static void CPrep_PragmaInlineMaxSize() {} +static void CPrep_PragmaInlineMaxTotalSize() {} + +static void pragma_segment() { + short i; + short t; + char name[256]; + + if (notendofline()) { + for (i = 0; i < 255; i++) { + spaceskip = 0; + t = prepskipnextchar(); + if (spaceskip) + break; + if (t <= ' ') + break; + name[i] = t; + pos = nextcharpos; + } + name[i] = 0; + + if (!i || i >= 255) + CPrep_Warning(186); + + copts.forcedSegment = GetHashNameNodeExport(name); + ObjGen_SegmentName(); + } else { + if (copts.warn_illpragma) + CPrep_Warning(186); + } +} + +static void pragma_options() {} + +static void pragma_push() { + struct COptsPush *push; + + push = galloc(sizeof(struct COptsPush)); + push->next = coptpushs; + coptpushs = push; + + push->opts = copts; +} + +static void pragma_pop() { + if (coptpushs) { + copts = coptpushs->opts; + coptpushs = coptpushs->next; + CMach_Configure(); + } else { + CPrep_Error(237); + } +} + +static void pragma_overload() {} +static void pragma_optimization_level() {} +static void pragma_opt_unroll_count() {} +static void pragma_opt_unroll_instr_count() {} +static void pragma_pack() {} +static void pragma_comment() {} +static void pragma_message() {} +static void preppragma() {} +static void prepinclude() {} +static void prepline() {} +static void CPrep_GetPrepType() {} +static void CPrep_ParseUnary() {} +static void CPrep_ParseBinary() {} +static void CPrep_ParseCond() {} +static void doevalconstexpr() {} +static void pushifstate() {} +static void popifstate() {} +static void positiveif() {} +static void negativeif() {} +static void prepif() {} +static void prepifdef() {} +static void prepifndef() {} +static void prepelif() {} +static void prepelse() {} +static void prependif() {} +static void prepifskip() {} +void preprocessor() {} +void CPrep_BrowserTokenOffset() {} +void CPrep_BrowserFileOffset() {} + +void CPrep_BrowserFilePosition(CPrepFileInfo **fileinfo, SInt32 *offset) { + CPrepFileInfo *file; + + if (ts_first < ts_current) { + file = ts_current[-1].tokenfile; + *offset = ts_current[-1].tokenoffset + 1; + } else { + file = filestack[filesp]; + if (tokenstacklevel) { + *offset = tokenstack[0].pos - filestack[filesp]->textbuffer; + } else { + *offset = pos - filestack[filesp]->textbuffer; + } + } + + if (file && file->fileID > 0 && (file->recordbrowseinfo || gForceSourceLoc)) { + *fileinfo = file; + } else { + *fileinfo = NULL; + *offset = 0; + } +} + +CPrepFileInfo *CPrep_BrowserCurrentFile() { + return prep_file; +} diff --git a/compiler_and_linker/FrontEnd/C/CPrepTokenizer.c b/compiler_and_linker/FrontEnd/C/CPrepTokenizer.c new file mode 100644 index 0000000..5b77268 --- /dev/null +++ b/compiler_and_linker/FrontEnd/C/CPrepTokenizer.c @@ -0,0 +1,166 @@ +#include "compiler.h" +#include "compiler/tokens.h" + +static Boolean prepnextstringchar_foundnl; + +short prepskipnextchar() { + +} + +short prepnextchar() { + +} + +short prepnextstringchar(char *str, Boolean flag) { + +} + +void CPrep_MatchChar(char ch, Boolean flag) { + +} + +char *CPrep_MatchChar2(char *str, char ch, Boolean flag) { + +} + +short prepcurchar() { + +} + +static short prepcurstringchar(char *str) { +} + +static void prepcurstringchar_skip() { +} + +char *ReadIdentifier(char *str) { +} + +static short intsuffix(short token, Boolean flag) { +} + +static short floatsuffix(short token) { +} + +static short tohex(short token) { +} + +static short nextchar(char *str) { +} + +char *CPrep_SkipNewComment(char *str) { + +} + +Boolean skipendoflinematch(char *str, Boolean flag) { +} + +void skipendofline() { +} + +void CPrep_SkipAsmComment() { +} + +static short tille() {} +static short tcret() {} +static short tapos() {} +static short tquot() {} +static short thash() {} +static short tmult() {} +static short tcolo() {} +static short tless() {} +static short tequa() {} +static short tgrea() {} +static short tatsg() {} +static short tperc() {} +static short texcl() {} +static short tplus() {} +static short tminu() {} +static short torrr() {} +static short tampe() {} +static short tpowe() {} +static short tdivi() {} +static short tzero() {} +static short tpoin() {} +static short tnumb() {} +static short tiden() {} +static short tchrL() {} +static short tchra() {} +static short tchrb() {} +static short tchrc() {} +static short tchrd() {} +static short tchre() {} +static short tchrf() {} +static short tchrg() {} +static short tchri() {} +static short tchrl() {} +static short tchrm() {} +static short tchrn() {} +static short tchro() {} +static short tchrp() {} +static short tchrr() {} +static short tchrs() {} +static short tchrt() {} +static short tchru() {} +static short tchrv() {} +static short tchrw() {} +static short tchrx() {} +static short tchr_() {} +static short token() {} +static short tdoll() {} +static short tisid() {} +static short tnull() {} +static short t0x1a() {} + +static short (*cprep_tokenize[256])() = { + &tnull, &tille, &tille, &tille, &tisid, &tisid, &tille, &tille, + &tille, &tille, &tille, &tille, &tille, &tcret, &tille, &tille, + &tille, &tille, &tille, &tille, &tille, &tille, &tille, &tille, + &tille, &tille, &t0x1a, &tille, &tille, &tille, &tille, &tille, + &tille, &texcl, &tquot, &thash, &tdoll, &tperc, &tampe, &tapos, + &token, &token, &tmult, &tplus, &token, &tminu, &tpoin, &tdivi, + &tzero, &tnumb, &tnumb, &tnumb, &tnumb, &tnumb, &tnumb, &tnumb, + &tnumb, &tnumb, &tcolo, &token, &tless, &tequa, &tgrea, &token, + &tatsg, &tiden, &tiden, &tiden, &tiden, &tiden, &tiden, &tiden, + &tiden, &tiden, &tiden, &tiden, &tchrL, &tiden, &tchrn, &tiden, + &tchrp, &tiden, &tiden, &tiden, &tiden, &tiden, &tiden, &tiden, + &tchrx, &tiden, &tiden, &token, &token, &token, &tpowe, &tchr_, + &token, &tchra, &tchrb, &tchrc, &tchrd, &tchre, &tchrf, &tchrg, + &tiden, &tchri, &tiden, &tiden, &tchrl, &tchrm, &tchrn, &tchro, + &tchrp, &tiden, &tchrr, &tchrs, &tchrt, &tchru, &tchrv, &tchrw, + &tchrx, &tiden, &tiden, &token, &torrr, &token, &token, &tille, + &tille, &tille, &tille, &tille, &tille, &tille, &tille, &tille, + &tille, &tille, &tille, &tille, &tille, &tille, &tille, &tille, + &tille, &tille, &tille, &tille, &tille, &tille, &tille, &tille, + &tille, &tille, &tille, &tille, &tille, &tille, &tille, &tille, + &tille, &tille, &tille, &tille, &tille, &tille, &tille, &tille, + &tille, &tille, &tille, &tille, &tille, &tille, &tille, &tille, + &tille, &tille, &tille, &tille, &tille, &tille, &tille, &tille, + &tille, &tille, &tille, &tille, &tille, &tille, &tille, &tille, + &tille, &tille, &tille, &tille, &tille, &tille, &tille, &tille, + &tille, &tille, &tille, &tille, &tille, &tille, &tille, &tille, + &tille, &tille, &tille, &tille, &tille, &tille, &tille, &tille, + &tille, &tille, &tille, &tille, &tille, &tille, &tille, &tille, + &tille, &tille, &tille, &tille, &tille, &tille, &tille, &tille, + &tille, &tille, &tille, &tille, &tille, &tille, &tille, &tille, + &tille, &tille, &tille, &tille, &tille, &tille, &tille, &tille, + &tille, &tille, &tille, &tille, &tille, &tille, &tille, &tille +}; + +short lookahead() { +} + +short lookahead_noeol() { +} + +static void CPrep_StringConCat(Boolean flag) { +} + +short lex() { +} + +short plex() { +} + +short lexidentifier() { +} diff --git a/compiler_and_linker/FrontEnd/C/CScope.c b/compiler_and_linker/FrontEnd/C/CScope.c new file mode 100644 index 0000000..7423c07 --- /dev/null +++ b/compiler_and_linker/FrontEnd/C/CScope.c @@ -0,0 +1,2690 @@ +#include "compiler.h" +#include "compiler/CError.h" +#include "compiler/enode.h" +#include "compiler/objects.h" +#include "compiler/scopes.h" +#include "compiler/templates.h" +#include "compiler/types.h" + +static Boolean cscope_isambig; +static UInt8 cscope_lookuptype; +static SInt32 cscope_foundclassoffset; +static TemplClass *cscope_foundtemplate; +static TypeClass *cscope_foundclass; +static HashNameNode *cscope_name; +static TypeClass *cscope_mostderived; +Boolean cscope_is_member_func; +Object *cscope_currentfunc; +TypeClass *cscope_currentclass; +NameSpace *cscope_current; +NameSpace *cscope_root; + +void CScope_Setup() { + cscope_current = cscope_root = CScope_NewHashNameSpace(0); + cscope_currentclass = NULL; + cscope_currentfunc = NULL; + cscope_is_member_func = 0; +} + +void CScope_Cleanup() { +} + +void CScope_GetScope(CScopeSave *save) { + save->current = cscope_current; + save->currentclass = cscope_currentclass; + save->currentfunc = cscope_currentfunc; + save->is_member_func = cscope_is_member_func; +} + +void CScope_SetNameSpaceScope(NameSpace *nspace, CScopeSave *save) { + save->current = cscope_current; + save->currentclass = cscope_currentclass; + save->currentfunc = cscope_currentfunc; + save->is_member_func = cscope_is_member_func; + + cscope_current = nspace; + cscope_currentclass = nspace->theclass; + cscope_currentfunc = NULL; + cscope_is_member_func = 0; +} + +void CScope_SetClassScope(TypeClass *cls, CScopeSave *save) { + save->current = cscope_current; + save->currentclass = cscope_currentclass; + save->currentfunc = cscope_currentfunc; + save->is_member_func = cscope_is_member_func; + + cscope_current = cls->nspace; + cscope_currentclass = cls; + cscope_currentfunc = NULL; + cscope_is_member_func = 0; +} + +void CScope_SetClassDefScope(TypeClass *cls, CScopeSave *save) { + save->current = cscope_current; + save->currentclass = cscope_currentclass; + save->currentfunc = cscope_currentfunc; + save->is_member_func = cscope_is_member_func; + + cscope_current = cls->nspace; + cscope_currentclass = cls; +} + +void CScope_SetFunctionScope(Object *function, CScopeSave *save) { + save->current = cscope_current; + save->currentclass = cscope_currentclass; + save->currentfunc = cscope_currentfunc; + save->is_member_func = cscope_is_member_func; + + cscope_currentfunc = function; + cscope_currentclass = NULL; + cscope_is_member_func = 0; + + if (TYPE_FUNC(function->type)->flags & FUNC_FLAGS_METHOD) { + cscope_currentclass = TYPE_METHOD(function->type)->theclass; + cscope_current = cscope_currentclass->nspace; + cscope_is_member_func = TYPE_METHOD(function->type)->x26 == 0; + } else { + cscope_current = function->nspace; + } +} + +void CScope_SetMethodScope(Object *function, TypeClass *cls, Boolean unknownFlag, CScopeSave *save) { + save->current = cscope_current; + save->currentclass = cscope_currentclass; + save->currentfunc = cscope_currentfunc; + save->is_member_func = cscope_is_member_func; + + cscope_currentfunc = function; + cscope_currentclass = cls; + cscope_current = cls->nspace; + cscope_is_member_func = !unknownFlag; +} + +void CScope_RestoreScope(CScopeSave *saved) { + cscope_current = saved->current; + cscope_currentclass = saved->currentclass; + cscope_currentfunc = saved->currentfunc; + cscope_is_member_func = saved->is_member_func; +} + +static Boolean CScope_ObjectIsFunction(Object *obj) { + return obj->otype == OT_OBJECT && obj->type->type == TYPEFUNC; +} + +Boolean CScope_IsEmptySymTable() { + NameSpaceObjectList *scan; + NameSpaceName *nsname; + int i; + +#line 232 + CError_ASSERT(cscope_root->is_hash); + + i = 0; + do { + for (nsname = cscope_root->data.hash[i]; nsname; nsname = nsname->next) { + for (scan = &nsname->first; scan; scan = scan->next) { + if (scan->object->otype != OT_OBJECT || !CParser_IsPublicRuntimeObject(OBJECT(scan->object))) + return 0; + } + } + } while (++i < 1024); + + return 1; +} + +Boolean CScope_IsInLocalNameSpace(NameSpace *nspace) { + while (nspace) { + if (!nspace->is_global && !nspace->is_templ) + return 1; + nspace = nspace->parent; + } + return 0; +} + +static void CScope_AppendNameSpaceName(NameSpaceName *nsn) { + if (nsn->next) + CScope_AppendNameSpaceName(nsn->next); + if (nsn->name) { + AppendGListName(&name_mangle_list, nsn->name->name); + AppendGListName(&name_mangle_list, "::"); + } +} + +static void CScope_AmbigNameError(NameSpace *nspace1, NameSpace *nspace2, HashNameNode *name) { + if (name && nspace1 != nspace2) { + CError_Error(319, CError_GetNameString(nspace1, name), CError_GetNameString(nspace2, name)); + } else { + CError_Error(188, nspace2); + } +} + +NameSpaceObjectList *CScope_FindName(NameSpace *nspace, HashNameNode *name) { + NameSpaceName *scan; + + for (scan = nspace->tparams; scan; scan = scan->next) { + if (scan->name == name) + return &scan->first; + } + + if (!nspace->is_hash) + scan = nspace->data.list; + else + scan = nspace->data.hash[name->hashval & 1023]; + + for (; scan; scan = scan->next) { + if (scan->name == name) + return &scan->first; + } + + return NULL; +} + +static NameSpaceObjectList *CScope_FindQualName(NameSpace *nspace, HashNameNode *name) { + NameSpaceName *scan; + + if (!nspace->is_hash) + scan = nspace->data.list; + else + scan = nspace->data.hash[name->hashval & 1023]; + + for (; scan; scan = scan->next) { + if (scan->name == name) + return &scan->first; + } + + return NULL; +} + +NameSpaceName *CScope_FindNameSpaceName(NameSpace *nspace, HashNameNode *name) { + NameSpaceName *scan; + + for (scan = nspace->tparams; scan; scan = scan->next) { + if (scan->name == name) + return scan; + } + + if (!nspace->is_hash) + scan = nspace->data.list; + else + scan = nspace->data.hash[name->hashval & 1023]; + + for (; scan; scan = scan->next) { + if (scan->name == name) + return scan; + } + + return NULL; +} + +NameSpaceObjectList *CScope_InsertName(NameSpace *nspace, HashNameNode *name) { + NameSpaceName **nsnptr; + NameSpaceName *nsname; + if (nspace->is_global) + nsname = galloc(sizeof(NameSpaceName)); + else + nsname = lalloc(sizeof(NameSpaceName)); + + nsname->name = name; + nsname->first.next = NULL; + nsname->first.object = NULL; + if (nspace->is_hash) { + nsnptr = &nspace->data.hash[name->hashval & 0x3FF]; + nsname->next = *nsnptr; + *nsnptr = nsname; + } else { + nsname->next = nspace->data.list; + nspace->data.list = nsname; + } + nspace->names++; + + return &nsname->first; +} + +static NameSpaceObjectList *CScope_AppendName(NameSpace *nspace, HashNameNode *name) { + NameSpaceName *nsname; + NameSpaceName *scan; +#line 387 + CError_ASSERT(!nspace->is_hash); + + if (nspace->is_global) + nsname = galloc(sizeof(NameSpaceName)); + else + nsname = lalloc(sizeof(NameSpaceName)); + + nsname->next = NULL; + nsname->name = name; + nsname->first.next = NULL; + nsname->first.object = NULL; + if (nspace->data.list) { + scan = nspace->data.list; + while (scan->next) + scan = scan->next; + scan->next = nsname; + } else { + nspace->data.list = nsname; + } + nspace->names++; + + return &nsname->first; +} + +static NameSpaceList *CScope_AddNameSpaceToList(NameSpaceList *list, NameSpace *nspace) { + NameSpaceList *scan; + NameSpaceList *newlist; + ClassList *clslist; + + for (scan = list; scan; scan = scan->next) { + if (scan->nspace == nspace) + return list; + } + + newlist = lalloc(sizeof(NameSpaceList)); + newlist->next = list; + newlist->nspace = nspace; + list = newlist; + + if (nspace->theclass) { + list = CScope_AddNameSpaceToList(list, nspace->parent); + for (clslist = nspace->theclass->bases; clslist; clslist = clslist->next) + list = CScope_AddNameSpaceToList(list, clslist->base->nspace); + } + + return list; +} + +static NameSpaceList *CScope_BuildTypeAssociatedNameSpaceList(NameSpaceList *list, Type *type) { + FuncArg *arg; + +restart: + switch (type->type) { + case TYPEVOID: + case TYPEINT: + case TYPEFLOAT: + case TYPESTRUCT: + case TYPEBITFIELD: + case TYPETEMPLATE: + case TYPETEMPLDEPEXPR: + break; + case TYPEPOINTER: + case TYPEARRAY: + type = TYPE_POINTER(type)->target; + goto restart; + case TYPEENUM: + list = CScope_AddNameSpaceToList(list, TYPE_ENUM(type)->nspace); + break; + case TYPEFUNC: + for (arg = TYPE_FUNC(type)->args; arg; arg = arg->next) { + if (arg->type) + list = CScope_BuildTypeAssociatedNameSpaceList(list, arg->type); + } + type = TYPE_FUNC(type)->functype; + goto restart; + case TYPEMEMBERPOINTER: + list = CScope_BuildTypeAssociatedNameSpaceList(list, TYPE_MEMBER_POINTER(type)->ty1); + type = TYPE_MEMBER_POINTER(type)->ty2; + if (type->type != TYPECLASS) + break; + case TYPECLASS: + list = CScope_AddNameSpaceToList(list, TYPE_CLASS(type)->nspace); + break; + default: +#line 494 + CError_FATAL(); + } + + return list; +} + +static NameSpaceList *CScope_BuildAssociatedNameSpaceList(ENodeList *enodeList) { + // not 100% sure about the type for this but i think it's right?? + NameSpaceList *nslist = NULL; + while (enodeList) { + nslist = CScope_BuildTypeAssociatedNameSpaceList(nslist, enodeList->node->rtype); + enodeList = enodeList->next; + } + return nslist; +} + +static Boolean CScope_IsSameObject(Object *a, Object *b) { + if (a == b) + return 1; + return (a->nspace == b->nspace) && (a->name == b->name) && is_typesame(a->type, b->type); +} + +NameSpaceObjectList *CScope_ArgumentDependentNameLookup(NameSpaceObjectList *list, HashNameNode *name, ENodeList *argNodes, Boolean flag) { + NameSpaceList *scan; + NameSpaceObjectList *iscan; + NameSpaceObjectList *iiscan; + NameSpaceObjectList *newlist; + + for (scan = CScope_BuildAssociatedNameSpaceList(argNodes); scan; scan = scan->next) { + for (iscan = CScope_FindQualName(scan->nspace, name); iscan; iscan = iscan->next) { + if (iscan->object->otype != OT_OBJECT) + continue; + if (OBJECT(iscan->object)->type->type != TYPEFUNC) + continue; + if (flag && (TYPE_FUNC(OBJECT(iscan->object)->type)->flags & FUNC_FLAGS_METHOD)) + continue; + + for (iiscan = list; iiscan; iiscan = iiscan->next) { + if (iiscan->object->otype == OT_OBJECT && CScope_IsSameObject(OBJECT(iiscan->object), OBJECT(iscan->object))) + break; + } + + if (!iiscan) { + newlist = lalloc(sizeof(NameSpaceObjectList)); + newlist->object = iscan->object; + newlist->next = list; + list = newlist; + } + } + } + + return list; +} + +NameSpace *CScope_NewHashNameSpace(HashNameNode *name) { + NameSpace *nspace; + void *buffer; + + buffer = galloc(0x400 * sizeof(void *)); + memclrw(buffer, 0x400 * sizeof(void *)); + nspace = galloc(sizeof(NameSpace)); + memclrw(nspace, sizeof(NameSpace)); + nspace->name = name; + nspace->data.hash = buffer; + nspace->is_hash = 1; + nspace->is_global = 1; + return nspace; +} + +NameSpace *CScope_NewListNameSpace(HashNameNode *name, Boolean is_global) { + NameSpace *nspace; + if (is_global) { + nspace = galloc(sizeof(NameSpace)); + memclrw(nspace, sizeof(NameSpace)); + } else { + nspace = lalloc(sizeof(NameSpace)); + memclrw(nspace, sizeof(NameSpace)); + } + nspace->name = name; + nspace->is_hash = 0; + nspace->is_global = is_global; + return nspace; +} + +NameSpace *CScope_FindNonClassNonFunctionNS(NameSpace *nspace) { + while (nspace) { + if (!nspace->theclass && !nspace->is_templ) + return nspace; + nspace = nspace->parent; + } + return cscope_root; +} + +NameSpace *CScope_FindGlobalNS(NameSpace *nspace) { + while (nspace) { + if (nspace->name && !nspace->theclass && nspace->is_global) + return nspace; + nspace = nspace->parent; + } + return cscope_root; +} + +Boolean CScope_IsStdNameSpace(NameSpace *nspace) { + return nspace && !nspace->theclass && (nspace->parent == cscope_root) && nspace->name && !strcmp(nspace->name->name, "std"); +} + +Boolean CScope_IsEmptyNameSpace(NameSpace *nspace) { +#line 664 + CError_ASSERT(!nspace->is_hash); + return !nspace->data.list; +} + +void CScope_MergeNameSpace(NameSpace *dst, NameSpace *src) { + NameSpaceName *nsname; + +#line 678 + CError_ASSERT(!dst->is_hash && !src->is_hash); + + if ((nsname = dst->data.list)) { + while (nsname->next) + nsname = nsname->next; + nsname->next = src->data.list; + } else { + dst->data.list = src->data.list; + } +} + +void CScope_AddObject(NameSpace *nspace, HashNameNode *name, ObjBase *obj) { + NameSpaceObjectList *objlist; + NameSpaceObjectList *newlist; + + objlist = CScope_FindQualName(nspace, name); + if (objlist) { + if (nspace->is_global) + newlist = galloc(sizeof(NameSpaceObjectList)); + else + newlist = lalloc(sizeof(NameSpaceObjectList)); + + if (obj->otype == OT_NAMESPACE || objlist->object->otype == OT_NAMESPACE) { + CError_Error(322/*, objlist->object*/); + return; + } + + if (obj->otype == OT_TYPETAG) { + do { + if (objlist->object->otype == OT_TYPETAG) { + CError_Error(322/*, objlist->object*/); + return; + } + + if (copts.cplusplus && objlist->object->otype == OT_TYPE && !is_typesame(OBJ_TYPE_TAG(obj)->type, OBJ_TYPE(objlist->object)->type)) { + CError_Error(332); + return; + } + + if (!objlist->next) { + objlist->next = newlist; + newlist->next = NULL; + newlist->object = obj; + return; + } + objlist = objlist->next; + } while (1); + } + + if (objlist->object->otype == OT_TYPETAG) { + if (copts.cplusplus && obj->otype == OT_TYPE && !is_typesame(OBJ_TYPE(obj)->type, OBJ_TYPE_TAG(objlist->object)->type)) { + CError_Error(332); + return; + } + +#line 739 + CError_ASSERT(!objlist->next); + + newlist->object = objlist->object; + newlist->next = NULL; + objlist->object = obj; + objlist->next = newlist; + return; + } + + if (!copts.cplusplus || !CScope_ObjectIsFunction(OBJECT(obj))) { + CError_Error(322); + return; + } + + do { + if (objlist->object->otype == OT_TYPETAG) { + objlist->next = galloc(sizeof(NameSpaceObjectList)); + objlist->next->next = NULL; + objlist->next->object = objlist->object; + objlist->object = obj; + return; + } + + if (!CScope_ObjectIsFunction(OBJECT(objlist->object))) { + CError_Error(322); + return; + } + + if (!objlist->next) { + objlist->next = galloc(sizeof(NameSpaceObjectList)); + objlist->next->next = NULL; + objlist->next->object = obj; + return; + } + + objlist = objlist->next; + } while (1); + } else if (nspace->theclass && TYPE_CLASS(nspace->theclass)->flags & CLASS_FLAGS_900) { + CScope_AppendName(nspace, name)->object = obj; + } else { + CScope_InsertName(nspace, name)->object = obj; + } +} + +void CScope_AddGlobalObject(Object *obj) { + obj->nspace = cscope_root; + CScope_AddObject(cscope_root, obj->name, OBJ_BASE(obj)); +} + +NameSpaceLookupList *CScope_BuildNameSpaceLookupList(NameSpace *nspace) { + NameSpaceLookupList *lookup; + NameSpaceList list; + NameSpaceList *current; + NameSpaceList *current2; + NameSpaceList *current3; + NameSpaceList *newlist; + NameSpaceLookupList *currentL; + NameSpace *currentNS; + + lookup = lalloc(sizeof(NameSpaceLookupList)); + memclrw(lookup, sizeof(NameSpaceLookupList)); + lookup->nspace = nspace; + + if (nspace->parent) + lookup->next = CScope_BuildNameSpaceLookupList(nspace->parent); + + if (nspace->usings) { + list.nspace = nspace; + list.next = NULL; + for (current2 = &list; current2; current2 = current2->next) { + for (current = current2->nspace->usings; current; current = current->next) { + for (current3 = &list; current3; current3 = current3->next) { + if (current3->nspace == current->nspace) + break; + } + if (!current3) { + newlist = lalloc(sizeof(NameSpaceList)); + newlist->nspace = current->nspace; + newlist->next = current2->next; + current2->next = newlist; + } + } + } + + for (current = list.next; current; current = current->next) { + for (currentL = lookup; currentL; currentL = currentL->next) { + for (currentNS = current->nspace; currentNS; currentNS = currentNS->parent) { + if (currentL->nspace == currentNS) + goto foundIt; + } + } +#line 853 + CError_FATAL(); + foundIt: + for (current2 = currentL->namespaces; current2; current2 = current2->next) { + if (current2->nspace == current->nspace) + break; + } + if (!current2) { + newlist = lalloc(sizeof(NameSpaceList)); + newlist->nspace = current->nspace; + newlist->next = currentL->namespaces; + currentL->namespaces = newlist; + } + } + } + + return lookup; +} + +static Boolean CScope_IsInLookup(NameSpaceLookupList *list, NameSpace *nspace) { + NameSpaceLookupList *scan; + NameSpaceList *iscan; + + for (scan = list; scan; scan = scan->next) { + if (scan->nspace == nspace) + return 1; + for (iscan = scan->namespaces; iscan; iscan = iscan->next) { + if (iscan->nspace == nspace) + return 1; + } + } + + return 0; +} + +static NameSpaceLookupList *CScope_BuildNameSpaceMemberLookupList(NameSpace *nspace) { + NameSpaceLookupList list; + NameSpaceLookupList *current; + NameSpaceList *scan; + NameSpaceList *oscan; + NameSpaceList *newlist; + + list.nspace = nspace; + list.namespaces = NULL; + list.next = NULL; + + for (current = &list; current; current = current->next) { + if (current->nspace) { + for (scan = current->nspace->usings; scan; scan = scan->next) { + if (!CScope_IsInLookup(&list, scan->nspace)) { + if (!current->next) { + current->next = lalloc(sizeof(NameSpaceLookupList)); + current->next->nspace = NULL; + current->next->namespaces = NULL; + current->next->next = NULL; + } + newlist = lalloc(sizeof(NameSpaceList)); + newlist->nspace = scan->nspace; + newlist->next = current->next->namespaces; + current->next->namespaces = newlist; + } + } + } + + for (oscan = current->namespaces; oscan; oscan = oscan->next) { + for (scan = oscan->nspace->usings; scan; scan = scan->next) { + if (!CScope_IsInLookup(&list, scan->nspace)) { + if (!current->next) { + current->next = lalloc(sizeof(NameSpaceLookupList)); + current->next->nspace = NULL; + current->next->namespaces = NULL; + current->next->next = NULL; + } + newlist = lalloc(sizeof(NameSpaceList)); + newlist->nspace = scan->nspace; + newlist->next = current->next->namespaces; + current->next->namespaces = newlist; + } + } + } + } + + return list.next; +} + +static NameSpaceObjectList *CScope_CopyNameSpaceObjectList(NameSpaceObjectList *list) { + NameSpaceObjectList *first, *current; + + first = current = lalloc(sizeof(NameSpaceObjectList)); + do { + current->object = list->object; + list = list->next; + if (!list) { + current->next = NULL; + break; + } else { + current->next = lalloc(sizeof(NameSpaceObjectList)); + current = current->next; + } + } while (1); + + return first; +} + +static NameSpace *CScope_ExtractNameSpace(NameSpaceObjectList *list, Boolean *fail) { + Type *type; + +restart: + if (!list) + return NULL; + + switch (list->object->otype) { + case OT_TYPE: + type = OBJ_TYPE(list->object)->type; + break; + case OT_TYPETAG: + type = OBJ_TYPE_TAG(list->object)->type; + break; + case OT_NAMESPACE: + return OBJ_NAMESPACE(list->object)->nspace; + default: +#line 1052 + CError_FATAL(); + break; + case OT_ENUMCONST: + case OT_MEMBERVAR: + case OT_OBJECT: + list = list->next; + goto restart; + } + + if (type->type != TYPECLASS) { + if (type->type == TYPETEMPLATE) + return NULL; + CError_Error(320); + if (fail) + *fail = 1; + return NULL; + } else { + return TYPE_CLASS(type)->nspace; + } +} + +static BClassList *CScope_RecFindClassMember(CScopeParseResult *result, TypeClass *tclass, SInt32 offset) { + // does not match, r24 and r23 are swapped at the end x.x + Boolean fail; + NameSpace *nspace; + NameSpaceObjectList *list; + ClassList *base; + TypeClass *bestClass; + BClassList *bestBase, *n; + BClassList *candidate; + SInt32 thisoffset; + BClassList *newlist; + + if ((list = CScope_FindName(tclass->nspace, cscope_name))) { + if (cscope_foundclass) { + if (CClass_ClassDominates(cscope_foundclass, tclass)) + return NULL; + if (CClass_ClassDominates(tclass, cscope_foundclass)) + cscope_foundclass = NULL; + } + + switch (cscope_lookuptype) { + case 2: + fail = 0; + if ((nspace = CScope_ExtractNameSpace(list, &fail))) { + if (cscope_foundclass) { + if (cscope_foundclass != tclass) { + CScope_AmbigNameError(cscope_foundclass->nspace, tclass->nspace, cscope_name); + return NULL; + } + if (cscope_foundclassoffset != offset) + cscope_isambig = 1; + return NULL; + } + + cscope_foundclass = tclass; + cscope_foundclassoffset = offset; + result->nspace_0 = nspace; + + newlist = lalloc(sizeof(BClassList)); + newlist->next = NULL; + newlist->type = (Type *) tclass; + return newlist; + } + + if (fail) + return NULL; + break; + case 0: + if (cscope_foundclass) { + if ( + list->object->otype == OT_TYPETAG + && result->nsol_14->object->otype == OT_TYPETAG + && OBJ_TYPE_TAG(list->object)->type->type == TYPECLASS + && OBJ_TYPE_TAG(result->nsol_14->object)->type->type == TYPECLASS + && (TYPE_CLASS(OBJ_TYPE_TAG(list->object)->type)->flags & CLASS_FLAGS_800) + && (TYPE_CLASS(OBJ_TYPE_TAG(result->nsol_14->object)->type)->flags & CLASS_FLAGS_800) + && TEMPL_CLASS_INST(OBJ_TYPE_TAG(list->object)->type)->templ == TEMPL_CLASS_INST(OBJ_TYPE_TAG(result->nsol_14->object)->type)->templ + ) { + cscope_foundtemplate = TEMPL_CLASS_INST(OBJ_TYPE_TAG(result->nsol_14->object)->type)->templ; + } else { + if (cscope_foundclass != tclass) { + CScope_AmbigNameError(cscope_foundclass->nspace, tclass->nspace, cscope_name); + return NULL; + } + if (cscope_foundclassoffset != offset) { + cscope_isambig = 1; + return NULL; + } + } + } + + cscope_foundclass = tclass; + cscope_foundclassoffset = offset; + result->nsol_14 = list; + newlist = lalloc(sizeof(BClassList)); + newlist->next = NULL; + newlist->type = (Type *) tclass; + return newlist; + case 1: + for (; list; list = list->next) { + if (list->object->otype == OT_TYPETAG) { + if (cscope_foundclass) { + if (cscope_foundclass != tclass) { + CScope_AmbigNameError(cscope_foundclass->nspace, tclass->nspace, cscope_name); + return NULL; + } + if (cscope_foundclassoffset != offset) + cscope_isambig = 1; + return NULL; + } + + cscope_foundclass = tclass; + cscope_foundclassoffset = offset; + result->x8 = OBJ_TYPE_TAG(list->object)->type; + newlist = lalloc(sizeof(BClassList)); + newlist->next = NULL; + newlist->type = (Type *) tclass; + return newlist; + } + } + break; + default: +#line 1202 + CError_FATAL(); + } + } + + for (base = tclass->bases, bestBase = NULL; base; base = base->next) { + thisoffset = base->is_virtual ? CClass_VirtualBaseOffset(cscope_mostderived, base->base) : offset + base->offset; + if ((candidate = CScope_RecFindClassMember(result, base->base, thisoffset))) { + n = lalloc(sizeof(BClassList)); + n->next = candidate; + n->type = (Type *) tclass; + if (bestBase && bestClass == cscope_foundclass) { + if (CClass_IsMoreAccessiblePath(n, bestBase)) + bestBase = n; + } else { + bestClass = cscope_foundclass; + bestBase = n; + } + } + } + + return bestBase; +} + +static Boolean CScope_FindClassMember(CScopeParseResult *result, NameSpace *nspace, HashNameNode *name, UInt8 lookupType) { + BClassList *bcl; + BClassList *scan; + + cscope_mostderived = nspace->theclass; + cscope_foundclass = NULL; + cscope_foundtemplate = NULL; + cscope_name = name; + cscope_lookuptype = lookupType; + cscope_isambig = 0; + + if ((bcl = CScope_RecFindClassMember(result, cscope_mostderived, 0))) { + if (cscope_foundtemplate) + return 1; + + if ((scan = result->bcl_18)) { + while (scan->next) + scan = scan->next; + if (TYPE_CLASS(scan->type) != cscope_mostderived) + scan->next = bcl; + else + scan->next = bcl->next; + } else { + result->bcl_18 = bcl; + } + + if (cscope_isambig) + result->isambig = 1; + return 1; + } else { + return 0; + } +} + +static BClassList *CScope_GetAccessPathRec(TypeClass *src, TypeClass *dest, SInt32 offset) { + BClassList *list; + BClassList *best; + ClassList *base; + + if (src == dest) { + if (cscope_foundclass && cscope_foundclassoffset != offset) + CError_Error(188); + + list = lalloc(sizeof(BClassList)); + list->next = NULL; + list->type = (Type *) src; + cscope_foundclass = src; + cscope_foundclassoffset = offset; + return list; + } + + for (base = src->bases, best = NULL; base; base = base->next) { + if ((list = CScope_GetAccessPathRec(base->base, dest, base->is_virtual ? CClass_VirtualBaseOffset(cscope_mostderived, base->base) : (offset + base->offset)))) + best = list; + } + + if (best) { + list = lalloc(sizeof(BClassList)); + list->next = best; + list->type = (Type *) src; + return list; + } + + return NULL; +} + +static BClassList *CScope_GetAccessPath(TypeClass *src, TypeClass *dest) { + cscope_mostderived = src; + cscope_foundclass = NULL; + return CScope_GetAccessPathRec(src, dest, 0); +} + +static NameSpace *CScope_FindLookupNameSpace(CScopeNSIterator *iterator, NameSpaceLookupList *lookup, HashNameNode *name) { + NameSpaceObjectList *list; + NameSpaceList *scan; + NameSpace *retnspace = NULL; + NameSpace *candidate; + Boolean fail = 0; + + if (lookup->nspace->theclass) { + if (CScope_FindClassMember(iterator->result, lookup->nspace, name, 2)) { + retnspace = iterator->result->nspace_0; + iterator->result->nspace_0 = NULL; + return retnspace; + } else { + return NULL; + } + } + + if ((list = CScope_FindName(lookup->nspace, name))) { + fail = 0; + retnspace = CScope_ExtractNameSpace(list, &fail); + if (fail) + return NULL; + } + + for (scan = lookup->namespaces; scan; scan = scan->next) { + fail = 0; + if ((list = CScope_FindName(scan->nspace, name)) && (candidate = CScope_ExtractNameSpace(list, &fail))) { + if (retnspace) { + if (retnspace != candidate) + CScope_AmbigNameError(retnspace, candidate, NULL); + } else { + retnspace = candidate; + } + } + if (fail) + return NULL; + } + + return retnspace; +} + +static NameSpaceObjectList *CScope_FindLookupName(NameSpaceLookupList *list, HashNameNode *name, NameSpace **foundnspace) { + NameSpaceName *scanname; + NameSpaceObjectList *tmpOL; + NameSpaceObjectList *r31; + NameSpaceObjectList *r30; + NameSpaceList *r29; + NameSpace *r28; + Boolean r27; + NameSpaceObjectList *r6; + NameSpaceObjectList *scanOL; + NameSpaceObjectList *newlist; + + if (list->nspace) { + for (scanname = list->nspace->tparams; scanname; scanname = scanname->next) { + if (scanname->name == name) + return &scanname->first; + } + + if ((tmpOL = CScope_FindName(list->nspace, name))) { + r31 = tmpOL; + r28 = list->nspace; + } else { + r31 = NULL; + r28 = NULL; + } + } else { + r31 = NULL; + r28 = NULL; + } + + r27 = 0; + for (r29 = list->namespaces; r29; r29 = r29->next) { + if ((tmpOL = CScope_FindName(r29->nspace, name))) { + if (r31) { + for (r30 = tmpOL; r30; r30 = r30->next) { + for (r6 = r31; r6; r6 = r6->next) { + if (r6->object == r30->object) + break; + if (r6->object->otype == r30->object->otype) { + switch (r6->object->otype) { + case OT_TYPE: + if ((OBJ_TYPE(r6->object)->type == OBJ_TYPE(r30->object)->type) && (OBJ_TYPE(r6->object)->unk6 == OBJ_TYPE(r30->object)->unk6)) + goto break1; + break; + case OT_TYPETAG: + if (OBJ_TYPE_TAG(r6->object)->type == OBJ_TYPE_TAG(r30->object)->type) + goto break1; + break; + case OT_ENUMCONST: + if (OBJ_ENUM_CONST(r6->object)->type == OBJ_ENUM_CONST(r30->object)->type) + goto break1; + break; + case OT_OBJECT: + if (OBJECT(r6->object)->datatype == DALIAS) { + if (OBJECT(r30->object)->datatype == DALIAS) { + if (OBJECT(r6->object)->u.alias.object == OBJECT(r30->object)->u.alias.object) + goto break1; + } else { + if (OBJECT(r6->object)->u.alias.object == OBJECT(r30->object)) + goto break1; + } + } else { + if ((OBJECT(r30->object)->datatype == DALIAS) && OBJECT(r6->object) == OBJECT(r30->object)->u.alias.object) + goto break1; + } + break; + } + } + } + break1: + if (!r6) { + if (!r27) { + r31 = CScope_CopyNameSpaceObjectList(r31); + r27 = 1; + } + if (CScope_ObjectIsFunction(OBJECT(r30->object))) { + for (scanOL = r31; scanOL; scanOL = scanOL->next) { + if (!CScope_ObjectIsFunction(OBJECT(scanOL->object))) { + if (scanOL->object->otype != OT_TYPETAG) { + CScope_AmbigNameError(r28, r29->nspace, name); + break; + } + } + } + } else if (r30->object->otype == OT_TYPETAG) { + for (scanOL = r31; scanOL; scanOL = scanOL->next) { + if (scanOL->object->otype == OT_TYPETAG) { + CScope_AmbigNameError(r28, r29->nspace, name); + break; + } + } + } else { + for (scanOL = r31; scanOL; scanOL = scanOL->next) { + if (scanOL->object->otype != OT_TYPETAG) { + CScope_AmbigNameError(r28, r29->nspace, name); + break; + } + } + } + + if (!scanOL) { + newlist = lalloc(sizeof(NameSpaceObjectList)); + newlist->object = r30->object; + newlist->next = r31; + r31 = newlist; + } + } + } + } else { + r31 = tmpOL; + r28 = r29->nspace; + } + } + } + + if (foundnspace) + *foundnspace = r28; + return r31; +} + +static NameSpaceObjectList *CScope_NSIteratorFind(CScopeNSIterator *iterator, HashNameNode *name) { + NameSpaceObjectList *list; + + if (iterator->lookup) { + if (iterator->lookup->namespaces) + return CScope_FindLookupName(iterator->lookup, name, NULL); + if (iterator->lookup->nspace->theclass) { + if (CScope_FindClassMember(iterator->result, iterator->lookup->nspace, name, 0)) { + list = iterator->result->nsol_14; + iterator->result->nsol_14 = NULL; + return list; + } else { + return NULL; + } + } + + if ((list = CScope_FindName(iterator->lookup->nspace, name))) + return list; + } else { + if (iterator->nspace->theclass) { + if (CScope_FindClassMember(iterator->result, iterator->nspace, name, 0)) { + list = iterator->result->nsol_14; + iterator->result->nsol_14 = NULL; + return list; + } else { + return NULL; + } + } + + if ((list = CScope_FindName(iterator->nspace, name))) + return list; + } + + return NULL; +} + +static NameSpaceObjectList *CScope_NSIteratorNonClassFind(CScopeNSIterator *iterator, HashNameNode *name) { + NameSpaceObjectList *list; + + if (iterator->lookup) { + if (iterator->lookup->namespaces) + return CScope_FindLookupName(iterator->lookup, name, NULL); + if (iterator->lookup->nspace->theclass) + return NULL; + if ((list = CScope_FindName(iterator->lookup->nspace, name))) + return list; + } else { + if (iterator->nspace->theclass) + return NULL; + if ((list = CScope_FindName(iterator->nspace, name))) + return list; + } + + return NULL; +} + +static NameSpace *CScope_NSIteratorFindNameSpace(CScopeNSIterator *iterator, HashNameNode *name) { + NameSpace *nspace; + NameSpaceObjectList *list; + + if (iterator->lookup) { + if (iterator->lookup->namespaces) + return CScope_FindLookupNameSpace(iterator, iterator->lookup, name); + if (iterator->lookup->nspace->theclass) { + if (CScope_FindClassMember(iterator->result, iterator->lookup->nspace, name, 2)) { + nspace = iterator->result->nspace_0; + iterator->result->nspace_0 = NULL; + return nspace; + } else { + return NULL; + } + } + + if ((list = CScope_FindName(iterator->lookup->nspace, name))) + return CScope_ExtractNameSpace(list, NULL); + } else { + if (iterator->nspace->theclass) { + if (CScope_FindClassMember(iterator->result, iterator->nspace, name, 2)) { + nspace = iterator->result->nspace_0; + iterator->result->nspace_0 = NULL; + return nspace; + } else { + return NULL; + } + } + + if ((list = CScope_FindName(iterator->nspace, name))) + return CScope_ExtractNameSpace(list, NULL); + } + + return NULL; +} + +static Boolean CScope_SetupParseNameResult(CScopeParseResult *result, NameSpaceObjectList *list, HashNameNode *name) { + if (!list->next || list->next->object->otype == OT_TYPETAG) { + switch (list->object->otype) { + case OT_NAMESPACE: + CError_Error(321); + return 0; + case OT_TYPE: + result->x8 = OBJ_TYPE(list->object)->type; + result->xC = OBJ_TYPE(list->object)->unk6; + result->obj_10 = list->object; + result->name_4 = name; + result->x20 = 1; + break; + case OT_TYPETAG: + result->x8 = OBJ_TYPE_TAG(list->object)->type; + result->xC = NULL; + result->obj_10 = list->object; + result->name_4 = name; + result->x20 = 1; + break; + default: + result->obj_10 = list->object; + } + } else { + result->nsol_14 = list; + } + + return 1; +} + +Boolean CScope_FindQualifiedClassMember(CScopeParseResult *result, TypeClass *tclass, HashNameNode *name) { + NameSpaceObjectList *list; + + memclrw(result, sizeof(CScopeParseResult)); + CDecl_CompleteType((Type *) tclass); + + if (CScope_FindClassMember(result, tclass->nspace, name, 0)) { + list = result->nsol_14; +#line 1780 + CError_ASSERT(list); + result->nsol_14 = NULL; + + if (CScope_SetupParseNameResult(result, list, name) && !result->x8) + return 1; + else + CError_Error(340, name->name); + } + + return 0; +} + +static NameSpace *CScope_FindQualifiedNameSpace(CScopeParseResult *result, NameSpace *nspace, HashNameNode *name) { + NameSpaceObjectList *list; + NameSpace *cand; + NameSpace *found; + NameSpaceList *scan; + NameSpaceLookupList *lookup; + Boolean fail = 0; + + if (nspace->theclass) { + if (CScope_FindClassMember(result, nspace, name, 2)) { + nspace = result->nspace_0; + result->nspace_0 = NULL; + return nspace; + } else { + return NULL; + } + } + + if ((list = CScope_FindQualName(nspace, name)) && CScope_ExtractNameSpace(list, &fail)) + return nspace; + + if (!fail && nspace->usings) { + found = NULL; + for (lookup = CScope_BuildNameSpaceMemberLookupList(nspace); lookup; lookup = lookup->next) { + for (scan = lookup->namespaces; scan; scan = scan->next) { + if ((list = CScope_FindQualName(scan->nspace, name)) && (cand = CScope_ExtractNameSpace(list, &fail))) { + if (found && cand != found) + CScope_AmbigNameError(found, cand, NULL); + found = cand; + } + + if (fail) + return NULL; + } + + if (found) + return found; + } + } + + return NULL; +} + +static NameSpaceObjectList *CScope_FindQualifiedName(CScopeParseResult *result, NameSpace *nspace, HashNameNode *name, NameSpace **foundnspace) { + NameSpaceObjectList *list; + NameSpaceLookupList *lookup; + + if (nspace->theclass) { + CDecl_CompleteType((Type *) nspace->theclass); + if (CScope_FindClassMember(result, nspace, name, 0)) { + list = result->nsol_14; + result->nsol_14 = NULL; + return list; + } else { + return NULL; + } + } + + if ((list = CScope_FindQualName(nspace, name))) { + *foundnspace = nspace; + return list; + } + + if (nspace->usings) { + for (lookup = CScope_BuildNameSpaceMemberLookupList(nspace); lookup; lookup = lookup->next) { + if ((list = CScope_FindLookupName(lookup, name, foundnspace))) + return list; + } + } + + return NULL; +} + +static Boolean CScope_FindQualifiedTag(CScopeParseResult *result, NameSpace *nspace, HashNameNode *name) { + NameSpaceObjectList *list; + NameSpaceLookupList *lookup; + Type *best; + NameSpace *bestnspace; + NameSpaceList *scan; + + if (nspace->theclass) { + CDecl_CompleteType((Type *) nspace->theclass); + return CScope_FindClassMember(result, nspace, name, 1) != 0; + } + + if ((list = CScope_FindQualName(nspace, name))) { + for (; list; list = list->next) { + if (list->object->otype == OT_TYPETAG) { + result->x8 = OBJ_TYPE_TAG(list->object)->type; + return 1; + } + } + } + + if (nspace->usings) { + best = NULL; + for (lookup = CScope_BuildNameSpaceMemberLookupList(nspace); lookup; lookup = lookup->next) { + for (scan = lookup->namespaces; scan; scan = scan->next) { + for (list = CScope_FindQualName(scan->nspace, name); list; list = list->next) { + if (list->object->otype == OT_TYPETAG) { + if (best && best != OBJ_TYPE_TAG(list->object)->type) + CScope_AmbigNameError(scan->nspace, bestnspace, name); + best = OBJ_TYPE_TAG(list->object)->type; + bestnspace = scan->nspace; + break; + } + } + } + + if (best) { + result->x8 = best; + return 1; + } + } + } + + return 0; +} + +inline void CScope_NSIteratorInit(CScopeNSIterator *iterator, NameSpace *nspace, CScopeParseResult *result) { + // assumed name + if (nspace->usings) { + iterator->nspace = NULL; + iterator->lookup = CScope_BuildNameSpaceLookupList(nspace); + } else { + iterator->nspace = nspace; + iterator->lookup = NULL; + } + iterator->result = result; +} + +inline Boolean CScope_NSIteratorNext(CScopeNSIterator *iterator) { + // assumed name + if (iterator->lookup) + return (iterator->lookup = iterator->lookup->next) != NULL; + if (iterator->result->x1D) + return 0; + + if ((iterator->nspace = iterator->nspace->parent)) { + if (iterator->nspace->usings && !iterator->result->x1D) { + iterator->lookup = CScope_BuildNameSpaceLookupList(iterator->nspace); + iterator->nspace = NULL; + } + return 1; + } else { + return 0; + } +} + +Type *CScope_GetType(NameSpace *nspace, HashNameNode *name, void **unk6) { + CScopeParseResult result; + CScopeNSIterator iterator; + NameSpaceObjectList *list; + Boolean ok; + + memclrw(&result, sizeof(result)); + CScope_NSIteratorInit(&iterator, nspace, &result); + + do { + for (list = CScope_NSIteratorFind(&iterator, name); list; list = list->next) { + if (list->object->otype == OT_TYPETAG) { + if (unk6) + *unk6 = NULL; + return OBJ_TYPE_TAG(list->object)->type; + } + if (list->object->otype == OT_TYPE) { + if (unk6) + *unk6 = OBJ_TYPE(list->object)->unk6; + return OBJ_TYPE(list->object)->type; + } + } + } while (CScope_NSIteratorNext(&iterator)); + + return NULL; +} + +Type *CScope_GetTagType(NameSpace *nspace, HashNameNode *name) { + CScopeParseResult result; + CScopeNSIterator iterator; + NameSpaceObjectList *list; + Boolean ok; + + memclrw(&result, sizeof(result)); + CScope_NSIteratorInit(&iterator, nspace, &result); + + do { + for (list = CScope_NSIteratorFind(&iterator, name); list; list = list->next) { + if (list->object->otype == OT_TYPETAG) + return OBJ_TYPE_TAG(list->object)->type; + } + } while (CScope_NSIteratorNext(&iterator)); + + return NULL; +} + +static Boolean CScope_DependentTemplateMember(CScopeParseResult *result, TypeTemplDep *ttempldep, Boolean flag1, Boolean flag2) { + // does not match, sign extension/caching mishap + SInt32 streamstate; + short token; + short token2; + TypeTemplDep *newtype; + TypeTemplDep *newtype2; + + CPrep_TokenStreamGetState(&streamstate); +#line 2026 + CError_ASSERT(lex() == TK_COLON_COLON); + + do { + token = lex(); + if (token == TK_OPERATOR && flag1) { + if (!CParser_ParseOperatorName(NULL, 1, 1)) + return 0; + newtype = CDecl_NewTemplDepType(TEMPLDEP_QUALNAME); + newtype->u.qual.type = ttempldep; + newtype->u.qual.name = tkidentifier; + CPrep_TokenStreamSetState(&streamstate); + lex(); + tk = lex(); + result->x8 = (Type *) newtype; + return 1; + } else if (token == TK_TEMPLATE) { + if (lex() != TK_IDENTIFIER) { + CError_Error(107); + return 0; + } + + CPrep_TokenStreamGetState(&streamstate); + newtype = CDecl_NewTemplDepType(TEMPLDEP_QUALNAME); + newtype->u.qual.type = ttempldep; + newtype->u.qual.name = tkidentifier; + if ((token2 = lex()) != '<') { + CError_Error(230); + return 0; + } + tk = token2; + newtype2 = CDecl_NewTemplDepType(TEMPLDEP_QUALTEMPL); + newtype2->u.qualtempl.type = newtype; + newtype2->u.qualtempl.args = CTempl_ParseUncheckTemplArgs(NULL, 1); + CPrep_TokenStreamGetState(&streamstate); + if (lex() == TK_COLON_COLON) { + ttempldep = newtype2; + continue; + } else { + CPrep_TokenStreamSetState(&streamstate); + result->x8 = (Type *) newtype2; + return 1; + } + } else if (token == TK_IDENTIFIER) { + newtype = CDecl_NewTemplDepType(TEMPLDEP_QUALNAME); + newtype->u.qual.type = ttempldep; + newtype->u.qual.name = tkidentifier; + tk = token; + + CPrep_TokenStreamGetState(&streamstate); + token2 = lex(); + tkidentifier = newtype->u.qual.name; + if (token2 == TK_COLON_COLON) { + ttempldep = newtype; + continue; + } + + if ((token2 == '<') && !flag2) { + tk = token2; + newtype2 = newtype; + newtype = CDecl_NewTemplDepType(TEMPLDEP_QUALTEMPL); + newtype->u.qualtempl.type = newtype2; + newtype->u.qualtempl.args = CTempl_ParseUncheckTemplArgs(NULL, 1); + + CPrep_TokenStreamGetState(&streamstate); + if (lex() == TK_COLON_COLON) { + ttempldep = newtype; + continue; + } + } + + CPrep_TokenStreamSetState(&streamstate); + result->x8 = (Type *) newtype; + return 1; + } else { + CPrep_TokenStreamSetState(&streamstate); + result->x8 = (Type *) ttempldep; + return 1; + } + } while (1); +} + +static Boolean CScope_CheckDtorName(TypeClass *tclass, Boolean *flag) { + if ((tk = lex()) != TK_IDENTIFIER) + CError_Error(107); + + if (tclass) { + *flag = 0; + if ((tclass->classname == tkidentifier) || (CScope_GetType(tclass->nspace, tkidentifier, NULL) == (Type *) tclass) || (CScope_GetType(cscope_current, tkidentifier, NULL) == (Type *) tclass)) { + if (!CClass_Destructor(tclass)) + *flag = 1; + if ((tclass->flags & CLASS_FLAGS_800) && (lookahead() == '<')) { + tk = lex(); + if (!CTemplTool_EqualArgs(TEMPL_CLASS_INST(tclass)->inst_args, CTempl_ParseUncheckTemplArgs(NULL, 0))) + CError_Error(374); + } + return 1; + } + } + + CError_Error(141); + return 0; +} + +static Boolean CScope_ParseQualifiedName(CScopeParseResult *result, NameSpace *nspace) { + NameSpaceObjectList *list; + HashNameNode *saveidentifier; + TypeClass *tclass; + Boolean flag = 0; + + do { + switch (tk) { + case TK_TEMPLATE: + if ((tk = lex()) != TK_IDENTIFIER) { + CError_Error(107); + return 0; + } + case TK_IDENTIFIER: + saveidentifier = tkidentifier; + if (lookahead() == TK_COLON_COLON) { + tk = lex(); + nspace = CScope_FindQualifiedNameSpace(result, nspace, saveidentifier); + if (!nspace) + return 0; + result->x1D = 1; + tk = lex(); + continue; + } + break; + case TK_OPERATOR: + if (!CParser_ParseOperatorName(NULL, 1, 1)) + return 0; + CPrep_UnLex(); + saveidentifier = tkidentifier; + break; + case '~': + if (!CScope_CheckDtorName(nspace->theclass, &flag)) + return 0; + saveidentifier = destructor_name_node; + flag = 1; + break; + default: + CError_Error(107); + return 0; + } + + if (!(list = CScope_FindQualifiedName(result, nspace, saveidentifier, &result->nspace_0)) || !CScope_SetupParseNameResult(result, list, saveidentifier)) { + if (flag) { + result->x1C = 1; + return 1; + } + if (nspace->theclass && !(nspace->theclass->flags & CLASS_FLAGS_2)) + CError_Error(136, nspace->theclass, 0); + else + CError_Error(140, saveidentifier->name); + return 0; + } + + if (result->x8 && (result->x8->type == TYPECLASS) && (lookahead() == '<')) { + tclass = TYPE_CLASS(result->x8); + if (tclass->flags & CLASS_FLAGS_800) + tclass = TYPE_CLASS(TEMPL_CLASS_INST(tclass)->templ); + else if (!(tclass->flags & CLASS_FLAGS_100)) + return 1; + + tk = lex(); + result->x8 = CTempl_ClassGetType(tclass); + if ((result->x8->type == TYPECLASS) && (lookahead() == TK_COLON_COLON)) { + lex(); + tk = lex(); + result->x1D = 1; + nspace = TYPE_CLASS(result->x8)->nspace; + result->x8 = NULL; + result->obj_10 = NULL; + continue; + } + } + + return 1; + } while (1); +} + +Boolean CScope_ParseExprName(CScopeParseResult *result) { + CScopeNSIterator iterator; + HashNameNode *name; + NameSpaceObjectList *list; + Boolean flag; + + if (!copts.cplusplus) { + memclrw(result, sizeof(CScopeParseResult)); + if (tk != TK_IDENTIFIER) { + CError_Error(107); + return 0; + } + + name = tkidentifier; + CScope_NSIteratorInit(&iterator, cscope_current, result); + do { + if ((list = CScope_NSIteratorFind(&iterator, name)) && (list->object->otype != OT_TYPETAG)) { + result->nspace_0 = iterator.lookup ? iterator.lookup->nspace : iterator.nspace; + return CScope_SetupParseNameResult(result, list, name); + } + } while (CScope_NSIteratorNext(&iterator)); + + result->nspace_0 = cscope_current; + result->name_4 = name; + return 1; + } else { + if ((tk == TK_COLON_COLON || tk == TK_IDENTIFIER) && CScope_ParseQualifiedNameSpace(result, 1, 1)) { + if (result->x8) + return 1; +#line 2313 + CError_ASSERT(result->nspace_0); + } else { + memclrw(result, sizeof(CScopeParseResult)); + result->nspace_0 = cscope_current; + } + + switch (tk) { + case TK_TEMPLATE: + if (!result->x1D) + CError_Error(373); + + if ((tk = lex()) != TK_IDENTIFIER) { + CError_Error(107); + return 0; + } + case TK_IDENTIFIER: + name = tkidentifier; + break; + case TK_OPERATOR: + if (!CParser_ParseOperatorName(NULL, 1, 1)) + return 0; + name = tkidentifier; + CPrep_UnLex(); + break; + case '~': + if (!CScope_CheckDtorName(result->nspace_0->theclass, &flag)) + return 0; + if (flag) { + result->x1C = 1; + return 1; + } + name = destructor_name_node; + break; + default: + CError_Error(107); + return 0; + } + + if (result->x1D) { + if (!(list = CScope_FindQualifiedName(result, result->nspace_0, name, &result->nspace_0))) { + CError_Error(140, CError_GetNameString(result->nspace_0, name)); + return 0; + } else { + return CScope_SetupParseNameResult(result, list, name); + } + } + + CScope_NSIteratorInit(&iterator, result->nspace_0, result); + do { + if ((list = CScope_NSIteratorFind(&iterator, name))) { + result->nspace_0 = iterator.lookup ? iterator.lookup->nspace : iterator.nspace; + return CScope_SetupParseNameResult(result, list, name); + } + } while (CScope_NSIteratorNext(&iterator)); + + if (result->x1D) { + CError_Error(140, name->name); + return 0; + } else { + result->nspace_0 = cscope_current; + result->name_4 = name; + return 1; + } + } +} + +Boolean CScope_ParseDeclName(CScopeParseResult *result) { + CScopeNSIterator iterator; + HashNameNode *name; + NameSpaceObjectList *list; + NameSpace *nspace; + Boolean flag; + CScopeSave save; + short op; + + if (!copts.cplusplus) { + non_cpp_mode: + if (tk != TK_IDENTIFIER) { + CError_Error(107); + return 0; + } + memclrw(result, sizeof(CScopeParseResult)); + + name = tkidentifier; + CScope_NSIteratorInit(&iterator, cscope_current, result); + do { + if ((list = CScope_NSIteratorFind(&iterator, name)) && (copts.cplusplus || (list->object->otype != OT_TYPETAG))) { + result->nspace_0 = iterator.lookup ? iterator.lookup->nspace : iterator.nspace; + return CScope_SetupParseNameResult(result, list, name); + } + } while (CScope_NSIteratorNext(&iterator)); + + result->nspace_0 = cscope_current; + result->name_4 = name; + return 0; + } else { + if ((tk != TK_COLON_COLON) && (tk != TK_IDENTIFIER)) { + CError_Error(107); + return 0; + } + + if (!CScope_ParseQualifiedNameSpace(result, 0, 0)) + goto non_cpp_mode; + + if (result->x8) + return 1; + + nspace = result->nspace_0; +#line 2435 + CError_ASSERT(nspace); + + switch (tk) { + case TK_OPERATOR: + CScope_SetNameSpaceScope(nspace, &save); + if (!CParser_ParseOperatorName(&op, 1, 1)) { + CScope_RestoreScope(&save); + return 0; + } + CScope_RestoreScope(&save); + if (op) + CError_Error(121); + result->x21 = 1; + return 1; + case TK_IDENTIFIER: + name = tkidentifier; + if (nspace->theclass && nspace->theclass->classname == tkidentifier) + name = constructor_name_node; + break; + case '~': + if (!nspace->theclass) { + CError_Error(121); + return 0; + } + tk = lex(); + if (tk != TK_IDENTIFIER) { + CError_Error(107); + return 0; + } + if (nspace->theclass->classname != tkidentifier) + CError_Error(121); + name = destructor_name_node; + break; + default: + CError_Error(107); + return 0; + } + + if (result->x1D) { + if (!(list = CScope_FindQualifiedName(result, result->nspace_0, name, &result->nspace_0))) { + CError_Error(140, name->name); + return 0; + } else { + return CScope_SetupParseNameResult(result, list, name); + } + } + + CScope_NSIteratorInit(&iterator, nspace, result); + do { + if ((list = CScope_NSIteratorFind(&iterator, name))) { + result->nspace_0 = iterator.lookup ? iterator.lookup->nspace : iterator.nspace; + return CScope_SetupParseNameResult(result, list, name); + } + } while (CScope_NSIteratorNext(&iterator)); + + CError_Error(140, name->name); + return 0; + } +} + +Boolean CScope_ParseQualifiedNameSpace(CScopeParseResult *result, Boolean flag1, Boolean flag2) { + // mostly matches, some registers are awkwardly swapped + HashNameNode *name; // r25 + NameSpace *nspace; // r24 + short t; // r23 + Type *type; // r28? + Type *type2; // r21? + NameSpaceObjectList *list; // r21 + CScopeNSIterator iterator; + + memclrw(result, sizeof(CScopeParseResult)); + nspace = NULL; + if (tk == TK_COLON_COLON) { + result->nspace_0 = nspace = cscope_root; + result->x1D = 1; + tk = lex(); + } + + restart: + if (tk != TK_IDENTIFIER) { + if (tk != TK_TEMPLATE) + return nspace != NULL; + if (!result->x1D) + CError_Error(373); + if ((tk = lex()) != TK_IDENTIFIER) { + CError_Error(107); + return 0; + } + } + + name = tkidentifier; + t = lookahead(); + tkidentifier = name; + + if (t != TK_COLON_COLON && t != '<') + return nspace != NULL; + + CScope_NSIteratorInit(&iterator, nspace ? nspace : cscope_current, result); + // r28 = r23 ??? + do { + // list = r21 + for (list = CScope_NSIteratorFind(&iterator, name); list; list = list->next) { + if (list->object->otype == OT_NAMESPACE) { +#line 2565 + CError_ASSERT(!nspace || !nspace->theclass); + + result->nspace_0 = nspace = OBJ_NAMESPACE(list->object)->nspace; + if ((tk = lex()) != TK_COLON_COLON) { + CError_Error(321); + return 0; + } + + result->x1D = 1; + tk = lex(); + goto restart; + } + if (list->object->otype == OT_TYPETAG) { + type = OBJ_TYPE_TAG(list->object)->type; + if (type->type != TYPECLASS) { + if (t == '<') { + result->x8 = type; + return 1; + } else { + CError_Error(121); + return 0; + } + } + parse_thing: + if (t == '<') { + if (TYPE_CLASS(type)->flags & CLASS_FLAGS_800) { + type = (Type *) TEMPL_CLASS_INST(type)->templ; + } else if (!(TYPE_CLASS(type)->flags & CLASS_FLAGS_100)) { + result->x8 = type; + return 1; + } + } + if ((tk = lex()) == '<') { +#line 2609 + CError_ASSERT(TYPE_CLASS(type)->flags & CLASS_FLAGS_100); + type2 = CTempl_ClassGetType(TYPE_CLASS(type)); + if (type2->type == TYPETEMPLATE) { + if (lookahead() != TK_COLON_COLON) { + result->x8 = type2; + return 1; + } + return CScope_DependentTemplateMember(result, TYPE_TEMPLATE(type2), flag1, flag2); + } else if (type2->type != TYPECLASS) { + return 0; + } + + result->nspace_0 = nspace = TYPE_CLASS(type2)->nspace; + if (lookahead() != TK_COLON_COLON) { + result->x8 = type2; + return 1; + } + tk = lex(); + CDecl_CompleteType(type2); + } else { +#line 2632 + CError_ASSERT(tk == TK_COLON_COLON); + if (!(TYPE_CLASS(type)->flags & CLASS_FLAGS_100) || CParser_CheckTemplateClassUsage(TEMPL_CLASS(type), 1)) + result->nspace_0 = nspace = TYPE_CLASS(type)->nspace; + CDecl_CompleteType(type); + } + + result->x1D = 1; + tk = lex(); + goto restart; + } + if (list->object->otype == OT_TYPE) { + type2 = OBJ_TYPE(list->object)->type; + if (type2->type != TYPECLASS) { + if (type2->type == TYPETEMPLATE) { + if (TYPE_TEMPLATE(type2)->dtype == TEMPLDEP_ARGUMENT && TYPE_TEMPLATE(type2)->u.pid.type == TPT_TEMPLATE) { + type2 = CTempl_ParseTemplTemplParam(type2); + if ((type2->type != TYPETEMPLATE) || ((t = lookahead()) != TK_COLON_COLON)) { + result->x8 = type2; + return 1; + } + } + if (t == TK_COLON_COLON) + return CScope_DependentTemplateMember(result, TYPE_TEMPLATE(type2), flag1, flag2); + } + if (t == '<') { + result->x8 = type2; + return 1; + } else { + CError_Error(121); + return 0; + } + } else { + if ((t == '<') && (TYPE_CLASS(type2)->flags & CLASS_FLAGS_100)) { + type = type2; + goto parse_thing; + } + if ((tk = lex()) == '<') { + result->x8 = type2; + return 1; + } +#line 2686 + CError_ASSERT(tk == TK_COLON_COLON); + if (!type2->size) + CDecl_CompleteType(type2); + result->nspace_0 = nspace = TYPE_CLASS(type2)->nspace; + result->x1D = 1; + tk = lex(); + goto restart; + } + } + if (t == '<') + return nspace != NULL; + } + } while (CScope_NSIteratorNext(&iterator)); + + CError_Error(140, name->name); + return 0; +} + +Boolean CScope_ParseElaborateName(CScopeParseResult *result) { + CScopeNSIterator iterator; + HashNameNode *name; + NameSpaceObjectList *list; + Boolean flag; + + if (!copts.cplusplus) { + memclrw(result, sizeof(CScopeParseResult)); + if (tk != TK_IDENTIFIER) { + CError_Error(107); + return 0; + } + + name = tkidentifier; + CScope_NSIteratorInit(&iterator, cscope_current, result); + do { + for (list = CScope_NSIteratorFind(&iterator, name); list; list = list->next) { + if (list->object->otype == OT_TYPETAG) { + result->nspace_0 = iterator.lookup ? iterator.lookup->nspace : iterator.nspace; + return CScope_SetupParseNameResult(result, list, name); + } + } + } while (CScope_NSIteratorNext(&iterator)); + + result->name_4 = name; + return 1; + } else { + if ((tk != TK_COLON_COLON) && (tk != TK_IDENTIFIER)) { + CError_Error(107); + return 0; + } + + if (!CScope_ParseQualifiedNameSpace(result, 0, 0)) { + result->nspace_0 = cscope_current; + if (tk != TK_IDENTIFIER) { + CError_Error(107); + return 0; + } + name = tkidentifier; + } else { + if (result->x8) + return 1; +#line 2760 + CError_ASSERT(result->nspace_0); + + if (tk != TK_IDENTIFIER) { + CError_Error(107); + return 0; + } + name = tkidentifier; + + if (result->x1D) { + if (result->nspace_0->theclass) + return CScope_FindClassMember(result, result->nspace_0, name, 1) != 0; + else + return CScope_FindQualifiedTag(result, result->nspace_0, name); + } + } + + CScope_NSIteratorInit(&iterator, result->nspace_0, result); + do { + for (list = CScope_NSIteratorFind(&iterator, name); list; list = list->next) { + if (list->object->otype == OT_TYPETAG || list->object->otype == OT_TYPE) { + result->nspace_0 = iterator.lookup ? iterator.lookup->nspace : iterator.nspace; + return CScope_SetupParseNameResult(result, list, name); + } + } + } while (CScope_NSIteratorNext(&iterator)); + + result->name_4 = name; + return 1; + } +} + +Boolean CScope_FindObject(NameSpace *nspace, CScopeParseResult *result, HashNameNode *name) { + CScopeNSIterator iterator; + NameSpaceObjectList *list; + + memclrw(result, sizeof(CScopeParseResult)); + CScope_NSIteratorInit(&iterator, nspace, result); + do { + for (list = CScope_NSIteratorFind(&iterator, name); list; list = list->next) { + if (copts.cplusplus || list->object->otype != OT_TYPETAG) { + result->nspace_0 = iterator.lookup ? iterator.lookup->nspace : iterator.nspace; + return CScope_SetupParseNameResult(result, list, name); + } + } + } while (CScope_NSIteratorNext(&iterator)); + + return 0; +} + +Boolean CScope_FindNonClassObject(NameSpace *nspace, CScopeParseResult *result, HashNameNode *name) { + CScopeNSIterator iterator; + NameSpaceObjectList *list; + + memclrw(result, sizeof(CScopeParseResult)); + CScope_NSIteratorInit(&iterator, nspace, result); + do { + for (list = CScope_NSIteratorNonClassFind(&iterator, name); list; list = list->next) { + if (copts.cplusplus || list->object->otype != OT_TYPETAG) { + result->nspace_0 = iterator.lookup ? iterator.lookup->nspace : iterator.nspace; + return CScope_SetupParseNameResult(result, list, name); + } + } + } while (CScope_NSIteratorNext(&iterator)); + + return 0; +} + +NameSpaceObjectList *CScope_FindObjectList(CScopeParseResult *result, HashNameNode *name) { + CScopeNSIterator iterator; + NameSpaceObjectList *list; + + memclrw(result, sizeof(CScopeParseResult)); + CScope_NSIteratorInit(&iterator, cscope_current, result); + do { + for (list = CScope_NSIteratorFind(&iterator, name); list; list = list->next) { + if (copts.cplusplus || list->object->otype != OT_TYPETAG) { + result->nspace_0 = iterator.lookup ? iterator.lookup->nspace : iterator.nspace; + return list; + } + } + } while (CScope_NSIteratorNext(&iterator)); + + return 0; +} + +Boolean CScope_PossibleTypeName(HashNameNode *name) { + CScopeParseResult result; + CScopeNSIterator iterator; + NameSpaceObjectList *list; + + memclrw(&result, sizeof(CScopeParseResult)); + CScope_NSIteratorInit(&iterator, cscope_current, &result); + do { + if ((list = CScope_NSIteratorFind(&iterator, name))) { + switch (list->object->otype) { + case OT_TYPE: + case OT_NAMESPACE: + return 1; + case OT_TYPETAG: + if (copts.cplusplus) + return 1; + break; + default: + return 0; + } + } + } while (CScope_NSIteratorNext(&iterator)); + + return 0; +} + +Boolean CScope_FindClassMemberObject(TypeClass *tclass, CScopeParseResult *result, HashNameNode *name) { + NameSpaceObjectList *list; + + memclrw(result, sizeof(CScopeParseResult)); + + if (CScope_FindClassMember(result, tclass->nspace, name, 0)) { + list = result->nsol_14; + result->nsol_14 = NULL; + if (list && list->object->otype == OT_OBJECT) + return CScope_SetupParseNameResult(result, list, name); + } + + return 0; +} + +void CScope_InitObjectIterator(CScopeObjectIterator *iterator, NameSpace *nspace) { + memclrw(iterator, sizeof(CScopeObjectIterator)); + iterator->nspace = nspace; + if (!iterator->nspace->is_hash) + iterator->nextname = nspace->data.list; + else + iterator->nextname = nspace->data.hash[0]; +} + +ObjBase *CScope_NextObjectIteratorObject(CScopeObjectIterator *iterator) { + ObjBase *obj; + + do { + if (iterator->currlist) { + do { + obj = iterator->currlist->object; + if (obj->otype == OT_OBJECT) { + iterator->currlist = iterator->currlist->next; + return obj; + } + } while ((iterator->currlist = iterator->currlist->next)); + } + + if (iterator->nextname) { + iterator->currlist = &iterator->nextname->first; + iterator->nextname = iterator->nextname->next; + } else { + if (!iterator->nspace->is_hash || ++iterator->hashindex >= 1024) + return NULL; + iterator->nextname = iterator->nspace->data.hash[iterator->hashindex]; + } + } while (1); +} + +NameSpaceObjectList *CScope_NextObjectIteratorObjectList(CScopeObjectIterator *iterator) { + NameSpaceName *nsname; + + do { + if ((nsname = iterator->nextname)) { + iterator->nextname = nsname->next; + return &nsname->first; + } else { + if (!iterator->nspace->is_hash || ++iterator->hashindex >= 1024) + return NULL; + iterator->nextname = iterator->nspace->data.hash[iterator->hashindex]; + } + } while (1); +} + +void CScope_DefineTypeTag(NameSpace *nspace, HashNameNode *name, Type *type) { + ObjTypeTag *ott; + + ott = galloc(sizeof(ObjTypeTag)); + memclrw(ott, sizeof(ObjTypeTag)); + ott->otype = OT_TYPETAG; + ott->access = nspace->theclass ? global_access : ACCESSPUBLIC; + ott->type = type; + CScope_AddObject(nspace, name, OBJ_BASE(ott)); +} + +Type *CScope_GetLocalTagType(NameSpace *nspace, HashNameNode *name) { + NameSpaceObjectList *list; + + for (list = CScope_FindQualName(nspace, name); list; list = list->next) { + if (list->object->otype == OT_TYPETAG) + return OBJ_TYPE_TAG(list->object)->type; + } + + return NULL; +} + +Boolean CScope_FindTypeName(NameSpace *nspace, HashNameNode *name, CScopeParseResult *result) { + CScopeNSIterator iterator; + NameSpaceObjectList *list; + NameSpaceObjectList *scan; + + memclrw(result, sizeof(CScopeParseResult)); + CScope_NSIteratorInit(&iterator, nspace, result); + + do { + list = CScope_NSIteratorFind(&iterator, name); + for (scan = list; scan; scan = scan->next) { + switch (scan->object->otype) { + case OT_NAMESPACE: + result->nspace_0 = OBJ_NAMESPACE(scan->object)->nspace; + return 1; + case OT_TYPE: + case OT_TYPETAG: + return CScope_SetupParseNameResult(result, scan, name); + default: + return 0; + } + } + } while (CScope_NSIteratorNext(&iterator)); + + return 0; +} + +static NameSpaceObjectList *CScope_GetLocalObjects(NameSpaceObjectList *objs) { + NameSpaceObjectList *list; + NameSpaceObjectList **ptr; + + list = objs; + while (list) { + if (list->object->otype == OT_OBJECT && OBJECT(list->object)->datatype == DALIAS) { + list = CScope_CopyNameSpaceObjectList(objs); + ptr = &list; + while (*ptr) { + if ((*ptr)->object->otype == OT_OBJECT && OBJECT((*ptr)->object)->datatype == DALIAS) + *ptr = (*ptr)->next; + else + ptr = &(*ptr)->next; + } + return list; + } else { + list = list->next; + } + } + + return objs; +} + +NameSpaceObjectList *CScope_GetLocalObject(NameSpace *nspace, HashNameNode *name) { + NameSpaceObjectList *list; + + if ((list = CScope_FindQualName(nspace, name))) { + switch (list->object->otype) { + case OT_OBJECT: + return CScope_GetLocalObjects(list); + default: + CError_Error(122, name->name); + return NULL; + case OT_TYPETAG: + break; + } + } + + return NULL; +} + +static BClassList *CScope_GetBaseAccessPathEnd(BClassList *list) { + BClassList *best = list; + ClassList *scan; + + do { + if (!list->next) + return best; + + for (scan = TYPE_CLASS(list->type)->bases; scan; scan = scan->next) { + if (TYPE_CLASS(list->next->type) == scan->base) + break; + } + + if (!scan) + best = list->next; + list = list->next; + } while (1); +} + +BClassList *CScope_GetClassAccessPath(BClassList *list, TypeClass *tclass) { + BClassList *scan; + BClassList *list2; + + if (!list) + return NULL; + + list = CScope_GetBaseAccessPathEnd(list); + for (scan = list; scan; scan = scan->next) { + if (scan->type == (Type *) tclass) + return scan; + } + + if ((list2 = CScope_GetAccessPath(tclass, TYPE_CLASS(list->type)))) { + for (scan = list2; scan; scan = scan->next) { + if (scan->type == list->type) { + scan->next = list->next; + return list2; + } + } +#line 3217 + CError_FATAL(); + } + + return NULL; +} + +static Boolean CScope_FixMemberResult(TypeClass *tclass, CScopeParseResult *result) { + if (!(result->bcl_18 = CScope_GetClassAccessPath(result->bcl_18, tclass))) { + if (result->name_4) + CError_Error(150, result->name_4->name); + else + CError_Error(328); + return 0; + } else { + return 1; + } +} + +Boolean CScope_ParseMemberName(TypeClass *tclass, CScopeParseResult *result, Boolean flag) { + HashNameNode *name; + NameSpaceObjectList *list; + short t; + Boolean dtorflag; + + if (tk == TK_COLON_COLON) { + restart: + if (!CScope_ParseExprName(result)) + return 0; + + if (result->x8 && result->x8->type == TYPETEMPLATE && TYPE_TEMPLATE(result->x8)->dtype == TEMPLDEP_QUALNAME) { + if (flag) + return 1; + CError_Error(340, TYPE_TEMPLATE(result->x8)->u.qual.name->name); + result->x8 = NULL; + return 0; + } + + if (result->x1C) + return 1; + else + return CScope_FixMemberResult(tclass, result); + } + + if (tk == TK_IDENTIFIER) { + name = tkidentifier; + t = lookahead(); + tkidentifier = name; + switch (t) { + case TK_COLON_COLON: + memclrw(result, sizeof(CScopeParseResult)); + if (!CScope_FindClassMember(result, tclass->nspace, name, 2)) + goto restart; + break; + case '<': + if (flag) + goto restart; + break; + } + } else if (tk == '~') { + memclrw(result, sizeof(CScopeParseResult)); + if (CScope_CheckDtorName(tclass, &dtorflag)) { + if (dtorflag) { + result->x1C = 1; + return 1; + } + + if (!(list = CScope_FindQualifiedName(result, tclass->nspace, destructor_name_node, &result->nspace_0))) { + CError_Error(140, CError_GetNameString(result->nspace_0, destructor_name_node)); + return 0; + } else { + return CScope_SetupParseNameResult(result, list, destructor_name_node); + } + } + return 0; + } + + memclrw(result, sizeof(CScopeParseResult)); + return CScope_ParseQualifiedName(result, tclass->nspace); +} + +static void CScope_AddUsingObject(BClassList *bcl, NameSpace *nspace, ObjBase *obj, HashNameNode *name, AccessType access) { + NameSpaceObjectList *list; + BClassList *pathcopy; + TypeClass *tclass; + ObjBase *copy; + Object *objscan; + + if (bcl) { + if (!nspace->theclass) + CError_Error(200); + else + CClass_CheckPathAccess(bcl, NULL, obj->access); + } + + if (obj->otype == OT_TYPE) { + if (!nspace->theclass) { + if ((list = CScope_FindQualName(nspace, name)) && (list->object->otype == OT_TYPE) && + (OBJ_TYPE(obj)->type == OBJ_TYPE(list->object)->type) && + (OBJ_TYPE(obj)->unk6 == OBJ_TYPE(list->object)->unk6)) + return; + } + copy = galloc(sizeof(ObjType)); + *OBJ_TYPE(copy) = *OBJ_TYPE(obj); + copy->access = access; + CScope_AddObject(nspace, name, copy); + } else if (obj->otype == OT_TYPETAG) { + if (!nspace->theclass) { + if ((list = CScope_FindQualName(nspace, name)) && (list->object->otype == OT_TYPETAG) && + (OBJ_TYPE_TAG(obj)->type == OBJ_TYPE_TAG(list->object)->type)) + return; + } + copy = galloc(sizeof(ObjTypeTag)); + *OBJ_TYPE_TAG(copy) = *OBJ_TYPE_TAG(obj); + copy->access = access; + CScope_AddObject(nspace, name, copy); + } else if (obj->otype == OT_ENUMCONST) { + copy = galloc(sizeof(ObjEnumConst)); + *OBJ_ENUM_CONST(copy) = *OBJ_ENUM_CONST(obj); + copy->access = access; + CScope_AddObject(nspace, OBJ_ENUM_CONST(copy)->name, copy); + } else if (obj->otype == OT_MEMBERVAR) { + if (nspace->theclass) { + copy = galloc(sizeof(ObjMemberVarPath)); + *OBJ_MEMBER_VAR(copy) = *OBJ_MEMBER_VAR(obj); + copy->access = access; + pathcopy = CScope_GetClassAccessPath(CClass_GetPathCopy(bcl, 1), nspace->theclass); + if (pathcopy && pathcopy->type == (Type *) nspace->theclass) { + OBJ_MEMBER_VAR_PATH(copy)->has_path = 1; + OBJ_MEMBER_VAR_PATH(copy)->path = pathcopy; + } else { + CError_Error(221); + } + CScope_AddObject(nspace, OBJ_MEMBER_VAR(copy)->name, copy); + } else { + CError_Error(221); + } + } else if (obj->otype == OT_OBJECT) { + if (!nspace->theclass) { + for (list = CScope_FindQualName(nspace, OBJECT(obj)->name); list; list = list->next) { + if (list->object->otype == OT_OBJECT) { + objscan = OBJECT(list->object); + while (objscan->datatype == DALIAS) + objscan = objscan->u.alias.object; + if (OBJECT(obj) == objscan) + return; + } + } + } + + copy = galloc(sizeof(Object)); + *OBJECT(copy) = *OBJECT(obj); + copy->access = access; + OBJECT(copy)->datatype = DALIAS; + OBJECT(copy)->u.alias.object = OBJECT(obj); + OBJECT(copy)->u.alias.member = NULL; + OBJECT(copy)->u.alias.offset = 0; + + if (OBJECT(copy)->type->type == TYPEFUNC && (TYPE_FUNC(OBJECT(copy)->type)->flags & FUNC_FLAGS_METHOD) && !TYPE_METHOD(OBJECT(copy)->type)->x26) { + if (!(tclass = nspace->theclass) || !(OBJECT(copy)->u.alias.member = CScope_GetClassAccessPath( + CClass_GetPathCopy(bcl, 1), tclass)) || (OBJECT(copy)->u.alias.member->type != (Type *) nspace->theclass)) { + CError_Error(221); + OBJECT(copy)->u.alias.member = NULL; + } + } + + CScope_AddObject(nspace, OBJECT(copy)->name, copy); + } else { + CError_Error(200); + } +} + +void CScope_AddClassUsingDeclaration(TypeClass *tclass, TypeClass *tclass2, HashNameNode *name, AccessType access) { + CScopeParseResult result; + NameSpaceObjectList *scan; + + memclrw(&result, sizeof(CScopeParseResult)); + if (!CScope_FindClassMember(&result, tclass2->nspace, name, 0) || !CScope_FixMemberResult(tclass, &result)) { + CError_Error(340, name->name); + return; + } + + if (result.nsol_14) { + for (scan = result.nsol_14; scan; scan = scan->next) { + switch (scan->object->otype) { + case OT_ENUMCONST: + case OT_MEMBERVAR: + case OT_OBJECT: + CScope_AddUsingObject(result.bcl_18, tclass->nspace, scan->object, result.name_4, access); + break; + } + } + } else { + if (result.obj_10) + CScope_AddUsingObject(result.bcl_18, tclass->nspace, result.obj_10, result.name_4, access); + else + CError_Error(340, name->name); + } +} + +void CScope_ParseUsingDeclaration(NameSpace *nspace, AccessType access) { + // almost matches, slight bit of register weirdness + CScopeParseResult result; + + if (nspace->theclass) { + Boolean flag_r27 = (TYPE_CLASS(nspace->theclass)->flags & CLASS_FLAGS_100) ? 1 : 0; + Boolean flag_r26 = 0; + if (tk == TK_TYPENAME) { + if (!flag_r27) + CError_Error(200); + flag_r26 = 1; + tk = lex(); + } + + if (!CScope_ParseMemberName(nspace->theclass, &result, flag_r27)) { + CError_Error(200); + return; + } + + if (result.x8 && result.x8->type == TYPETEMPLATE && TYPE_TEMPLATE(result.x8)->dtype == TEMPLDEP_QUALNAME) { +#line 3578 + CError_ASSERT(flag_r27); + + if (flag_r26) { + ObjType *objtype = galloc(sizeof(ObjType)); + memclrw(objtype, sizeof(ObjType)); + objtype->otype = OT_TYPE; + objtype->access = access; + objtype->type = result.x8; + CScope_AddObject(nspace, TYPE_TEMPLATE(result.x8)->u.qual.name, OBJ_BASE(objtype)); + } else { + CTemplClass_RegisterUsingDecl(TEMPL_CLASS(nspace->theclass), result.x8, access); + } + + if ((tk = lex()) != ';') + CError_Error(123); + return; + } + + if (!result.x1D) { + CError_Error(200); + return; + } + } else { + NameSpace *savenspace = cscope_current; + cscope_current = nspace; + if (!CScope_ParseExprName(&result) || !result.x1D) { + cscope_current = savenspace; + CError_Error(200); + return; + } else { + cscope_current = savenspace; + } + } + + if (result.nsol_14) { + NameSpaceObjectList *scan; + for (scan = result.nsol_14; scan; scan = scan->next) { + if (scan->object->otype == OT_OBJECT) + CScope_AddUsingObject(result.bcl_18, nspace, scan->object, result.name_4, access); + } + } else { + if (result.obj_10) + CScope_AddUsingObject(result.bcl_18, nspace, result.obj_10, result.name_4, access); + else + CError_Error(200); + } + + if ((tk = lex()) != ';') + CError_Error(123); +} + +static NameSpace *CScope_ParseQualifiedNamespaceSpecifier(NameSpace *nspace) { + CScopeParseResult result; + CScopeNSIterator iterator; + NameSpaceObjectList *list; + + memclrw(&result, sizeof(CScopeParseResult)); + if (tk == TK_COLON_COLON) { + nspace = cscope_root; + result.x1D = 1; + tk = lex(); + } + + do { + if (tk != TK_IDENTIFIER) { + CError_Error(107); + break; + } + + CScope_NSIteratorInit(&iterator, nspace, &result); + do { + if ((list = CScope_NSIteratorFind(&iterator, tkidentifier)) && list->object->otype == OT_NAMESPACE) { + nspace = OBJ_NAMESPACE(list->object)->nspace; + goto some_goto; + } + } while (CScope_NSIteratorNext(&iterator)); + CError_Error(140, tkidentifier->name); + some_goto: + if ((tk = lex()) != TK_COLON_COLON) + break; + result.x1D = 1; + tk = lex(); + } while (1); + + return nspace; +} + +void CScope_ParseNameSpaceAlias(HashNameNode *name) { + NameSpaceObjectList *list; + ObjNameSpace *objns; + + list = CScope_FindQualName(cscope_current, name); + if (!list) { + tk = lex(); + objns = galloc(sizeof(ObjNameSpace)); + memclrw(objns, sizeof(ObjNameSpace)); + objns->otype = OT_NAMESPACE; + objns->access = ACCESSPUBLIC; + objns->nspace = CScope_ParseQualifiedNamespaceSpecifier(cscope_current); + CScope_AddObject(cscope_current, name, OBJ_BASE(objns)); + } else if (list->object->otype != OT_NAMESPACE) { + CError_Error(320); + tk = lex(); + CScope_ParseQualifiedNamespaceSpecifier(cscope_current); + } else { + tk = lex(); + if (CScope_ParseQualifiedNamespaceSpecifier(cscope_current) != OBJ_NAMESPACE(list->object)->nspace) + CError_Error(122, name->name); + } + + if (tk != ';') + CError_Error(123); +} + +void CScope_ParseUsingDirective(NameSpace *nspace) { + NameSpace *target; + NameSpaceList *list; + + target = CScope_ParseQualifiedNamespaceSpecifier(nspace); + if (target != nspace) { + for (list = nspace->usings; list; list = list->next) { + if (list->nspace == target) + break; + } + if (!list) { + list = galloc(sizeof(NameSpaceList)); + list->next = nspace->usings; + list->nspace = target; + nspace->usings = list; + } + } else { + CError_Error(321); + } + + if (tk != ';') + CError_Error(123); +} |