diff options
Diffstat (limited to 'compiler_and_linker/unsorted/CTemplateClass.c')
-rw-r--r-- | compiler_and_linker/unsorted/CTemplateClass.c | 1632 |
1 files changed, 0 insertions, 1632 deletions
diff --git a/compiler_and_linker/unsorted/CTemplateClass.c b/compiler_and_linker/unsorted/CTemplateClass.c deleted file mode 100644 index 8b3b889..0000000 --- a/compiler_and_linker/unsorted/CTemplateClass.c +++ /dev/null @@ -1,1632 +0,0 @@ -#include "compiler/CTemplateClass.h" -#include "compiler/CABI.h" -#include "compiler/CBrowse.h" -#include "compiler/CClass.h" -#include "compiler/CDecl.h" -#include "compiler/CError.h" -#include "compiler/CInline.h" -#include "compiler/CInt64.h" -#include "compiler/CMachine.h" -#include "compiler/CMangler.h" -#include "compiler/CParser.h" -#include "compiler/CPrep.h" -#include "compiler/CPrepTokenizer.h" -#include "compiler/CScope.h" -#include "compiler/CTemplateFunc.h" -#include "compiler/CTemplateNew.h" -#include "compiler/CTemplateTools.h" -#include "compiler/CompilerTools.h" -#include "compiler/objects.h" -#include "compiler/scopes.h" -#include "compiler/templates.h" - -TemplClass *CTemplClass_GetMasterTemplate(TemplClass *tmclass) { - if (tmclass->inst_parent) { - tmclass = TEMPL_CLASS(tmclass->theclass.nspace->theclass); - CError_ASSERT(42, tmclass->theclass.flags & CLASS_IS_TEMPL); - } - - return tmclass; -} - -static void CTemplClass_SetupActionErrorRef(TemplateAction *action, TStreamElement **saved) { - CError_ResetErrorSkip(); - CError_LockErrorPos(&action->source_ref, saved); -} - -static void CTemplClass_RestoreActionErrorRef(TStreamElement **saved) { - CError_ResetErrorSkip(); - CError_UnlockErrorPos(saved); -} - -static void CTemplClass_AppendTemplateAction(TemplClass *tmclass, TemplateAction *action) { - TemplateAction *last; - - action->source_ref = *CPrep_CurStreamElement(); - - if ((last = tmclass->actions)) { - while (last->next) - last = last->next; - last->next = action; - } else { - tmclass->actions = action; - } -} - -static DefAction *CTemplClass_NewDefAction(TypeDeduce *deduce, TemplateAction *action) { - DefAction *defAction = lalloc(sizeof(DefAction)); - defAction->next = deduce->defActions; - defAction->action = action; - deduce->defActions = defAction; - return defAction; -} - -static void CTemplClass_InsertTemplateAction(TemplClass *tmclass, TemplateAction *action) { - action->source_ref = *CPrep_CurStreamElement(); - action->next = tmclass->actions; - tmclass->actions = action; -} - -void CTemplClass_RegisterUsingDecl(TemplClass *tmclass, TypeTemplDep *type, AccessType access) { - TemplateAction *action; - - action = galloc(sizeof(TemplateAction)); - memclrw(action, sizeof(TemplateAction)); - - action->type = TAT_USINGDECL; - action->u.usingdecl.type = type; - action->u.usingdecl.access = access; - - CTemplClass_AppendTemplateAction(tmclass, action); -} - -void CTemplClass_RegisterFriend(TemplClass *tmclass, DeclInfo *di) { - TemplateFriend *tfriend; - TemplateAction *action; - - tfriend = galloc(sizeof(TemplateFriend)); - memclrw(tfriend, sizeof(TemplateFriend)); - - if (tk == '{' && IS_TYPE_FUNC(di->thetype)) { - di->qual |= Q_INLINE; - TYPE_FUNC(di->thetype)->flags |= FUNC_DEFINED | FUNC_IS_TEMPL_INSTANCE; - tfriend->fileoffset = cparser_fileoffset; - - CPrep_StreamGetBlock(&tfriend->stream, NULL, 1); - - if (lookahead() == ';') - tk = lex(); - else - tk = ';'; - } - - CDecl_PackDeclInfo(&tfriend->decl, di); - - action = galloc(sizeof(TemplateAction)); - memclrw(action, sizeof(TemplateAction)); - - action->type = TAT_FRIEND; - action->u.tfriend = tfriend; - - CTemplClass_AppendTemplateAction(tmclass, action); -} - -void CTemplClass_RegisterBaseClass(TemplClass *tmclass, Type *type, AccessType access, Boolean is_virtual) { - TemplateAction *action; - ClassList *insert_after; - - if ((insert_after = tmclass->theclass.bases)) { - while (insert_after->next) - insert_after = insert_after->next; - } - - action = galloc(sizeof(TemplateAction)); - memclrw(action, sizeof(TemplateAction)); - - action->type = TAT_BASE; - action->u.base.type = type; - action->u.base.insert_after = insert_after; - action->u.base.access = access; - action->u.base.is_virtual = is_virtual; - - CTemplClass_InsertTemplateAction(tmclass, action); -} - -void CTemplClass_RegisterEnumType(TemplClass *tmclass, TypeEnum *enumtype) { - TemplateAction *action; - - action = galloc(sizeof(TemplateAction)); - memclrw(action, sizeof(TemplateAction)); - - action->type = TAT_ENUMTYPE; - action->u.enumtype = enumtype; - - CTemplClass_AppendTemplateAction(tmclass, action); -} - -void CTemplClass_RegisterEnumerator(TemplClass *tmclass, ObjEnumConst *objenumconst, ENode *initexpr) { - TemplateAction *action; - - action = galloc(sizeof(TemplateAction)); - memclrw(action, sizeof(TemplateAction)); - - action->type = TAT_ENUMERATOR; - action->u.enumerator.objenumconst = objenumconst; - action->u.enumerator.initexpr = initexpr ? CInline_CopyExpression(initexpr, CopyMode1) : NULL; - - CTemplClass_AppendTemplateAction(tmclass, action); -} - -void CTemplClass_RegisterObjectInit(TemplClass *tmclass, Object *object, ENode *initexpr) { - TemplateAction *action; - - action = galloc(sizeof(TemplateAction)); - memclrw(action, sizeof(TemplateAction)); - - action->type = TAT_OBJECTINIT; - action->u.objectinit.object = object; - action->u.objectinit.initexpr = CInline_CopyExpression(initexpr, CopyMode1); - - CTemplClass_AppendTemplateAction(tmclass, action); -} - -void CTemplClass_RegisterObjectDef(TemplClass *tmclass, ObjBase *refobj) { - TemplateAction *action; - - action = galloc(sizeof(TemplateAction)); - memclrw(action, sizeof(TemplateAction)); - - action->type = TAT_OBJECTDEF; - action->u.refobj = refobj; - - CTemplClass_AppendTemplateAction(tmclass, action); -} - -void CTemplClass_CompleteClass(TemplClass *templ, ClassLayout *de) { - templ->lex_order_count = de->lex_order_count; - if (de->has_vtable) - templ->flags |= TEMPLCLASS_HAS_VTABLE; - templ->theclass.flags |= CLASS_COMPLETED; -} - -static TemplClassInst *CTemplClass_NewInstance(TemplClass *templ, TemplArg *inst_args, TemplArg *oargs) { - TemplClassInst *inst; - ObjTypeTag *tag; - NameSpace *nspace; - HashNameNode *name; - - CError_ASSERT(288, !templ->pspec_owner); - - inst = galloc(sizeof(TemplClassInst)); - memclrw(inst, sizeof(TemplClassInst)); - - inst->next = templ->instances; - templ->instances = inst; - - if (templ->templ__params) - name = CMangler_TemplateInstanceName(templ->theclass.classname, oargs ? oargs : inst_args); - else - name = templ->theclass.classname; - - inst->inst_args = inst_args; - inst->oargs = oargs; - inst->parent = templ->inst_parent; - - nspace = CScope_NewListNameSpace(name, 1); - nspace->theclass = TYPE_CLASS(inst); - if (templ->templ_parent && templ->inst_parent) { - nspace->parent = TYPE_CLASS(templ->inst_parent)->nspace; - } else { - NameSpace *scan = templ->theclass.nspace->parent; - while (scan->is_templ) - scan = scan->parent; - nspace->parent = scan; - } - - inst->theclass.type = TYPECLASS; - inst->theclass.flags = CLASS_IS_TEMPL_INST; - inst->theclass.nspace = nspace; - inst->theclass.classname = templ->theclass.classname; - inst->theclass.mode = templ->theclass.mode; - inst->theclass.eflags = templ->theclass.eflags; - inst->templ = templ; - - tag = galloc(sizeof(ObjTypeTag)); - memclrw(tag, sizeof(ObjTypeTag)); - - tag->otype = OT_TYPETAG; - tag->access = ACCESSPUBLIC; - tag->type = TYPE(inst); - CScope_AddObject(nspace, templ->theclass.classname, OBJ_BASE(tag)); - - return inst; -} - -TemplClassInst *CTemplClass_GetInstance(TemplClass *tmclass, TemplArg *inst_args, TemplArg *oargs) { - TemplClassInst *inst; - - for (inst = tmclass->instances; inst; inst = inst->next) { - CError_ASSERT(353, !oargs); - - if (CTemplTool_EqualArgs(inst_args, inst->oargs ? inst->oargs : inst->inst_args)) - return inst; - } - - return CTemplClass_NewInstance(tmclass, inst_args, oargs); -} - -TemplateMember *CTemplClass_DefineMember(TemplClass *tmclass, Object *object, FileOffsetInfo *foi, TokenStream *stream) { - TemplateMember *member; - - for (member = tmclass->members; member; member = member->next) { - if (member->object == object) { - CError_Error(CErrorStr333, object); - return member; - } - } - - member = galloc(sizeof(TemplateMember)); - memclrw(member, sizeof(TemplateMember)); - member->next = tmclass->members; - tmclass->members = member; - - member->params = NULL; - member->object = object; - member->fileoffset = *foi; - member->stream = *stream; - - return member; -} - -static void CTemplClass_ParseBody(TemplClass *templ, short mode, SInt32 *offset) { - DeclInfo di; - - templ->align = copts.structalignment; - - memclrw(&di, sizeof(di)); - di.file = CPrep_BrowserCurrentFile(); - CPrep_BrowserFilePosition(&di.file2, &di.sourceoffset); - di.sourceoffset = *offset; - di.x28 = templ; - - CDecl_ParseClass(&di, mode, 1, 0); - - if (tk == TK_UU_ATTRIBUTE_UU) - CParser_ParseAttribute(di.thetype, NULL); - if (tk != ';') - CError_Error(CErrorStr123); - - CBrowse_NewTemplateClass(templ, di.file2, di.sourceoffset, CPrep_BrowserFileOffset() + 1); -} - -void CTemplClass_ParsePartialSpecialization(DeclFucker *what_is_this, TemplParam *params, short mode, SInt32 *offset) { - Type *type; - NameSpace *nspace; - TemplArg *args; - TemplPartialSpec *pspec; - TemplClass *templ; - TemplArg *arg; - TemplParam *param; - - nspace = what_is_this->nspace; - - if ((tk = lex()) != TK_IDENTIFIER) { - CError_Error(CErrorStr107); - return; - } - - if (!(type = CScope_GetLocalTagType(nspace, tkidentifier))) { - CError_Error(CErrorStr140, tkidentifier->name); - return; - } - - if (!IS_TEMPL_CLASS(type)) { - CError_Error(CErrorStr132, tkidentifier->name); - return; - } - - if ((tk = lex()) != '<') - CError_FATAL(469); - - for (param = params; param; param = param->next) { - switch (param->pid.type) { - case TPT_TYPE: - if (!param->data.typeparam.type) - continue; - CError_Error(CErrorStr344); - break; - - case TPT_NONTYPE: - if (!param->data.paramdecl.defaultarg) - continue; - CError_Error(CErrorStr344); - break; - - case TPT_TEMPLATE: - if (!param->data.templparam.defaultarg) - continue; - CError_Error(CErrorStr344); - break; - - default: - CError_FATAL(501); - } - - break; - } - - args = CTempl_ParseUncheckTemplArgs(TEMPL_CLASS(type)->templ__params, 0); - tk = lex(); - - arg = args; - param = TEMPL_CLASS(type)->templ__params; - while (1) { - if (!arg) { - if (!param) - break; - CError_Error(CErrorStr344); - return; - } - if (!param) { - CError_Error(CErrorStr344); - return; - } - if (param->pid.type != arg->pid.type) { - CError_Error(CErrorStr344); - return; - } - arg = arg->next; - param = param->next; - } - - if (CTemplTool_IsSameTemplate(TEMPL_CLASS(type)->templ__params, args)) - CError_Error(CErrorStr344); - - for (pspec = TEMPL_CLASS(type)->pspecs; pspec; pspec = pspec->next) { - if (CTemplTool_EqualParams(pspec->templ->templ__params, params, 0) && CTemplTool_EqualArgs(pspec->args, args)) - break; - } - - if (!pspec) { - templ = galloc(sizeof(TemplClass)); - memclrw(templ, sizeof(TemplClass)); - - templ->templ__params = params; - CDecl_DefineClass(nspace, TEMPL_CLASS(type)->theclass.classname, TYPE_CLASS(templ), mode, 0, 0); - - templ->theclass.flags = CLASS_IS_TEMPL; - templ->pspec_owner = TEMPL_CLASS(type); - - pspec = galloc(sizeof(TemplPartialSpec)); - memclrw(pspec, sizeof(TemplPartialSpec)); - - pspec->templ = templ; - pspec->args = CTemplTool_MakeGlobalTemplArgCopy(args); - pspec->next = TEMPL_CLASS(type)->pspecs; - TEMPL_CLASS(type)->pspecs = pspec; - } else { - if ((pspec->templ->theclass.flags & CLASS_COMPLETED) && tk != ';') { - CError_Error(CErrorStr132, TEMPL_CLASS(type)->theclass.classname->name); - return; - } - - if (tk == ':' || tk == '{') - CTemplTool_EqualParams(pspec->templ->templ__params, params, 1); - } - - switch (tk) { - case ':': - case '{': - CTemplClass_ParseBody(pspec->templ, mode, offset); - break; - case ';': - break; - default: - CError_Error(CErrorStr121); - } -} - -void CTemplClass_ParseClass(DeclFucker *what_is_this, TemplParam *params, short mode, SInt32 *offset) { - TemplClass *templ; - NameSpace *nspace; - Type *type; - UInt8 classDeclSpec = 0; - - nspace = what_is_this->nspace; - if ((tk = lex()) == TK_UU_DECLSPEC) - CDecl_ParseClassDeclSpec(&classDeclSpec); - - if (tk != TK_IDENTIFIER) { - CError_Error(CErrorStr107); - return; - } - - type = CScope_GetLocalTagType(nspace, tkidentifier); - if (!type) { - templ = galloc(sizeof(TemplClass)); - memclrw(templ, sizeof(TemplClass)); - - templ->next = ctempl_templates; - ctempl_templates = templ; - - templ->templ__params = params; - CDecl_DefineClass(nspace, tkidentifier, TYPE_CLASS(templ), mode, 0, 1); - templ->theclass.flags = CLASS_IS_TEMPL; - templ->theclass.eflags = classDeclSpec; - - tk = lex(); - if (nspace->theclass && (nspace->theclass->flags & CLASS_IS_TEMPL)) { - TemplateAction *action; - - templ->templ_parent = TEMPL_CLASS(nspace->theclass); - - action = galloc(sizeof(TemplateAction)); - memclrw(action, sizeof(TemplateAction)); - - action->type = TAT_NESTEDCLASS; - action->u.tclasstype = templ; - CTemplClass_AppendTemplateAction(templ->templ_parent, action); - } - } else { - if (!IS_TEMPL_CLASS(type)) { - CError_Error(CErrorStr132, tkidentifier->name); - return; - } - - templ = TEMPL_CLASS(type); - if (!CTemplTool_EqualParams(templ->templ__params, params, 0)) { - CError_Error(CErrorStr132, templ->theclass.classname->name); - return; - } - - CTemplTool_MergeDefaultArgs(templ->templ__params, params); - templ->theclass.eflags |= classDeclSpec; - - tk = lex(); - - if ((templ->theclass.flags & CLASS_COMPLETED) && tk != ';') { - CError_Error(CErrorStr132, templ->theclass.classname->name); - return; - } - - if (tk != ';') - CTemplTool_EqualParams(templ->templ__params, params, 1); - } - - switch (tk) { - case ':': - case '{': - CTemplClass_ParseBody(templ, mode, offset); - break; - case ';': - break; - default: - CError_Error(CErrorStr121); - } -} - -static Boolean CTemplClass_TypeParamCompare(TemplArg *arg, Type *type, UInt32 qual) { - return is_typesame(type, arg->data.typeparam.type) && arg->data.typeparam.qual == qual; -} - -static TemplArg *CTemplClass_PartialTemplateArgMatch(TemplPartialSpec *pspec, TemplArg *args, Boolean flag) { - TemplArg *argA; - TemplArg *argB; - int i; - DeduceInfo info; - - if (!CTemplTool_InitDeduceInfo(&info, pspec->templ->templ__params, NULL, 1)) - return NULL; - - argA = pspec->args; - argB = args; - while (1) { - if (!argA) { - if (argB) - return NULL; - - for (i = 0; i < info.maxCount; i++) { - if (!info.args[i].is_deduced) - return NULL; - } - - if (flag) - return CTemplTool_MakeTemplArgList(&info); - else - return args; - } - - if (!argB) - return NULL; - - if (argA->pid.type != argB->pid.type) - return NULL; - - switch (argA->pid.type) { - case TPT_TYPE: - if (CTemplTool_IsTemplateArgumentDependentType(argA->data.typeparam.type)) { - if (!CTempl_DeduceType( - argA->data.typeparam.type, argA->data.typeparam.qual, - argB->data.typeparam.type, argB->data.typeparam.qual, - info.args, 0, 0 - )) - return NULL; - } else { - if ( - !is_typesame(argA->data.typeparam.type, argB->data.typeparam.type) || - argA->data.typeparam.qual != argB->data.typeparam.qual - ) - return NULL; - } - break; - - case TPT_NONTYPE: - if (CTemplTool_IsTemplateArgumentDependentExpression(argA->data.paramdecl.expr)) { - i = CTempl_GetTemplateArgumentExpressionIndex(argA); - CError_ASSERT(789, i >= 0); - - if (info.args[i].is_deduced) { - if (!CTemplTool_EqualExprTypes(argB->data.paramdecl.expr, info.args[i].data.paramdecl.expr)) - return NULL; - } else { - info.args[i].data.paramdecl.expr = argB->data.paramdecl.expr; - info.args[i].pid.type = TPT_NONTYPE; - info.args[i].is_deduced = 1; - } - } else { - if (!CTemplTool_EqualExprTypes(argB->data.paramdecl.expr, argA->data.paramdecl.expr)) - return NULL; - } - break; - - case TPT_TEMPLATE: - if (CTemplTool_IsTemplateArgumentDependentType(argA->data.ttargtype)) { - if (!CTempl_DeduceType( - argA->data.ttargtype, 0, - argB->data.ttargtype, 0, - info.args, 0, 0 - )) - return NULL; - } else { - if (!is_typesame(argA->data.ttargtype, argB->data.ttargtype)) - return NULL; - } - break; - - default: - CError_FATAL(830); - } - - argA = argA->next; - argB = argB->next; - } -} - -static Boolean CTemplClass_PartialClassIsAtLeastAsSpecialized(TemplPartialSpec *pspec1, TemplPartialSpec *pspec2) { - TemplArg *argA; - TemplArg *argB; - int i; - DeduceInfo info; - - if (!CTemplTool_InitDeduceInfo(&info, pspec2->templ->templ__params, NULL, 1)) - return 0; - - argA = pspec1->args; - argB = pspec2->args; - - while (1) { - if (!argA) { - CError_ASSERT(856, !argB); - - for (i = 0; i < info.maxCount; i++) { - if (!info.args[i].is_deduced) - return 0; - } - - return 1; - } - - CError_ASSERT(865, argB); - CError_ASSERT(866, argA->pid.type == argB->pid.type); - - switch (argA->pid.type) { - case TPT_TYPE: - if (!CTempl_DeduceType( - argB->data.typeparam.type, argB->data.typeparam.qual, - argA->data.typeparam.type, argA->data.typeparam.qual, - info.args, 0, 0 - )) - return 0; - break; - - case TPT_NONTYPE: - if (CTemplTool_IsTemplateArgumentDependentExpression(argB->data.paramdecl.expr)) { - i = CTempl_GetTemplateArgumentExpressionIndex(argB); - CError_ASSERT(907, i >= 0); - - if (info.args[i].is_deduced) { - if (argA->data.paramdecl.expr) { - if (!info.args[i].data.paramdecl.expr || !CTemplTool_EqualExprTypes(argA->data.paramdecl.expr, info.args[i].data.paramdecl.expr)) - return 0; - } else { - if (info.args[i].data.paramdecl.expr || argA->pid.index != info.args[i].pid.index) - return 0; - } - } else { - info.args[i].data.paramdecl.expr = argA->data.paramdecl.expr; - info.args[i].pid.index = argA->pid.index; - info.args[i].pid.type = TPT_NONTYPE; - info.args[i].is_deduced = 1; - } - } else { - if ( - !argA->data.paramdecl.expr || - !CTemplTool_EqualExprTypes(argA->data.paramdecl.expr, argB->data.paramdecl.expr) - ) - return 0; - } - break; - - case TPT_TEMPLATE: - if (!CTempl_DeduceType( - argB->data.ttargtype, 0, - argA->data.ttargtype, 0, - info.args, 0, 0 - )) - return 0; - break; - - default: - CError_FATAL(955); - } - - argA = argA->next; - argB = argB->next; - } -} - -static Boolean CTemplClass_PartialClassIsMoreSpecialized(TemplPartialSpec *pspec1, TemplPartialSpec *pspec2) { - return CTemplClass_PartialClassIsAtLeastAsSpecialized(pspec1, pspec2) && - !CTemplClass_PartialClassIsAtLeastAsSpecialized(pspec2, pspec1); -} - -typedef struct PSpecList { - struct PSpecList *next; - TemplPartialSpec *pspec; -} PSpecList; - -static PSpecList *CTemplClass_FindMostSpecializedPartialSpecializations(PSpecList *list) { - PSpecList **array; - PSpecList *scan; - int i; - int j; - int count; - - scan = list; - count = 0; - while (scan) { - scan = scan->next; - count++; - } - - array = lalloc(sizeof(PSpecList *) * count); - for (i = 0, scan = list; scan; scan = scan->next) - array[i++] = scan; - - for (i = 0; i < count; i++) { - if (array[i]) { - for (j = 0; j < count; j++) { - if (array[j] && i != j && CTemplClass_PartialClassIsMoreSpecialized(array[i]->pspec, array[j]->pspec)) - array[j] = NULL; - } - } - } - - for (i = 0, list = NULL; i < count; i++) { - if (array[i]) { - if (!list) - list = array[i]; - else - array[j]->next = array[i]; - array[i]->next = NULL; - j = i; - } - } - - return list; -} - -Boolean CTemplClass_FindPartialTemplate(TemplArg *args, TemplClass **resultTempl, TemplArg **resultArgs) { - TemplPartialSpec *pspec; - PSpecList *list; - TemplClassInst *inst; - - for (inst = (*resultTempl)->instances; inst; inst = inst->next) { - if (inst->is_instantiated || inst->is_specialized) { - if (CTemplTool_EqualArgs(args, inst->oargs ? inst->oargs : inst->inst_args)) - return 0; - } - } - - list = NULL; - for (pspec = (*resultTempl)->pspecs; pspec; pspec = pspec->next) { - if (CTemplClass_PartialTemplateArgMatch(pspec, args, 0)) { - PSpecList *entry = lalloc(sizeof(PSpecList)); - entry->next = list; - entry->pspec = pspec; - list = entry; - } - } - - if (list) { - if (list->next) { - list = CTemplClass_FindMostSpecializedPartialSpecializations(list); - if (list->next) - CError_Error(CErrorStr346); - } - - if (!list->pspec->templ->templ__params) { - *resultTempl = list->pspec->templ; - *resultArgs = NULL; - return 1; - } - - *resultTempl = list->pspec->templ; - *resultArgs = CTemplClass_PartialTemplateArgMatch(list->pspec, args, 1); - return *resultArgs != NULL; - } else { - return 0; - } -} - -TemplClass *CTemplClass_DefineNestedClass(TemplClass *parent, HashNameNode *name, short mode) { - TemplateAction *action; - TemplClass *templ; - - templ = galloc(sizeof(TemplClass)); - memclrw(templ, sizeof(TemplClass)); - - templ->next = ctempl_templates; - ctempl_templates = templ; - - templ->templ_parent = parent; - templ->templ__params = NULL; - CDecl_DefineClass(parent->theclass.nspace, name, TYPE_CLASS(templ), mode, 0, 1); - - templ->theclass.flags = CLASS_IS_TEMPL; - templ->align = copts.structalignment; - - action = galloc(sizeof(TemplateAction)); - memclrw(action, sizeof(TemplateAction)); - - action->type = TAT_NESTEDCLASS; - action->u.tclasstype = templ; - CTemplClass_AppendTemplateAction(parent, action); - - return templ; -} - -static void CTemplClass_CopyNestedClass(TypeDeduce *deduce, TemplClass *templ) { - ObjTypeTag *tag; - - tag = galloc(sizeof(ObjTypeTag)); - memclrw(tag, sizeof(ObjTypeTag)); - - tag->otype = OT_TYPETAG; - tag->access = ACCESSPUBLIC; - - if (!templ->templ__params) { - TemplClassInst *inst = CTemplClass_NewInstance(templ, NULL, NULL); - inst->parent = deduce->inst; - inst->theclass.nspace->parent = deduce->inst->theclass.nspace; - - tag->type = TYPE(inst); - } else { - TemplClass *copy = galloc(sizeof(TemplClass)); - memclrw(copy, sizeof(TemplClass)); - - copy->next = ctempl_templates; - ctempl_templates = copy; - - copy->theclass = templ->theclass; - copy->templ_parent = deduce->tmclass; - copy->inst_parent = deduce->inst; - copy->templ__params = templ->templ__params; - copy->members = NULL; - copy->instances = NULL; - copy->pspecs = NULL; - copy->actions = templ->actions; - copy->lex_order_count = templ->lex_order_count; - copy->align = templ->align; - copy->flags = templ->flags; - - tag->type = TYPE(copy); - } - - CScope_AddObject(deduce->inst->theclass.nspace, templ->theclass.classname, OBJ_BASE(tag)); -} - -static void CTemplClass_CopyBaseClasses(TypeDeduce *deduce, TemplClassInst *inst, TemplClass *templ) { - TemplateAction *action; - ClassList *newBase; - ClassList *templbase; - ClassList *instbase; - ClassList *base; - UInt32 qual = 0; - - for (base = templ->theclass.bases; base; base = base->next) { - ClassList *scan; - newBase = galloc(sizeof(ClassList)); - *newBase = *base; - newBase->next = NULL; - - if ((scan = inst->theclass.bases)) { - while (1) { - if (scan->base == newBase->base) { - CError_Error(CErrorStr131); - break; - } - if (!scan->next) { - scan->next = newBase; - break; - } - scan = scan->next; - } - } else { - inst->theclass.bases = newBase; - } - } - - for (action = deduce->tmclass->actions; action; action = action->next) { - if (action->type == TAT_BASE) { - TStreamElement *save; - - CTemplClass_SetupActionErrorRef(action, &save); - - newBase = galloc(sizeof(ClassList)); - memclrw(newBase, sizeof(ClassList)); - - newBase->base = TYPE_CLASS(CTemplTool_DeduceTypeCopy(deduce, action->u.base.type, &qual)); - newBase->access = action->u.base.access; - newBase->is_virtual = action->u.base.is_virtual; - - if (IS_TYPE_CLASS(newBase->base)) { - if (newBase->base->size == 0) { - CDecl_CompleteType(TYPE(newBase->base)); - IsCompleteType(TYPE(newBase->base)); - } - - if (CDecl_CheckNewBase(TYPE_CLASS(inst), newBase->base, newBase->is_virtual)) { - if (action->u.base.insert_after) { - templbase = templ->theclass.bases; - instbase = inst->theclass.bases; - while (1) { - CError_ASSERT(1222, templbase && instbase); - - if (templbase == action->u.base.insert_after) { - newBase->next = instbase->next; - instbase->next = newBase; - break; - } - - templbase = templbase->next; - instbase = instbase->next; - } - } else { - newBase->next = inst->theclass.bases; - inst->theclass.bases = newBase; - } - } - } else { - CError_Error(CErrorStr131); - } - - CTemplClass_RestoreActionErrorRef(&save); - } - } - - if (inst->theclass.flags & CLASS_HAS_VBASES) - CDecl_MakeVBaseList(TYPE_CLASS(inst)); -} - -static void CTemplClass_CopyEnum(TypeDeduce *deduce, TemplateAction *action) { - TypeEnum *destenum; - TypeEnum *srcenum; - ObjEnumConst **destptr; - ObjEnumConst *src; - TemplateAction *scanaction; - - srcenum = action->u.enumtype; - destenum = galloc(sizeof(TypeEnum)); - memclrw(destenum, sizeof(TypeEnum)); - - destenum->type = TYPEENUM; - destenum->size = srcenum->size; - destenum->nspace = deduce->inst->theclass.nspace; - destenum->enumtype = srcenum->enumtype; - destenum->enumname = srcenum->enumname; - - if (destenum->enumname) - CScope_DefineTypeTag(destenum->nspace, destenum->enumname, TYPE(destenum)); - - src = srcenum->enumlist; - destptr = &destenum->enumlist; - while (src) { - ObjEnumConst *dest; - - dest = galloc(sizeof(ObjEnumConst)); - *dest = *src; - - *destptr = dest; - dest->next = NULL; - dest->type = TYPE(destenum); - CScope_AddObject(deduce->inst->theclass.nspace, dest->name, OBJ_BASE(dest)); - - src = src->next; - destptr = &(*destptr)->next; - } - - for (scanaction = deduce->tmclass->actions; scanaction; scanaction = scanaction->next) { - if (scanaction->type == TAT_ENUMERATOR && scanaction->u.enumerator.objenumconst->type == TYPE(srcenum)) { - CTemplClass_NewDefAction(deduce, action)->enumtype = destenum; - return; - } - } -} - -static void CTemplClass_CompleteEnumType(TypeDeduce *deduce, TemplateAction *action, TypeEnum *destenum) { - TypeEnum *srcenum; - ObjEnumConst *dest; - TemplateAction *scanaction; - ENode *expr; - ObjEnumConst *src; - - srcenum = action->u.enumtype; - - for (scanaction = deduce->tmclass->actions; scanaction; scanaction = scanaction->next) { - if (scanaction->type == TAT_ENUMERATOR) { - src = scanaction->u.enumerator.objenumconst; - if (src->type == TYPE(srcenum)) { - TStreamElement *save; - - CTemplClass_SetupActionErrorRef(scanaction, &save); - - dest = destenum->enumlist; - while (dest) { - if (dest->name == src->name) - break; - dest = dest->next; - } - - CError_ASSERT(1332, dest); - - if (scanaction->u.enumerator.initexpr) { - expr = CTemplTool_DeduceExpr(deduce, scanaction->u.enumerator.initexpr); - if (!ENODE_IS(expr, EINTCONST)) { - CError_Error(CErrorStr124); - CTemplClass_RestoreActionErrorRef(&save); - break; - } - } else { - CError_ASSERT(1347, expr); - expr->data.intval = CInt64_Add(expr->data.intval, cint64_one); - } - - dest->val = expr->data.intval; - dest->type = expr->rtype; - CTemplClass_RestoreActionErrorRef(&save); - } - } - } - - CDecl_ComputeUnderlyingEnumType(destenum); -} - -static void CTemplClass_CopyObjMemberVarPath(TypeDeduce *deduce, ObjMemberVarPath *ivar) { - ObjMemberVarPath *copy; - - copy = galloc(sizeof(ObjMemberVarPath)); - *copy = *ivar; - - if (copy->path && copy->path->type == TYPE(deduce->tmclass)) { - copy->path = CClass_GetPathCopy(copy->path, 1); - copy->path->type = TYPE(deduce->inst); - } - - CScope_AddObject(deduce->inst->theclass.nspace, copy->name, OBJ_BASE(copy)); -} - -static void CTemplClass_CopyIVars(TypeDeduce *deduce, TemplClassInst *inst, TemplClass *templ) { - ObjMemberVar *src; - ObjMemberVar *dest; - ObjMemberVar **destptr; - TemplateAction *scanaction; - - src = templ->theclass.ivars; - destptr = &inst->theclass.ivars; - - while (src) { - CError_ASSERT(1397, !src->has_path); - - dest = galloc(sizeof(ObjMemberVar)); - *dest = *src; - - for (scanaction = deduce->tmclass->actions; scanaction; scanaction = scanaction->next) { - if (scanaction->type == TAT_OBJECTDEF && scanaction->u.refobj == OBJ_BASE(src)) { - CTemplClass_NewDefAction(deduce, scanaction)->refobj = OBJ_BASE(dest); - break; - } - } - - if (!scanaction) { - dest->type = CTemplTool_DeduceTypeCopy(deduce, dest->type, &dest->qual); - if (dest->type->size == 0) { - CDecl_CompleteType(dest->type); - IsCompleteType(dest->type); - } - } - - if (dest->name && dest->name != no_name_node) - CScope_AddObject(inst->theclass.nspace, dest->name, OBJ_BASE(dest)); - - *destptr = dest; - destptr = &dest->next; - src = src->next; - } -} - -static void CTemplClass_CopyObjType(TypeDeduce *deduce, ObjType *src, HashNameNode *name) { - TemplateAction *scanaction; - NameSpaceObjectList *list; - NameSpaceObjectList *newlist; - ObjType *dest; - - for (scanaction = deduce->tmclass->actions; scanaction; scanaction = scanaction->next) { - if (scanaction->type == TAT_OBJECTDEF && scanaction->u.refobj == OBJ_BASE(src)) - break; - } - - dest = galloc(sizeof(ObjType)); - *dest = *src; - - if (scanaction) - CTemplClass_NewDefAction(deduce, scanaction)->refobj = OBJ_BASE(dest); - else - dest->type = CTemplTool_DeduceTypeCopy(deduce, dest->type, &dest->qual); - - if ((list = CScope_FindName(deduce->inst->theclass.nspace, name)) && list->object->otype == OT_TYPETAG) { - CError_ASSERT(1470, list->next == NULL); - - newlist = galloc(sizeof(NameSpaceObjectList)); - newlist->object = list->object; - newlist->next = NULL; - - list->object = OBJ_BASE(dest); - list->next = newlist; - } else { - CScope_AddObject(deduce->inst->theclass.nspace, name, OBJ_BASE(dest)); - } -} - -static void CTemplClass_CopyObjTypeTag(TypeDeduce *deduce, ObjTypeTag *src, HashNameNode *name) { - UInt32 qual = 0; - ObjTypeTag *dest = galloc(sizeof(ObjTypeTag)); - - *dest = *src; - dest->type = CTemplTool_DeduceTypeCopy(deduce, dest->type, &qual); - - CScope_AddObject(deduce->inst->theclass.nspace, name, OBJ_BASE(dest)); -} - -static void CTemplClass_CopyMemberTemplate(TypeDeduce *deduce, Object *src) { - TemplateFunction *desttempl; - Object *dest; - TemplateFunction *srctempl; - TemplateAction *action; - - srctempl = src->u.func.u.templ; - CError_ASSERT(1516, srctempl && srctempl->params); - - for (action = deduce->tmclass->actions; action; action = action->next) { - if (action->type == TAT_OBJECTDEF && action->u.refobj == OBJ_BASE(src)) - break; - } - - desttempl = galloc(sizeof(TemplateFunction)); - *desttempl = *srctempl; - - desttempl->next = ctempl_templatefuncs; - ctempl_templatefuncs = desttempl; - - desttempl->unk4 = srctempl; - - dest = galloc(sizeof(Object)); - *dest = *src; - - dest->u.func.u.templ = desttempl; - dest->nspace = deduce->inst->theclass.nspace; - - CError_ASSERT(1541, !deduce->x15); - deduce->x15 = 1; - deduce->nindex = srctempl->params->pid.nindex; - - if (action) - CTemplClass_NewDefAction(deduce, action)->refobj = OBJ_BASE(dest); - else - dest->type = CTemplTool_DeduceTypeCopy(deduce, dest->type, &dest->qual); - - deduce->x15 = 0; - - CError_ASSERT(1553, IS_TYPE_FUNC(dest->type)); - - TYPE_FUNC(dest->type)->flags |= FUNC_IS_TEMPL; - - if ( - (TYPE_FUNC(dest->type)->flags & FUNC_IS_CTOR) && - deduce->x17 && - !action - ) - { - FuncArg *arg; - CError_ASSERT(1560, TYPE_FUNC(dest->type)->args); - arg = CParser_NewFuncArg(); - arg->type = TYPE(&stsignedshort); - arg->next = TYPE_FUNC(dest->type)->args->next; - TYPE_FUNC(dest->type)->args->next = arg; - } - - CScope_AddObject(deduce->inst->theclass.nspace, dest->name, OBJ_BASE(dest)); -} - -static void CTemplClass_CopyObject(TypeDeduce *deduce, Object *src) { - ObjectTemplated *dest; - TemplateAction *action; - TemplateAction *action2; - Boolean flag; - - flag = 1; - if (src->nspace != deduce->tmclass->theclass.nspace) { - CError_ASSERT(1587, src->datatype == DALIAS); - flag = 0; - } - - if (IS_TEMPL_FUNC(src->type)) { - CTemplClass_CopyMemberTemplate(deduce, src); - return; - } - - for (action = deduce->tmclass->actions; action; action = action->next) { - if (action->type == TAT_OBJECTDEF && action->u.refobj == OBJ_BASE(src)) - break; - } - - dest = galloc(sizeof(ObjectTemplated)); - dest->object = *src; - - if (action) - CTemplClass_NewDefAction(deduce, action)->refobj = OBJ_BASE(dest); - else - dest->object.type = CTemplTool_DeduceTypeCopy(deduce, dest->object.type, &dest->object.qual); - - if (flag) - dest->object.nspace = deduce->inst->theclass.nspace; - - dest->object.qual |= Q_IS_TEMPLATED; - dest->parent = src; - - if (IS_TYPE_FUNC(dest->object.type)) - TYPE_FUNC(dest->object.type)->flags &= ~FUNC_DEFINED; - - switch (dest->object.datatype) { - case DDATA: - dest->object.u.data.linkname = NULL; - for (action2 = deduce->tmclass->actions; action2; action2 = action2->next) { - if (action2->type == TAT_OBJECTINIT && action2->u.objectinit.object == src) { - CTemplClass_NewDefAction(deduce, action2)->refobj = OBJ_BASE(dest); - break; - } - } - break; - - case DABSOLUTE: - break; - - case DFUNC: - case DVFUNC: - dest->object.u.func.linkname = NULL; - CError_ASSERT(1650, IS_TYPE_FUNC(dest->object.type)); - CError_ASSERT(1651, !dest->object.u.func.u.templ && !dest->object.u.func.defargdata); - - if ( - (TYPE_FUNC(dest->object.type)->flags & FUNC_IS_CTOR) && - deduce->x17 && - !action - ) - { - FuncArg *arg; - CError_ASSERT(1657, TYPE_FUNC(dest->object.type)->args); - arg = CParser_NewFuncArg(); - arg->type = TYPE(&stsignedshort); - arg->next = TYPE_FUNC(dest->object.type)->args->next; - TYPE_FUNC(dest->object.type)->args->next = arg; - } - - if (TYPE_FUNC(dest->object.type)->flags & FUNC_CONVERSION) { - CError_ASSERT(1665, IS_TYPE_FUNC(src->type)); - if (CTemplTool_IsTemplateArgumentDependentType(TYPE_FUNC(src->type)->functype)) { - CError_ASSERT(1668, action); - return; - } - } - - break; - - case DINLINEFUNC: - break; - - case DALIAS: - if (dest->object.u.alias.member && dest->object.u.alias.member->type == TYPE(deduce->tmclass)) { - dest->object.u.alias.member = CClass_GetPathCopy(dest->object.u.alias.member, 1); - dest->object.u.alias.member->type = TYPE(deduce->inst); - } - break; - - case DLOCAL: - case DEXPR: - CError_FATAL(1688); - - default: - CError_FATAL(1691); - } - - CScope_AddObject(deduce->inst->theclass.nspace, dest->object.name, OBJ_BASE(dest)); -} - -static void CTemplClass_CompleteObject(TypeDeduce *deduce, TemplateAction *action, ObjBase *refobj) { - if (refobj->otype == OT_MEMBERVAR) { - ObjMemberVar *ivar = OBJ_MEMBER_VAR(refobj); - ivar->type = CTemplTool_DeduceTypeCopy(deduce, ivar->type, &ivar->qual); - - if (ivar->type->size == 0) { - CDecl_CompleteType(ivar->type); - if (copts.experimental) { - if (ivar->next || ivar->type->size != 0 || !IS_TYPE_ARRAY(ivar->type)) - IsCompleteType(ivar->type); - } else { - IsCompleteType(ivar->type); - } - } - } else if (refobj->otype == OT_TYPE) { - ObjType *obj = OBJ_TYPE(refobj); - obj->type = CTemplTool_DeduceTypeCopy(deduce, obj->type, &obj->qual); - } else { - Object *dest; - Object *src; - - CError_ASSERT(1737, refobj->otype == OT_OBJECT); - - dest = OBJECT(refobj); - src = OBJECT(action->u.refobj); - - if (IS_TEMPL_FUNC(src->type)) { - TemplateFunction *templ = src->u.func.u.templ; - CError_ASSERT(1747, templ); - CError_ASSERT(1748, !deduce->x15); - - deduce->x15 = 1; - deduce->nindex = templ->params->pid.nindex; - dest->type = CTemplTool_DeduceTypeCopy(deduce, dest->type, &dest->qual); - deduce->x15 = 0; - - CError_ASSERT(1753, IS_TYPE_FUNC(dest->type)); - TYPE_FUNC(dest->type)->flags |= FUNC_IS_TEMPL; - } else { - dest->type = CTemplTool_DeduceTypeCopy(deduce, dest->type, &dest->qual); - dest->qual |= Q_IS_TEMPLATED; - - if (IS_TYPE_FUNC(dest->type)) - TYPE_FUNC(dest->type)->flags &= ~FUNC_DEFINED; - - switch (dest->datatype) { - case DFUNC: - case DVFUNC: - CError_ASSERT(1769, IS_TYPE_FUNC(dest->type)); - if (TYPE_FUNC(dest->type)->flags & FUNC_CONVERSION) { - CError_ASSERT(1772, IS_TYPE_FUNC(dest->type)); - if (CTemplTool_IsTemplateArgumentDependentType(TYPE_FUNC(src->type)->functype)) { - dest->name = CMangler_ConversionFuncName( - TYPE_FUNC(dest->type)->functype, TYPE_FUNC(dest->type)->qual); - CScope_AddObject(deduce->inst->theclass.nspace, dest->name, OBJ_BASE(dest)); - } - } - - if ((TYPE_FUNC(dest->type)->flags & FUNC_IS_CTOR) && deduce->x17) { - FuncArg *arg; - CError_ASSERT(1786, TYPE_FUNC(dest->type)->args); - arg = CParser_NewFuncArg(); - arg->type = TYPE(&stsignedshort); - arg->next = TYPE_FUNC(dest->type)->args->next; - TYPE_FUNC(dest->type)->args->next = arg; - } - - break; - } - } - } -} - -static void CTemplClass_CompleteObjectInit(TypeDeduce *deduce, TemplateAction *action, Object *object) { - ENode *expr = CTemplTool_DeduceExpr(deduce, action->u.objectinit.initexpr); - - if (ENODE_IS(expr, EINTCONST) && (object->qual & Q_CONST) && IS_TYPE_INT_OR_ENUM(object->type)) { - object->u.data.u.intconst = expr->data.intval; - object->qual |= Q_INLINE_DATA | Q_20000; - } else { - CError_Error(CErrorStr354, object->name->name); - } -} - -static void CTemplClass_CopyNameSpace(TypeDeduce *deduce, TemplClassInst *inst, TemplClass *templ) { - NameSpaceName *nsname; - NameSpaceObjectList *list; - - CError_ASSERT(1830, !templ->theclass.nspace->is_hash); - - for (nsname = templ->theclass.nspace->data.list; nsname; nsname = nsname->next) { - for (list = &nsname->first; list; list = list->next) { - switch (list->object->otype) { - case OT_ENUMCONST: - break; - case OT_MEMBERVAR: - if (OBJ_MEMBER_VAR(list->object)->has_path) - CTemplClass_CopyObjMemberVarPath(deduce, OBJ_MEMBER_VAR_PATH(list->object)); - break; - case OT_TYPE: - CTemplClass_CopyObjType(deduce, OBJ_TYPE(list->object), nsname->name); - break; - case OT_TYPETAG: - break; - case OT_NAMESPACE: - CError_FATAL(1854); - case OT_OBJECT: - CTemplClass_CopyObject(deduce, OBJECT(list->object)); - break; - default: - CError_FATAL(1861); - } - } - } -} - -static void CTemplClass_CopyUsingDecl(TypeDeduce *deduce, TypeTemplDep *type, AccessType access) { - TypeClass *tclass; - UInt32 qual = 0; - - CError_ASSERT(1878, IS_TYPE_TEMPLATE(type) && type->dtype == TEMPLDEP_QUALNAME); - - tclass = TYPE_CLASS(CTemplTool_DeduceTypeCopy(deduce, TYPE(type->u.qual.type), &qual)); - if (!IS_TYPE_CLASS(tclass)) { - CError_Error(CErrorStr340, type->u.qual.name->name); - return; - } - - CDecl_CompleteType(TYPE(tclass)); - CScope_AddClassUsingDeclaration(TYPE_CLASS(deduce->inst), tclass, type->u.qual.name, access); -} - -static void CTemplClass_CopyFriend(TypeDeduce *deduce, TemplateFriend *tfriend) { - TemplArg *arg; - Object *funcobj; - Boolean flag; - CScopeSave saveScope; - DeclInfo di; - - CDecl_UnpackDeclInfo(&di, &tfriend->decl); - - if (CTemplTool_IsTemplateArgumentDependentType(di.thetype)) - di.thetype = CTemplTool_DeduceTypeCopy(deduce, di.thetype, &di.qual); - - if (di.expltargs) { - di.expltargs = CTemplTool_MakeGlobalTemplArgCopy(di.expltargs); - for (arg = di.expltargs; arg; arg = arg->next) { - switch (arg->pid.type) { - case TPT_TYPE: - if (CTemplTool_IsTemplateArgumentDependentType(arg->data.typeparam.type)) - arg->data.typeparam.type = CTemplTool_DeduceTypeCopy(deduce, arg->data.typeparam.type, &arg->data.typeparam.qual); - break; - case TPT_NONTYPE: - if (CTemplTool_IsTemplateArgumentDependentExpression(arg->data.paramdecl.expr)) - arg->data.paramdecl.expr = CTemplTool_DeduceExpr(deduce, arg->data.paramdecl.expr); - break; - case TPT_TEMPLATE: - default: - CError_FATAL(1930); - } - } - } - - if (IS_TYPE_FUNC(di.thetype)) { - CScope_SetNameSpaceScope(CScope_FindGlobalNS(deduce->inst->theclass.nspace), &saveScope); - funcobj = CDecl_GetFunctionObject(&di, NULL, &flag, 0); - CScope_RestoreScope(&saveScope); - - if (funcobj) { - CDecl_AddFriend(TYPE_CLASS(deduce->inst), funcobj, NULL); - if (tfriend->stream.tokens) - CInline_AddInlineFunctionAction(funcobj, TYPE_CLASS(deduce->inst), &tfriend->fileoffset, &tfriend->stream, 0); - } else { - CError_Error(CErrorStr201); - } - } else { - CError_ASSERT(1963, IS_TYPE_CLASS(di.thetype)); - CDecl_AddFriend(TYPE_CLASS(deduce->inst), NULL, TYPE_CLASS(di.thetype)); - } -} - -Boolean CTempl_InstantiateTemplateClass(TypeClass *tclass) { - TemplClassInst *inst; - ParserTryBlock *tryBlock; - TemplateAction *action; - DefAction *defAction; - UInt8 saveAlignMode; - - TypeDeduce deduce; - TemplStack stack; - CScopeSave saveScope; - ClassLayout layout; - TemplClass *templ; - TStreamElement *saveErrorRef; - TemplArg *inst_args; - - CError_ASSERT(1989, tclass->flags & CLASS_IS_TEMPL_INST); - - if (tclass->flags & CLASS_COMPLETED) - return 1; - - inst = TEMPL_CLASS_INST(tclass); - if (inst->is_specialized) - return 0; - - templ = inst->templ; - if (!(templ->flags & TEMPLCLASS_FLAGS_2)) - templ = CTemplClass_GetMasterTemplate(templ); - - if (templ->pspecs && CTemplClass_FindPartialTemplate(inst->inst_args, &templ, &inst_args)) { - CError_ASSERT(2013, !inst->oargs); - inst->templ = templ; - inst->oargs = inst->inst_args; - inst->inst_args = inst_args; - } - - if (!(templ->theclass.flags & CLASS_COMPLETED)) - return 0; - - if (inst->is_instantiated) - return 0; - - inst->is_instantiated = 1; - CScope_SetClassScope(tclass, &saveScope); - CTemplTool_PushInstance(&stack, tclass, NULL); - - tryBlock = trychain; - trychain = NULL; - - memclrw(&deduce, sizeof(deduce)); - deduce.tmclass = templ; - deduce.inst = inst; - deduce.params = templ->templ__params; - deduce.args = inst->inst_args; - - CError_ASSERT(2045, !templ->theclass.sominfo); - CError_ASSERT(2047, !templ->theclass.objcinfo); - CError_ASSERT(2049, !templ->theclass.vtable); - - inst->theclass.flags |= templ->theclass.flags & - (CLASS_ABSTRACT | CLASS_SINGLE_OBJECT | CLASS_HAS_VBASES | CLASS_IS_CONVERTIBLE | CLASS_COM_OBJECT); - - CTemplClass_CopyBaseClasses(&deduce, inst, templ); - - deduce.x17 = (inst->theclass.flags & CLASS_HAS_VBASES) && !(templ->theclass.flags & CLASS_HAS_VBASES); - - for (action = templ->actions; action; action = action->next) { - switch (action->type) { - case TAT_NESTEDCLASS: - CTemplClass_SetupActionErrorRef(action, &saveErrorRef); - CTemplClass_CopyNestedClass(&deduce, action->u.tclasstype); - CTemplClass_RestoreActionErrorRef(&saveErrorRef); - break; - case TAT_ENUMTYPE: - CTemplClass_SetupActionErrorRef(action, &saveErrorRef); - CTemplClass_CopyEnum(&deduce, action); - CTemplClass_RestoreActionErrorRef(&saveErrorRef); - break; - case TAT_FRIEND: - case TAT_ENUMERATOR: - case TAT_BASE: - case TAT_OBJECTINIT: - case TAT_USINGDECL: - case TAT_OBJECTDEF: - break; - default: - CError_FATAL(2094); - } - } - - CTemplClass_CopyIVars(&deduce, inst, templ); - CTemplClass_CopyNameSpace(&deduce, inst, templ); - - CError_ASSERT(2105, !templ->theclass.friends); - - for (action = templ->actions; action; action = action->next) { - switch (action->type) { - case TAT_NESTEDCLASS: - break; - case TAT_ENUMTYPE: - for (defAction = deduce.defActions; defAction; defAction = defAction->next) { - if (defAction->action == action) { - CTemplClass_SetupActionErrorRef(action, &saveErrorRef); - CTemplClass_CompleteEnumType(&deduce, action, defAction->enumtype); - CTemplClass_RestoreActionErrorRef(&saveErrorRef); - break; - } - } - break; - case TAT_FRIEND: - CTemplClass_SetupActionErrorRef(action, &saveErrorRef); - CTemplClass_CopyFriend(&deduce, action->u.tfriend); - CTemplClass_RestoreActionErrorRef(&saveErrorRef); - break; - case TAT_ENUMERATOR: - break; - case TAT_BASE: - break; - case TAT_OBJECTINIT: - for (defAction = deduce.defActions; ; defAction = defAction->next) { - CError_ASSERT(2136, defAction); - if (defAction->action == action) { - CTemplClass_SetupActionErrorRef(action, &saveErrorRef); - CTemplClass_CompleteObjectInit(&deduce, action, OBJECT(defAction->refobj)); - CTemplClass_RestoreActionErrorRef(&saveErrorRef); - break; - } - } - break; - case TAT_USINGDECL: - CTemplClass_SetupActionErrorRef(action, &saveErrorRef); - CTemplClass_CopyUsingDecl(&deduce, action->u.usingdecl.type, action->u.usingdecl.access); - CTemplClass_RestoreActionErrorRef(&saveErrorRef); - break; - case TAT_OBJECTDEF: - for (defAction = deduce.defActions; ; defAction = defAction->next) { - CError_ASSERT(2156, defAction); - if (defAction->action == action) { - CTemplClass_SetupActionErrorRef(action, &saveErrorRef); - CTemplClass_CompleteObject(&deduce, action, defAction->refobj); - CTemplClass_RestoreActionErrorRef(&saveErrorRef); - break; - } - } - break; - } - } - - memclrw(&layout, sizeof(layout)); - layout.lex_order_count = templ->lex_order_count; - layout.has_vtable = templ->flags & TEMPLCLASS_HAS_VTABLE; - - saveAlignMode = copts.structalignment; - copts.structalignment = templ->align; - CDecl_CompleteClass(&layout, TYPE_CLASS(inst)); - copts.structalignment = saveAlignMode; - - if (templ->theclass.align > inst->theclass.align) { - inst->theclass.align = templ->theclass.align; - inst->theclass.size += CABI_StructSizeAlignValue(TYPE(inst), inst->theclass.size); - } - - CTemplTool_PopInstance(&stack); - CScope_RestoreScope(&saveScope); - trychain = tryBlock; - - return 1; -} |