diff options
Diffstat (limited to 'compiler_and_linker/FrontEnd/C/CScope.c')
-rw-r--r-- | compiler_and_linker/FrontEnd/C/CScope.c | 2690 |
1 files changed, 2690 insertions, 0 deletions
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); +} |