summaryrefslogtreecommitdiff
path: root/compiler_and_linker/unsorted/CTemplateClass.c
diff options
context:
space:
mode:
authorAsh Wolf <ninji@wuffs.org>2023-01-26 11:30:47 +0000
committerAsh Wolf <ninji@wuffs.org>2023-01-26 11:30:47 +0000
commit094b96ca1df4a035b5f93c351f773306c0241f3f (patch)
tree95ce05e3ebe816c7ee7996206bb37ea17d8ca33c /compiler_and_linker/unsorted/CTemplateClass.c
parentfc0c4c0df7b583b55a08317cf1ef6a71d27c0440 (diff)
downloadMWCC-main.tar.gz
MWCC-main.zip
move lots of source files around to match their actual placement in the original treemain
Diffstat (limited to 'compiler_and_linker/unsorted/CTemplateClass.c')
-rw-r--r--compiler_and_linker/unsorted/CTemplateClass.c1632
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;
-}