summaryrefslogtreecommitdiff
path: root/compiler_and_linker/unsorted/CTemplateTools.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/CTemplateTools.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/CTemplateTools.c')
-rw-r--r--compiler_and_linker/unsorted/CTemplateTools.c1962
1 files changed, 0 insertions, 1962 deletions
diff --git a/compiler_and_linker/unsorted/CTemplateTools.c b/compiler_and_linker/unsorted/CTemplateTools.c
deleted file mode 100644
index 0e77e74..0000000
--- a/compiler_and_linker/unsorted/CTemplateTools.c
+++ /dev/null
@@ -1,1962 +0,0 @@
-#include "compiler/CTemplateTools.h"
-#include "compiler/CABI.h"
-#include "compiler/CDecl.h"
-#include "compiler/CError.h"
-#include "compiler/CExpr.h"
-#include "compiler/CFunc.h"
-#include "compiler/CInline.h"
-#include "compiler/CInt64.h"
-#include "compiler/CMachine.h"
-#include "compiler/CParser.h"
-#include "compiler/CScope.h"
-#include "compiler/CTemplateClass.h"
-#include "compiler/CTemplateNew.h"
-#include "compiler/CompilerTools.h"
-#include "compiler/enode.h"
-#include "compiler/objects.h"
-#include "compiler/scopes.h"
-#include "compiler/templates.h"
-#include "compiler/types.h"
-
-short ctempl_instdepth;
-
-void CTemplTool_PushInstance(TemplStack *stack, TypeClass *tmclass, Object *func) {
- if (tmclass) {
- stack->u.theclass = tmclass;
- stack->is_func = 0;
- } else {
- stack->u.func = func;
- stack->is_func = 1;
- }
- stack->next = ctempl_curinstance;
- ctempl_curinstance = stack;
-
- if (++ctempl_instdepth >= 64)
- CError_ErrorTerm(CErrorStr314);
-}
-
-void CTemplTool_PopInstance(TemplStack *stack) {
- CError_ASSERT(53, ctempl_curinstance == stack);
-
- ctempl_curinstance = stack->next;
- if (--ctempl_instdepth < 0)
- ctempl_instdepth = 0;
-}
-
-ENode *CTempTool_GetPTMTemplArgExpr(ENode *expr, Type *type) {
- NameSpaceObjectList *list;
-
- CError_ASSERT(69, ENODE_IS(expr, EMEMBER));
- CError_ASSERT(70, IS_TYPE_MEMBERPOINTER(type));
-
- if (!copts.cpp_extensions) {
- if (!expr->data.emember->x11 || !expr->data.emember->pr_1D)
- CError_Warning(CErrorStr331);
- }
-
- type = TYPE_MEMBER_POINTER(type)->ty1;
- for (list = expr->data.emember->list; list; list = list->next) {
- if (list->object->otype == OT_MEMBERVAR) {
- if (!is_typeequal(OBJ_MEMBER_VAR(list->object)->type, type))
- CError_Error(CErrorStr146);
- return expr;
- }
-
- if (list->object->otype == OT_OBJECT && is_memberpointerequal(OBJECT(list->object)->type, type)) {
- if (expr->data.emember->list != list || list->next) {
- // rewrite the EMEMBER to contain just one node
- expr->data.emember->list = galloc(sizeof(NameSpaceObjectList));
- *expr->data.emember->list = *list;
- expr->data.emember->list->next = NULL;
- }
- break;
- }
- }
-
- if (!list)
- CError_Error(CErrorStr146);
-
- return expr;
-}
-
-Boolean CTemplTool_InitDeduceInfo(DeduceInfo *info, TemplParam *params, TemplArg *args, Boolean flag) {
- int i;
- TemplArg *buffer;
- TemplParam *param;
-
- if (!params) {
- info->args = info->argBuffer;
- info->maxCount = 0;
- info->x12C = 0xFF;
- return 1;
- }
-
- memclrw(info, sizeof(DeduceInfo));
-
- i = 0;
- param = params;
- while (param) {
- param = param->next;
- i++;
- }
-
- if (i > 16) {
- buffer = lalloc(i * sizeof(TemplArg));
- memclrw(buffer, i * sizeof(TemplArg));
- } else {
- buffer = info->argBuffer;
- }
- info->args = buffer;
- info->maxCount = i;
- info->x12C = params->pid.nindex;
-
- for (param = params, i = 0; param; param = param->next, i++)
- buffer[i].pid = param->pid;
-
- i = 0;
- param = params;
- while (args) {
- if (!param || param->pid.type != args->pid.type)
- return 0;
-
- buffer[i].data = args->data;
- if (i > 0)
- buffer[i - 1].next = &buffer[i];
- buffer[i].next = NULL;
- buffer[i].is_deduced = 1;
- info->count++;
-
- if (param->pid.type == TPT_NONTYPE && !CTemplTool_IsTemplateArgumentDependentType(param->data.paramdecl.type)) {
- if (CExpr_CanImplicitlyConvert(buffer[i].data.paramdecl.expr, param->data.paramdecl.type, param->data.paramdecl.qual)) {
- buffer[i].data.paramdecl.expr = CExpr_AssignmentPromotion(
- buffer[i].data.paramdecl.expr, param->data.paramdecl.type, param->data.paramdecl.qual, 0);
- } else {
- return 0;
- }
- }
-
- args = args->next;
- param = param->next;
- i++;
- }
-
- if (flag) {
- for (param = params, i = 0; param; param = param->next, i++) {
- if (!buffer[i].is_deduced && !param->name) {
- switch (param->pid.type) {
- case TPT_TYPE:
- buffer[i].data.typeparam.type = &stvoid;
- break;
- case TPT_NONTYPE:
- buffer[i].data.paramdecl.expr = nullnode();
- break;
- case TPT_TEMPLATE:
- default:
- CError_FATAL(208);
- }
- buffer[i].is_deduced = 1;
- }
- }
- }
-
- return 1;
-}
-
-void CTemplTool_InsertTemplateParameter(NameSpace *nspace, TemplParam *param) {
- Type *type;
- ObjType *obj;
- NameSpaceName *nsn;
-
- type = CDecl_NewTemplDepType(TEMPLDEP_ARGUMENT);
- TYPE_TEMPLATE(type)->u.pid = param->pid;
-
- obj = galloc(sizeof(ObjType));
- memclrw(obj, sizeof(ObjType));
- obj->otype = OT_TYPE;
- obj->access = ACCESSPUBLIC;
- obj->type = type;
-
- for (nsn = nspace->tparams; nsn; nsn = nsn->next) {
- if (nsn->name == param->name) {
- CError_Error(CErrorStr122, param->name->name);
- return;
- }
- }
-
- nsn = galloc(sizeof(NameSpaceName));
- memclrw(nsn, sizeof(NameSpaceName));
-
- nsn->name = param->name;
- nsn->first.object = OBJ_BASE(obj);
-
- nsn->next = nspace->tparams;
- nspace->tparams = nsn;
-}
-
-TemplArg *CTemplTool_MakeTemplArgList(DeduceInfo *info) {
- TemplArg *args;
- TemplArg *last;
- int i;
-
- for (i = 0; i < info->maxCount; i++) {
- if (i) {
- last->next = galloc(sizeof(TemplArg));
- last = last->next;
- } else {
- args = last = galloc(sizeof(TemplArg));
- }
-
- *last = info->args[i];
- }
-
- last->next = NULL;
- return args;
-}
-
-Boolean CTemplTool_IsIdenticalTemplArgList(TemplArg *args, TemplParam *params) {
- while (args) {
- if (!params)
- return 0;
-
- CError_ASSERT(297, params->pid.type == args->pid.type);
-
- switch (args->pid.type) {
- case TPT_TYPE:
- if (
- !IS_TYPE_TEMPLATE(args->data.typeparam.type) ||
- TYPE_TEMPLATE(args->data.typeparam.type)->dtype != TEMPLDEP_ARGUMENT ||
- TYPE_TEMPLATE(args->data.typeparam.type)->u.pid.index != params->pid.index ||
- TYPE_TEMPLATE(args->data.typeparam.type)->u.pid.nindex != params->pid.nindex
- )
- return 0;
- break;
- case TPT_NONTYPE:
- if (
- !ENODE_IS(args->data.paramdecl.expr, ETEMPLDEP) ||
- args->data.paramdecl.expr->data.templdep.subtype != TDE_PARAM ||
- args->data.paramdecl.expr->data.templdep.u.pid.index != params->pid.index ||
- args->data.paramdecl.expr->data.templdep.u.pid.nindex != params->pid.nindex
- )
- return 0;
- break;
- case TPT_TEMPLATE:
- if (
- !IS_TYPE_TEMPLATE(args->data.ttargtype) ||
- TYPE_TEMPLATE(args->data.ttargtype)->dtype != TEMPLDEP_ARGUMENT ||
- TYPE_TEMPLATE(args->data.ttargtype)->u.pid.index != params->pid.index ||
- TYPE_TEMPLATE(args->data.ttargtype)->u.pid.nindex != params->pid.nindex
- )
- return 0;
- break;
- default:
- CError_FATAL(331);
- }
-
- args = args->next;
- params = params->next;
- }
-
- return !params;
-}
-
-Type *CTemplTool_GetSelfRefTemplate(Type *type) {
- TemplClass *templ;
- TemplArg *args;
-
- CError_ASSERT(347, IS_TYPE_TEMPLATE(type));
-
- if (TYPE_TEMPLATE(type)->dtype == TEMPLDEP_TEMPLATE) {
- if (CTemplTool_IsIdenticalTemplArgList(
- TYPE_TEMPLATE(type)->u.templ.args,
- TYPE_TEMPLATE(type)->u.templ.templ->templ__params))
- return TYPE(TYPE_TEMPLATE(type)->u.templ.templ);
-
- if (TYPE_TEMPLATE(type)->u.templ.templ->pspecs) {
- templ = TYPE_TEMPLATE(type)->u.templ.templ;
- if (
- CTemplClass_FindPartialTemplate(TYPE_TEMPLATE(type)->u.templ.args, &templ, &args) &&
- CTemplTool_IsIdenticalTemplArgList(args, templ->templ__params)
- )
- return TYPE(templ);
- }
-
- return NULL;
- }
-
- if (TYPE_TEMPLATE(type)->dtype == TEMPLDEP_QUALNAME) {
- Type *t = CTemplTool_GetSelfRefTemplate(TYPE(TYPE_TEMPLATE(type)->u.qual.type));
- if (
- t &&
- (t = CScope_GetLocalTagType(TYPE_CLASS(t)->nspace, TYPE_TEMPLATE(type)->u.qual.name)) &&
- IS_TEMPL_CLASS(t) &&
- !TEMPL_CLASS(t)->templ__params
- )
- return t;
-
- return NULL;
- }
-
- if (TYPE_TEMPLATE(type)->dtype == TEMPLDEP_QUALTEMPL) {
- Type *t;
-
- CError_ASSERT(389, TYPE_TEMPLATE(TYPE_TEMPLATE(type)->u.qualtempl.type)->dtype == TEMPLDEP_QUALNAME);
-
- t = CTemplTool_GetSelfRefTemplate(TYPE(TYPE_TEMPLATE(TYPE_TEMPLATE(type)->u.qualtempl.type)->u.qual.type));
- if (
- t &&
- (t = CScope_GetLocalTagType(TYPE_CLASS(t)->nspace, TYPE_TEMPLATE(TYPE_TEMPLATE(type)->u.qualtempl.type)->u.qual.name)) &&
- IS_TEMPL_CLASS(t)
- )
- {
- TemplClass *tm = TEMPL_CLASS(t);
- if (CTemplTool_IsIdenticalTemplArgList(TYPE_TEMPLATE(type)->u.qualtempl.args, tm->templ__params))
- return TYPE(tm);
- }
- }
-
- return NULL;
-}
-
-TemplateFunction *CTemplTool_GetFuncTempl(Object *object) {
- while (object->datatype == DALIAS)
- object = object->u.alias.object;
-
- CError_ASSERT(416, IS_TEMPL_FUNC(object->type));
- return object->u.func.u.templ;
-}
-
-Boolean CTemplTool_ParamHasDefaultArg(TemplParam *param) {
- switch (param->pid.type) {
- case TPT_TYPE:
- return param->data.typeparam.type != NULL;
- case TPT_NONTYPE:
- return param->data.paramdecl.defaultarg != NULL;
- case TPT_TEMPLATE:
- default:
- CError_FATAL(438);
- return 0;
- }
-}
-
-void CTemplTool_MergeDefaultArgs(TemplParam *dest, TemplParam *src) {
- while (1) {
- if (!dest) {
- CError_ASSERT(455, !src);
- return;
- }
-
- CError_ASSERT(458, src);
- CError_ASSERT(459, dest->pid.type == src->pid.type);
-
- switch (dest->pid.type) {
- case TPT_TYPE:
- if (!dest->data.typeparam.type && src->data.typeparam.type)
- dest->data = src->data;
- break;
- case TPT_NONTYPE:
- if (!dest->data.paramdecl.defaultarg && src->data.paramdecl.defaultarg)
- dest->data = src->data;
- break;
- case TPT_TEMPLATE:
- if (!dest->data.templparam.defaultarg && src->data.templparam.defaultarg)
- dest->data = src->data;
- break;
- default:
- CError_FATAL(484);
- }
-
- dest = dest->next;
- src = src->next;
- }
-}
-
-static FuncArg *CTemplTool_GetFirstRealArg(TypeFunc *tfunc) {
- FuncArg *arg = tfunc->args;
-
- if (IS_TYPEFUNC_NONSTATIC_METHOD(tfunc)) {
- CError_ASSERT(502, arg);
- arg = arg->next;
- if ((tfunc->flags & FUNC_IS_CTOR) && (TYPE_METHOD(tfunc)->theclass->flags & CLASS_HAS_VBASES)) {
- CError_ASSERT(507, arg);
- arg = arg->next;
- }
- }
-
- return arg;
-}
-
-void CTemplTool_MergeArgNames(TypeFunc *src, TypeFunc *dest) {
- FuncArg *destArg;
- FuncArg *srcArg;
-
- CError_ASSERT(524, IS_TYPE_FUNC(dest) && IS_TYPE_FUNC(src));
-
- srcArg = CTemplTool_GetFirstRealArg(src);
- destArg = CTemplTool_GetFirstRealArg(dest);
-
- while (1) {
- if (!srcArg || !destArg || srcArg == &elipsis || destArg == &elipsis) {
- CError_ASSERT(531, srcArg == destArg);
- break;
- }
-
- destArg->name = srcArg->name;
- srcArg = srcArg->next;
- destArg = destArg->next;
- }
-
- if (IS_TYPEFUNC_NONSTATIC_METHOD(dest)) {
- CError_ASSERT(538, destArg = dest->args);
- if (!destArg->name)
- destArg->name = this_name_node;
- }
-}
-
-Boolean CTemplTool_EqualParams(TemplParam *a, TemplParam *b, Boolean copyNames) {
- while (1) {
- if (!a)
- return !b;
- if (!b)
- return 0;
-
- if (a->pid.type != b->pid.type)
- return 0;
-
- if (copyNames)
- a->name = b->name;
-
- switch (a->pid.type) {
- case TPT_TYPE:
- break;
- case TPT_NONTYPE:
- if (
- !is_typesame(a->data.paramdecl.type, b->data.paramdecl.type) ||
- a->data.paramdecl.qual != b->data.paramdecl.qual
- )
- return 0;
- break;
- case TPT_TEMPLATE:
- break;
- default:
- CError_FATAL(576);
- }
-
- a = a->next;
- b = b->next;
- }
-}
-
-NameSpace *CTemplTool_SetupTemplateArgumentNameSpace(TemplParam *params, TemplArg *args, Boolean is_global) {
- NameSpace *nspace;
- Boolean clear_global;
- ObjType *objType;
- Object *object;
-
- clear_global = 0;
- if (!is_global && trychain) {
- clear_global = 1;
- is_global = 1;
- }
-
- nspace = CScope_NewListNameSpace(NULL, is_global);
- nspace->is_templ = 1;
-
- if (clear_global)
- nspace->is_global = 0;
-
- if (!params)
- return nspace;
-
- while (params) {
- CError_ASSERT(607, args);
-
- if (params->name) {
- switch (args->pid.type) {
- case TPT_TYPE:
- if (is_global) {
- objType = galloc(sizeof(ObjType));
- memclrw(objType, sizeof(ObjType));
- } else {
- objType = lalloc(sizeof(ObjType));
- memclrw(objType, sizeof(ObjType));
- }
- objType->otype = OT_TYPE;
- objType->access = ACCESSPUBLIC;
- objType->type = args->data.typeparam.type;
- objType->qual = args->data.typeparam.qual;
- CScope_AddObject(nspace, params->name, OBJ_BASE(objType));
- break;
- case TPT_NONTYPE:
- if (is_global) {
- object = galloc(sizeof(Object));
- memclrw(object, sizeof(Object));
- } else {
- object = lalloc(sizeof(Object));
- memclrw(object, sizeof(Object));
- }
- object->otype = OT_OBJECT;
- object->access = ACCESSPUBLIC;
- object->nspace = nspace;
- object->name = params->name;
- object->type = args->data.paramdecl.expr->rtype;
- object->qual = ENODE_QUALS(args->data.paramdecl.expr);
- object->datatype = DEXPR;
- object->u.expr = args->data.paramdecl.expr;
- if (IS_TYPE_REFERENCE(params->data.paramdecl.type)) {
- CError_ASSERT(652, IS_TYPE_POINTER_ONLY(object->u.expr->rtype));
- object->u.expr = makemonadicnode(object->u.expr, EINDIRECT);
- object->u.expr->rtype = TPTR_TARGET(params->data.paramdecl.type);
- }
- if (is_global)
- object->u.expr = CInline_CopyExpression(object->u.expr, CopyMode1);
- CScope_AddObject(nspace, params->name, OBJ_BASE(object));
- break;
- case TPT_TEMPLATE:
- if (is_global) {
- objType = galloc(sizeof(ObjType));
- memclrw(objType, sizeof(ObjType));
- } else {
- objType = lalloc(sizeof(ObjType));
- memclrw(objType, sizeof(ObjType));
- }
- objType->otype = OT_TYPE;
- objType->access = ACCESSPUBLIC;
- objType->type = args->data.ttargtype;
- objType->qual = 0;
- CScope_AddObject(nspace, params->name, OBJ_BASE(objType));
- break;
- default:
- CError_FATAL(681);
- }
- }
-
- params = params->next;
- args = args->next;
- }
-
- CError_ASSERT(685, !args);
-
- return nspace;
-}
-
-void CTemplTool_SetupOuterTemplateArgumentNameSpace(NameSpace *nspace) {
- NameSpace *newns;
-
- while (nspace) {
- if (nspace->theclass && (nspace->theclass->flags & CLASS_IS_TEMPL_INST)) {
- newns = CTemplTool_SetupTemplateArgumentNameSpace(
- TEMPL_CLASS_INST(nspace->theclass)->templ->templ__params,
- TEMPL_CLASS_INST(nspace->theclass)->inst_args,
- 0);
- newns->parent = nspace->parent;
- nspace->parent = newns;
- }
-
- nspace = nspace->parent;
- }
-}
-
-NameSpace *CTemplTool_InsertTemplateArgumentNameSpace(TemplParam *params, TemplClassInst *inst, CScopeSave *save) {
- NameSpace *nspace = CTemplTool_SetupTemplateArgumentNameSpace(params, inst->inst_args, 0);
-
- nspace->parent = inst->theclass.nspace->parent;
- inst->theclass.nspace->parent = nspace;
-
- CTemplTool_SetupOuterTemplateArgumentNameSpace(nspace);
- CScope_SetNameSpaceScope(inst->theclass.nspace, save);
-
- return nspace;
-}
-
-void CTemplTool_RemoveOuterTemplateArgumentNameSpace(NameSpace *nspace) {
- while (nspace->parent) {
- if (nspace->theclass && (nspace->theclass->flags & CLASS_IS_TEMPL_INST) && nspace->parent->is_templ)
- nspace->parent = nspace->parent->parent;
- nspace = nspace->parent;
- }
-}
-
-void CTemplTool_RemoveTemplateArgumentNameSpace(NameSpace *nspace, TemplClassInst *inst, CScopeSave *save) {
- CTemplTool_RemoveOuterTemplateArgumentNameSpace(inst->theclass.nspace);
- CScope_RestoreScope(save);
-}
-
-Boolean CTemplTool_IsTemplateArgumentDependentType(Type *type) {
- FuncArg *arg;
-
- while (1) {
- switch (type->type) {
- case TYPETEMPLATE:
- return 1;
- case TYPEVOID:
- case TYPEINT:
- case TYPEFLOAT:
- case TYPEENUM:
- case TYPESTRUCT:
- return 0;
- case TYPECLASS:
- return (TYPE_CLASS(type)->flags & CLASS_IS_TEMPL) ? 1 : 0;
- case TYPEMEMBERPOINTER:
- if (CTemplTool_IsTemplateArgumentDependentType(TYPE_MEMBER_POINTER(type)->ty1))
- return 1;
- type = TYPE_MEMBER_POINTER(type)->ty2;
- continue;
- case TYPEPOINTER:
- case TYPEARRAY:
- type = TPTR_TARGET(type);
- continue;
- case TYPEFUNC:
- for (arg = TYPE_FUNC(type)->args; arg && arg != &elipsis && arg != &oldstyle; arg = arg->next) {
- if (CTemplTool_IsTemplateArgumentDependentType(arg->type))
- return 1;
- }
- type = TYPE_FUNC(type)->functype;
- continue;
- case TYPEBITFIELD:
- type = TYPE_BITFIELD(type)->bitfieldtype;
- continue;
- case TYPETEMPLDEPEXPR:
- return 1;
- default:
- CError_FATAL(822);
- }
- }
-}
-
-Boolean CTemplTool_IsTemplateArgumentDependentExpression(ENode *expr) {
- if (!expr)
- return 0;
-
- if (IS_TYPE_TEMPLDEPEXPR(expr->rtype))
- return 1;
-
- return 0;
-}
-
-Boolean CTemplTool_IsSameTemplate(TemplParam *params, TemplArg *args) {
- while (1) {
- if (!args) {
- CError_ASSERT(850, !params);
- return 1;
- }
-
- CError_ASSERT(853, params && args->pid.type == params->pid.type);
-
- switch (args->pid.type) {
- case TPT_TYPE:
- if (
- !IS_TYPE_TEMPLATE(args->data.typeparam.type) ||
- TYPE_TEMPLATE(args->data.typeparam.type)->dtype != TEMPLDEP_ARGUMENT ||
- TYPE_TEMPLATE(args->data.typeparam.type)->u.pid.nindex != params->pid.nindex ||
- TYPE_TEMPLATE(args->data.typeparam.type)->u.pid.index != params->pid.index ||
- args->data.typeparam.qual != 0
- )
- return 0;
- break;
- case TPT_NONTYPE:
- if (
- !ENODE_IS(args->data.paramdecl.expr, ETEMPLDEP) ||
- args->data.paramdecl.expr->data.templdep.subtype != TDE_PARAM ||
- args->data.paramdecl.expr->data.templdep.u.pid.nindex != params->pid.nindex ||
- args->data.paramdecl.expr->data.templdep.u.pid.index != params->pid.index
- )
- return 0;
- break;
- case TPT_TEMPLATE:
- if (!IS_TYPE_TEMPLATE(args->data.ttargtype))
- return 0;
- break;
- default:
- CError_FATAL(886);
- }
-
- args = args->next;
- params = params->next;
- }
-}
-
-TemplClass *CTemplTool_IsTemplate(TypeTemplDep *ttd) {
- if (ttd->dtype == TEMPLDEP_QUALNAME && ttd->u.qual.type->dtype == TEMPLDEP_TEMPLATE)
- ttd = ttd->u.qual.type;
- else if (ttd->dtype != TEMPLDEP_TEMPLATE)
- return NULL;
-
- if (CTemplTool_IsSameTemplate(ttd->u.templ.templ->templ__params, ttd->u.templ.args))
- return ttd->u.templ.templ;
- else
- return NULL;
-}
-
-Type *CTemplTool_IsDependentTemplate(TemplClass *tmclass, TemplArg *args) {
- TemplParam *param;
- TemplArg *arg;
- Type *type;
-
- if (!tmclass->templ_parent || tmclass->inst_parent) {
- arg = args;
- param = tmclass->templ__params;
- while (1) {
- if (!arg) {
- CError_ASSERT(988, !param);
- return NULL;
- }
-
- CError_ASSERT(991, param && arg->pid.type == param->pid.type);
-
- switch (arg->pid.type) {
- case TPT_TYPE:
- if (CTemplTool_IsTemplateArgumentDependentType(arg->data.typeparam.type))
- goto done;
- break;
- case TPT_NONTYPE:
- if (CTemplTool_IsTemplateArgumentDependentExpression(arg->data.paramdecl.expr))
- goto done;
- break;
- case TPT_TEMPLATE:
- if (!IS_TYPE_CLASS(arg->data.ttargtype) && CTemplTool_IsTemplateArgumentDependentType(arg->data.ttargtype))
- goto done;
- break;
- default:
- CError_FATAL(1008);
- goto done;
- }
-
- arg = arg->next;
- param = param->next;
- }
- }
-done:
- if (cscope_current->theclass == TYPE_CLASS(tmclass) && CTemplTool_IsSameTemplate(tmclass->templ__params, args))
- return TYPE(tmclass);
-
- type = CDecl_NewTemplDepType(TEMPLDEP_TEMPLATE);
- TYPE_TEMPLATE(type)->u.templ.templ = tmclass;
- TYPE_TEMPLATE(type)->u.templ.args = args;
- return type;
-}
-
-Boolean CTemplTool_EqualExprTypes(ENode *a, ENode *b) {
- Object *objA;
- Object *objB;
-
- if (!a || !b)
- return 0;
- if (a->type != b->type)
- return 0;
-
- switch (a->type) {
- case EINTCONST:
- return CInt64_Equal(a->data.intval, b->data.intval);
- case EOBJREF:
- objA = a->data.objref;
- while (objA->datatype == DALIAS)
- objA = objA->u.alias.object;
- objB = b->data.objref;
- while (objB->datatype == DALIAS)
- objB = objB->u.alias.object;
- return objA == objB;
- case EMEMBER:
- return a->data.emember->list == b->data.emember->list;
- case ETEMPLDEP:
- if (a->data.templdep.subtype != b->data.templdep.subtype)
- return 0;
-
- switch (a->data.templdep.subtype) {
- case TDE_PARAM:
- return a->data.templdep.u.pid.nindex == b->data.templdep.u.pid.nindex &&
- a->data.templdep.u.pid.index == b->data.templdep.u.pid.index;
- case TDE_SIZEOF:
- case TDE_ALIGNOF:
- return is_typesame(a->data.templdep.u.typeexpr.type, b->data.templdep.u.typeexpr.type);
- case TDE_CAST:
- return is_typesame(a->data.templdep.u.cast.type, b->data.templdep.u.cast.type) &&
- a->data.templdep.u.cast.qual == b->data.templdep.u.cast.qual;
- case TDE_QUALNAME:
- return is_typesame(TYPE(a->data.templdep.u.qual.type), TYPE(b->data.templdep.u.qual.type)) &&
- a->data.templdep.u.qual.name == b->data.templdep.u.qual.name;
- case TDE_OBJ:
- return a->data.templdep.u.obj == b->data.templdep.u.obj;
- case TDE_ADDRESS_OF:
- return CTemplTool_EqualExprTypes(a->data.templdep.u.monadic, b->data.templdep.u.monadic);
- default:
- CError_FATAL(1086);
- }
- case EMUL:
- case EDIV:
- case EMODULO:
- case EADD:
- case ESUB:
- case ESHL:
- case ESHR:
- case ELESS:
- case EGREATER:
- case ELESSEQU:
- case EGREATEREQU:
- case EEQU:
- case ENOTEQU:
- case EAND:
- case EXOR:
- case EOR:
- case ELAND:
- case ELOR:
- case EROTL:
- case EROTR:
- return CTemplTool_EqualExprTypes(a->data.diadic.left, b->data.diadic.left) &&
- CTemplTool_EqualExprTypes(a->data.diadic.right, b->data.diadic.right);
- case EMONMIN:
- case EBINNOT:
- case ELOGNOT:
- return CTemplTool_EqualExprTypes(a->data.monadic, b->data.monadic);
- case ECOND:
- return CTemplTool_EqualExprTypes(a->data.cond.cond, b->data.cond.cond) &&
- CTemplTool_EqualExprTypes(a->data.cond.expr1, b->data.cond.expr1) &&
- CTemplTool_EqualExprTypes(a->data.cond.expr2, b->data.cond.expr2);
- default:
- CError_FATAL(1122);
- return 0;
- }
-}
-
-ENode *CTempl_MakeTemplDepExpr(ENode *left, ENodeType nt, ENode *right) {
- if (!IS_TYPE_TEMPLDEPEXPR(right->rtype)) {
- right = pointer_generation(right);
- if (!ENODE_IS(right, EINTCONST)) {
- CError_Error(CErrorStr348);
- right = nullnode();
- }
- }
-
- if (left) {
- if (!IS_TYPE_TEMPLDEPEXPR(left->rtype)) {
- left = pointer_generation(left);
- if (!ENODE_IS(left, EINTCONST)) {
- CError_Error(CErrorStr348);
- left = nullnode();
- }
- }
-
- left = makediadicnode(left, right, nt);
- } else {
- left = makemonadicnode(right, nt);
- }
-
- left->rtype = &sttemplexpr;
- return left;
-}
-
-void CTemplTool_CheckTemplArgType(Type *type) {
- while (IS_TYPE_POINTER_ONLY(type))
- type = TPTR_TARGET(type);
-
- if (IS_TYPE_CLASS(type)) {
- if (IsTempName(TYPE_CLASS(type)->classname) || CScope_IsInLocalNameSpace(TYPE_CLASS(type)->nspace))
- CError_Error(CErrorStr232);
- }
-}
-
-Boolean CTemplTool_EqualArgs(TemplArg *a, TemplArg *b) {
- while (a) {
- if (!b || a->pid.type != b->pid.type)
- return 0;
-
- switch (a->pid.type) {
- case TPT_TYPE:
- if (
- !is_typesame(a->data.typeparam.type, b->data.typeparam.type) ||
- a->data.typeparam.qual != b->data.typeparam.qual
- )
- return 0;
- break;
- case TPT_NONTYPE:
- if (!CTemplTool_EqualExprTypes(a->data.paramdecl.expr, b->data.paramdecl.expr))
- return 0;
- break;
- case TPT_TEMPLATE:
- if (!is_typesame(a->data.ttargtype, b->data.ttargtype))
- return 0;
- break;
- default:
- CError_FATAL(1215);
- }
-
- a = a->next;
- b = b->next;
- }
-
- if (b)
- return 0;
-
- return 1;
-}
-
-TemplArg *CTemplTool_MakeGlobalTemplArgCopy(TemplArg *args) {
- TemplArg *firstCopy;
- TemplArg *copy;
-
- firstCopy = NULL;
- while (args) {
- if (firstCopy) {
- copy->next = galloc(sizeof(TemplArg));
- copy = copy->next;
- } else {
- copy = galloc(sizeof(TemplArg));
- firstCopy = copy;
- }
-
- *copy = *args;
- if (copy->pid.type == TPT_NONTYPE && copy->data.paramdecl.expr)
- copy->data.paramdecl.expr = CInline_CopyExpression(copy->data.paramdecl.expr, CopyMode1);
-
- args = args->next;
- }
-
- return firstCopy;
-}
-
-Boolean CTemplTool_TemplDepTypeCompare(TypeTemplDep *a, TypeTemplDep *b) {
- if (a == b)
- return 1;
- if (a->dtype != b->dtype)
- return 0;
-
- switch (a->dtype) {
- case TEMPLDEP_ARGUMENT:
- return a->u.pid.nindex == b->u.pid.nindex &&
- a->u.pid.index == b->u.pid.index;
- case TEMPLDEP_QUALNAME:
- return CTemplTool_TemplDepTypeCompare(a->u.qual.type, b->u.qual.type) &&
- a->u.qual.name == b->u.qual.name;
- case TEMPLDEP_TEMPLATE:
- return a->u.templ.templ == b->u.templ.templ &&
- CTemplTool_EqualArgs(a->u.templ.args, b->u.templ.args);
- case TEMPLDEP_ARRAY:
- return is_typesame(a->u.array.type, b->u.array.type) &&
- CTemplTool_EqualExprTypes(a->u.array.index, b->u.array.index);
- case TEMPLDEP_QUALTEMPL:
- return CTemplTool_TemplDepTypeCompare(a->u.qualtempl.type, b->u.qualtempl.type) &&
- CTemplTool_EqualArgs(a->u.qualtempl.args, b->u.qualtempl.args);
- case TEMPLDEP_BITFIELD:
- return is_typesame(a->u.bitfield.type, b->u.bitfield.type) &&
- CTemplTool_EqualExprTypes(a->u.bitfield.size, b->u.bitfield.size);
- default:
- CError_FATAL(1286);
- return 0;
- }
-}
-
-Type *CTemplTool_DeduceArgDepType(TemplArg *args, Type *type, UInt32 qual, UInt32 *resultQual) {
- TemplArg *arg;
-
- *resultQual = qual;
-
- if (IS_TYPE_TEMPLATE(type) && TYPE_TEMPLATE(type)->dtype == TEMPLDEP_ARGUMENT) {
- arg = args;
- while (1) {
- if (!arg)
- return NULL;
-
- if (
- arg->pid.index == TYPE_TEMPLATE(type)->u.pid.index &&
- arg->pid.nindex == TYPE_TEMPLATE(type)->u.pid.nindex
- )
- break;
-
- arg = arg->next;
- }
-
- CError_ASSERT(1314, arg->pid.type == TPT_TYPE);
- *resultQual |= arg->data.typeparam.qual;
- return arg->data.typeparam.type;
- }
-
- return NULL;
-}
-
-static TemplClassInst *CTemplTool_FindNestedClassInstance(TemplClass *a, TemplClass *b, TemplClassInst *c) {
- TemplClass *array[32];
- TemplClassInst *inst;
- int i;
-
- array[0] = a;
- i = 0;
- while (1) {
- CError_ASSERT(1338, i < 32);
- CError_ASSERT(1339, a = a->templ_parent);
-
- if (a == b)
- break;
-
- CError_ASSERT(1341, a->templ__params == NULL);
-
- array[++i] = a;
- }
-
- while (1) {
- inst = array[i--]->instances;
- while (1) {
- CError_ASSERT(1350, inst);
- if (inst->parent == c)
- break;
- inst = inst->next;
- }
-
- c = inst;
- if (i < 0)
- break;
-
- if ((inst->theclass.flags & (CLASS_COMPLETED | CLASS_IS_TEMPL_INST)) == CLASS_IS_TEMPL_INST)
- CTempl_InstantiateTemplateClass(TYPE_CLASS(inst));
- }
-
- return inst;
-}
-
-static TemplClassInst *CTemplTool_FindNestedClass(TemplClass *a, TemplClassInst *b, TemplClass *c) {
- TemplClass *scan;
-
- while (1) {
- for (scan = c->templ_parent; scan; scan = scan->templ_parent) {
- if (scan == a)
- return CTemplTool_FindNestedClassInstance(c, a, b);
- }
-
- a = a->templ_parent;
- if (!a)
- break;
-
- b = b->parent;
- CError_ASSERT(1377, b);
- }
-
- return NULL;
-}
-
-static Type *CTemplTool_FindTemplateInstance(TypeDeduce *deduce, TemplClass *templ) {
- TemplClass *scantempl;
- TemplClass *dtempl;
- TemplClassInst *scaninst;
- TemplClassInst *dinst;
-
- dtempl = deduce->tmclass;
- CError_ASSERT(1393, dtempl);
-
- dinst = deduce->inst;
- if (!dinst) {
- if (!dtempl->templ_parent || !dtempl->inst_parent)
- return TYPE(templ);
-
- dtempl = dtempl->templ_parent;
- dinst = deduce->tmclass->inst_parent;
- }
-
- scantempl = dtempl;
- scaninst = dinst;
- while (1) {
- if (scantempl == templ)
- return TYPE(scaninst);
-
- if (!scantempl->templ_parent && scantempl->pspec_owner)
- scantempl = scantempl->pspec_owner;
-
- scantempl = scantempl->templ_parent;
- if (!scantempl)
- break;
-
- CError_ASSERT(1416, scaninst = scaninst->parent);
- }
-
- if (dtempl->flags & TEMPLCLASS_FLAGS_2) {
- scantempl = TEMPL_CLASS(dtempl->theclass.nspace->theclass);
- CError_ASSERT(1422, scantempl->theclass.flags & CLASS_IS_TEMPL);
- scaninst = dinst;
-
- while (1) {
- if (scantempl == templ)
- return TYPE(scaninst);
-
- scantempl = scantempl->templ_parent;
- if (!scantempl)
- break;
-
- CError_ASSERT(1430, scaninst = scaninst->parent);
- }
- }
-
- if (!templ->templ__params && (scaninst = CTemplTool_FindNestedClass(dtempl, dinst, templ)))
- return TYPE(scaninst);
-
- CError_FATAL(1477);
- return NULL;
-}
-
-static ENode *CTemplTool_DeduceExprCheck(ENode *expr) {
- if (expr->type != EINTCONST) {
- CError_Error(CErrorStr348);
- expr = nullnode();
- }
-
- return expr;
-}
-
-static ENodeList *CTemplTool_DeduceExprList(TypeDeduce *deduce, ENodeList *list) {
- ENodeList *resultList;
- ENodeList *last;
-
- resultList = NULL;
- while (list) {
- if (resultList) {
- last->next = lalloc(sizeof(ENodeList));
- last = last->next;
- } else {
- last = lalloc(sizeof(ENodeList));
- resultList = last;
- }
-
- *last = *list;
- last->node = CTemplTool_DeduceExpr(deduce, last->node);
-
- list = list->next;
- }
-
- return resultList;
-}
-
-ENode *CTemplTool_DeduceExpr(TypeDeduce *deduce, ENode *expr) {
- TemplArg *arg;
- TemplClassInst *inst;
- ENode *newExpr;
- NameSpaceObjectList *nsObjectList;
- TStreamElement *saved;
- NameResult pr;
- Type *type;
- UInt32 qual;
-
- if (!CTemplTool_IsTemplateArgumentDependentExpression(expr)) {
- newExpr = lalloc(sizeof(ENode));
- *newExpr = *expr;
- return newExpr;
- }
-
- switch (expr->type) {
- case ETEMPLDEP:
- switch (expr->data.templdep.subtype) {
- case TDE_PARAM:
- if (deduce->x15 && expr->data.templdep.u.pid.nindex == deduce->nindex) {
- newExpr = lalloc(sizeof(ENode));
- *newExpr = *expr;
- return newExpr;
- }
-
- for (arg = deduce->args; arg; arg = arg->next) {
- if (
- arg->pid.index == expr->data.templdep.u.pid.index &&
- arg->pid.nindex == expr->data.templdep.u.pid.nindex
- )
- {
- CError_ASSERT(1562, arg->pid.type == TPT_NONTYPE && arg->data.paramdecl.expr);
- newExpr = lalloc(sizeof(ENode));
- *newExpr = *arg->data.paramdecl.expr;
- return newExpr;
- }
- }
-
- for (inst = deduce->inst; inst; inst = inst->parent) {
- for (arg = inst->inst_args; arg; arg = arg->next) {
- if (
- arg->pid.index == expr->data.templdep.u.pid.index &&
- arg->pid.nindex == expr->data.templdep.u.pid.nindex
- )
- {
- CError_ASSERT(1575, arg->pid.type == TPT_NONTYPE && arg->data.paramdecl.expr);
- newExpr = lalloc(sizeof(ENode));
- *newExpr = *arg->data.paramdecl.expr;
- return newExpr;
- }
- }
- }
-
- CError_FATAL(1582);
-
- case TDE_SIZEOF:
- qual = 0;
- type = CTemplTool_DeduceTypeCopy(deduce, TYPE(expr->data.templdep.u.typeexpr.type), &qual);
- CDecl_CompleteType(type);
-
- if (CTemplTool_IsTemplateArgumentDependentType(type)) {
- newExpr = lalloc(sizeof(ENode));
- *newExpr = *expr;
- newExpr->data.templdep.u.typeexpr.type = type;
- return newExpr;
- }
-
- return intconstnode(CABI_GetSizeTType(), type->size);
-
- case TDE_ALIGNOF:
- qual = 0;
- type = CTemplTool_DeduceTypeCopy(deduce, TYPE(expr->data.templdep.u.typeexpr.type), &qual);
- CDecl_CompleteType(type);
-
- if (CTemplTool_IsTemplateArgumentDependentType(type)) {
- newExpr = lalloc(sizeof(ENode));
- *newExpr = *expr;
- newExpr->data.templdep.u.typeexpr.type = type;
- return newExpr;
- }
-
- return intconstnode(CABI_GetSizeTType(), CMach_GetTypeAlign(type));
-
- case TDE_CAST:
- qual = expr->data.templdep.u.cast.qual;
- type = CTemplTool_DeduceTypeCopy(deduce, expr->data.templdep.u.cast.type, &qual);
- return CExpr_DoExplicitConversion(type, qual, CTemplTool_DeduceExprList(deduce, expr->data.templdep.u.cast.args));
-
- case TDE_QUALNAME:
- qual = 0;
- type = CTemplTool_DeduceTypeCopy(deduce, TYPE(expr->data.templdep.u.qual.type), &qual);
-
- if (IS_TYPE_CLASS(type)) {
- CDecl_CompleteType(type);
- if (CScope_FindQualifiedClassMember(&pr, TYPE_CLASS(type), expr->data.templdep.u.qual.name))
- return pointer_generation(CExpr_MakeNameLookupResultExpr(&pr));
-
- CError_Error(CErrorStr150, expr->data.templdep.u.qual.name->name);
- } else if (IS_TYPE_TEMPLATE(type) && !deduce->inst) {
- newExpr = lalloc(sizeof(ENode));
- *newExpr = *expr;
- newExpr->data.templdep.u.qual.type = TYPE_TEMPLATE(type);
- return newExpr;
- } else {
- CError_Error(CErrorStr340, expr->data.templdep.u.qual.name->name);
- }
-
- return nullnode();
-
- case TDE_OBJ:
- type = CTemplTool_FindTemplateInstance(deduce, TEMPL_CLASS(expr->data.templdep.u.obj->nspace->theclass));
- CError_ASSERT(1651, type && IS_TYPE_CLASS(type));
-
- nsObjectList = CScope_GetLocalObject(TYPE_CLASS(type)->nspace, expr->data.templdep.u.obj->name);
- CError_ASSERT(1654, nsObjectList);
-
- memclrw(&pr, sizeof(pr));
- pr.obj_10 = nsObjectList->object;
- return pointer_generation(CExpr_MakeNameLookupResultExpr(&pr));
-
- case TDE_SOURCEREF:
- CError_LockErrorPos(expr->data.templdep.u.sourceref.token, &saved);
- newExpr = CTemplTool_DeduceExpr(deduce, expr->data.templdep.u.sourceref.expr);
- CError_UnlockErrorPos(&saved);
- return newExpr;
-
- case TDE_ADDRESS_OF:
- return getnodeaddress(CTemplTool_DeduceExpr(deduce, expr->data.templdep.u.monadic), 1);
-
- default:
- CError_FATAL(1671);
- }
- case EFUNCCALL:
- newExpr = CExpr_PointerGeneration(CTemplTool_DeduceExpr(deduce, expr->data.funccall.funcref));
- return CExpr_MakeFunctionCall(newExpr, CTemplTool_DeduceExprList(deduce, expr->data.funccall.args));
- case ELOGNOT:
- return CExpr_New_ELOGNOT_Node(CTemplTool_DeduceExpr(deduce, expr->data.monadic));
- case EMONMIN:
- return CExpr_New_EMONMIN_Node(CTemplTool_DeduceExpr(deduce, expr->data.monadic));
- case EBINNOT:
- return CExpr_New_EBINNOT_Node(CTemplTool_DeduceExpr(deduce, expr->data.monadic));
- case EMUL:
- case EDIV:
- case EMODULO:
- case EADD:
- case ESUB:
- case ESHL:
- case ESHR:
- case ELESS:
- case EGREATER:
- case ELESSEQU:
- case EGREATEREQU:
- case EEQU:
- case ENOTEQU:
- case EAND:
- case EXOR:
- case EOR:
- case ELAND:
- case ELOR:
- case EROTL:
- case EROTR:
- return CExpr_NewDyadicNode(
- CTemplTool_DeduceExpr(deduce, expr->data.diadic.left),
- expr->type,
- CTemplTool_DeduceExpr(deduce, expr->data.diadic.right));
- case ECOND:
- return CExpr_New_ECOND_Node(
- CTemplTool_DeduceExpr(deduce, expr->data.cond.cond),
- CTemplTool_DeduceExpr(deduce, expr->data.cond.expr1),
- CTemplTool_DeduceExpr(deduce, expr->data.cond.expr2));
- default:
- CError_FATAL(1727);
- case EINTCONST:
- newExpr = lalloc(sizeof(ENode));
- *newExpr = *expr;
- return newExpr;
- }
-}
-
-ENode *CTemplTool_DeduceDefaultArg(Object *func, ENode *expr) {
- TypeDeduce deduce;
-
- memclrw(&deduce, sizeof(deduce));
- CError_ASSERT(1747, IS_TYPE_FUNC(func->type));
-
- if (func->u.func.inst)
- deduce.args = func->u.func.inst->args;
-
- if ((TYPE_FUNC(func->type)->flags & FUNC_METHOD) && (TYPE_METHOD(func->type)->theclass->flags & CLASS_IS_TEMPL_INST)) {
- deduce.inst = TEMPL_CLASS_INST(TYPE_METHOD(func->type)->theclass);
- deduce.tmclass = TEMPL_CLASS_INST(TYPE_METHOD(func->type)->theclass)->templ;
- }
-
- return CTemplTool_DeduceExpr(&deduce, expr);
-}
-
-static TemplClass *CTemplTool_FindNestedTemplateInstance(TypeDeduce *deduce, TemplClass *templ) {
- TemplClass *dtempl;
- TemplClassInst *dinst;
- Type *type;
-
- if (templ->inst_parent)
- return templ;
-
- CError_ASSERT(1776, (dtempl = deduce->tmclass) && (dinst = deduce->inst));
-
- while (1) {
- if (
- templ->templ_parent == dtempl &&
- (type = CScope_GetLocalTagType(dinst->theclass.nspace, templ->theclass.classname)) &&
- IS_TEMPL_CLASS(type) &&
- TEMPL_CLASS(type)->templ_parent == templ->templ_parent
- )
- return TEMPL_CLASS(type);
-
- dtempl = dtempl->templ_parent;
- if (!dtempl)
- break;
-
- dinst = dinst->parent;
- CError_ASSERT(1790, dinst);
- }
-
- return templ;
-}
-
-static Type *CTemplTool_DeduceClassInstanceCopy(TypeDeduce *deduce, TemplClass *templ, TemplArg *args) {
- TemplArg *arg;
- TemplArg *deducedArgs;
- TemplArg *last;
- TemplParam *param;
- UInt32 qual;
- Type *type;
-
- if (templ->templ_parent)
- templ = CTemplTool_FindNestedTemplateInstance(deduce, templ);
-
- arg = args;
- deducedArgs = NULL;
- param = templ->templ__params;
-
- while (arg) {
- if (deducedArgs) {
- last->next = galloc(sizeof(TemplArg));
- last = last->next;
- } else {
- last = galloc(sizeof(TemplArg));
- deducedArgs = last;
- }
-
- *last = *arg;
-
- if (!param || param->pid.type != last->pid.type) {
- CError_Error(CErrorStr374);
- return &stvoid;
- }
-
- last->pid = param->pid;
- param = param->next;
-
- switch (last->pid.type) {
- case TPT_TYPE:
- last->data.typeparam.type = CTemplTool_DeduceTypeCopy(deduce, last->data.typeparam.type, &last->data.typeparam.qual);
- break;
-
- case TPT_NONTYPE:
- if (!last->data.paramdecl.expr) {
- CError_FATAL(1873);
- } else if (CTemplTool_IsTemplateArgumentDependentExpression(last->data.paramdecl.expr)) {
- last->data.paramdecl.expr = pointer_generation(CTemplTool_DeduceExpr(deduce, last->data.paramdecl.expr));
- last->data.paramdecl.expr = CInline_CopyExpression(last->data.paramdecl.expr, CopyMode1);
- }
- break;
-
- case TPT_TEMPLATE:
- qual = 0;
- last->data.ttargtype = CTemplTool_DeduceTypeCopy(deduce, last->data.ttargtype, &qual);
- break;
-
- default:
- CError_FATAL(1891);
- }
-
- arg = arg->next;
- }
-
- for (arg = deducedArgs; arg; arg = arg->next) {
- switch (arg->pid.type) {
- case TPT_TYPE:
- if (CTemplTool_IsTemplateArgumentDependentType(arg->data.typeparam.type))
- break;
- continue;
-
- case TPT_NONTYPE:
- if (CTemplTool_IsTemplateArgumentDependentExpression(arg->data.paramdecl.expr))
- break;
-
- switch (arg->data.paramdecl.expr->type) {
- case EINTCONST:
- case EOBJLIST:
- case EMEMBER:
- break;
- case EOBJREF:
- if (CParser_HasInternalLinkage2(arg->data.paramdecl.expr->data.objref))
- CError_Error(CErrorStr357);
- break;
- default:
- CError_Error(CErrorStr371);
- arg->data.paramdecl.expr = nullnode();
- break;
- }
- continue;
-
- case TPT_TEMPLATE:
- if (!IS_TYPE_CLASS(arg->data.ttargtype) && CTemplTool_IsTemplateArgumentDependentType(arg->data.ttargtype))
- break;
- continue;
-
- default:
- CError_FATAL(1937);
- }
-
- break;
- }
-
- if (arg) {
- type = CDecl_NewTemplDepType(TEMPLDEP_TEMPLATE);
- TYPE_TEMPLATE(type)->u.templ.templ = templ;
- TYPE_TEMPLATE(type)->u.templ.args = deducedArgs;
- return type;
- }
-
- if ((type = CTemplTool_IsDependentTemplate(templ, deducedArgs)))
- return type;
-
- return TYPE(CTemplClass_GetInstance(templ, deducedArgs, NULL));
-}
-
-static TemplArg *CTemplTool_FindTemplArg(TemplArg *args, TemplParamID pid) {
- while (args) {
- if (args->pid.index == pid.index && args->pid.nindex == pid.nindex) {
- CError_ASSERT(1984, pid.type == args->pid.type);
- return args;
- }
- args = args->next;
- }
-
- return NULL;
-}
-
-static TemplArg *CTemplTool_DeduceTemplArg(TypeDeduce *deduce, TemplParamID pid) {
- TemplClass *tmclass;
- TemplClassInst *inst;
- TemplArg *arg;
-
- if ((arg = CTemplTool_FindTemplArg(deduce->args, pid)))
- return arg;
-
- tmclass = deduce->tmclass;
- CError_ASSERT(2008, tmclass);
-
- inst = deduce->inst;
- if (!inst) {
- CError_ASSERT(2011, tmclass->templ_parent && tmclass->inst_parent);
- inst = deduce->tmclass->inst_parent;
- }
-
- while (1) {
- if ((arg = CTemplTool_FindTemplArg(inst->inst_args, pid)))
- return arg;
-
- inst = inst->parent;
- CError_ASSERT(2022, inst);
- }
-}
-
-static Type *CTemplTool_DeduceArrayCopy(TypeDeduce *deduce, Type *type, ENode *index, UInt32 *resultQual) {
- if (CTemplTool_IsTemplateArgumentDependentType(type))
- type = CTemplTool_DeduceTypeCopy(deduce, type, resultQual);
-
- index = CTemplTool_DeduceExpr(deduce, index);
-
- if (ENODE_IS(index, EINTCONST)) {
- if (CInt64_IsNegative(&index->data.intval)) {
- CError_Error(CErrorStr124);
- index->data.intval = cint64_one;
- }
-
- if (!CDecl_CheckArrayIntegr(type))
- type = TYPE(&stsignedchar);
-
- type = CDecl_NewArrayType(type, type->size * CInt64_GetULong(&index->data.intval));
- } else {
- if (!deduce->x16)
- CError_Error(CErrorStr124);
- }
-
- return type;
-}
-
-static Type *CTemplTool_DeduceBitfieldCopy(TypeDeduce *deduce, Type *type, ENode *size, UInt32 *resultQual) {
- TypeBitfield *tbitfield;
- short sizeval;
- short maxsize;
-
- if (CTemplTool_IsTemplateArgumentDependentType(type)) {
- UInt32 qual = 0;
- type = CTemplTool_DeduceTypeCopy(deduce, type, &qual);
- }
-
- if (!IS_TYPE_INT_OR_ENUM(type)) {
- CError_Error(CErrorStr138);
- type = TYPE(&stunsignedint);
- }
-
- switch (type->size) {
- case 1:
- maxsize = 8;
- break;
- case 2:
- maxsize = 16;
- break;
- case 4:
- maxsize = 32;
- break;
- default:
- CError_Error(CErrorStr138);
- return type;
- }
-
- if (!ENODE_IS(size, EINTCONST)) {
- size = CTemplTool_DeduceExpr(deduce, size);
- if (!ENODE_IS(size, EINTCONST)) {
- CError_Error(CErrorStr124);
- return type;
- }
- }
-
- sizeval = CInt64_GetULong(&size->data.intval);
- if (sizeval > maxsize || CInt64_IsNegative(&size->data.intval)) {
- CError_Error(CErrorStr138);
- sizeval = 1;
- }
-
- tbitfield = galloc(sizeof(TypeBitfield));
- memclrw(tbitfield, sizeof(TypeBitfield));
-
- tbitfield->type = TYPEBITFIELD;
- tbitfield->size = type->size;
- tbitfield->bitfieldtype = type;
- tbitfield->bitlength = sizeval;
-
- return TYPE(tbitfield);
-}
-
-static Type *CTemplTool_DeduceTemplDepType(TypeDeduce *deduce, TypeTemplDep *tdt, UInt32 *resultQual) {
- Type *type;
- UInt32 qual;
- TemplArg *arg;
-
- qual = 0;
-
- if (deduce->x14) {
- type = CTemplTool_GetSelfRefTemplate(TYPE(tdt));
- if (type && type == TYPE(deduce->tmclass))
- return type;
-
- switch (tdt->dtype) {
- case TEMPLDEP_ARGUMENT:
- return TYPE(tdt);
-
- case TEMPLDEP_QUALNAME:
- type = CTemplTool_DeduceTypeCopy(deduce, TYPE(tdt->u.qual.type), &qual);
- if (type == TYPE(tdt->u.qual.type))
- return TYPE(tdt);
-
- if (!IS_TYPE_CLASS(type)) {
- TypeTemplDep *tdtCopy;
- CError_ASSERT(2157, IS_TYPE_TEMPLATE(type));
- tdtCopy = galloc(sizeof(TypeTemplDep));
- *tdtCopy = *tdt;
- tdtCopy->u.qual.type = TYPE_TEMPLATE(type);
- return TYPE(tdtCopy);
- } else if ((type = CScope_GetType(TYPE_CLASS(type)->nspace, tdt->u.qual.name, resultQual))) {
- return type;
- } else {
- CError_Error(CErrorStr150, tdt->u.qual.name->name);
- return TYPE(tdt);
- }
-
- case TEMPLDEP_TEMPLATE:
- for (arg = tdt->u.templ.args; arg; arg = arg->next) {
- if (arg->pid.type == TPT_TYPE)
- arg->data.typeparam.type = CTemplTool_DeduceTypeCopy(deduce, arg->data.typeparam.type, &arg->data.typeparam.qual);
- }
- return TYPE(tdt);
-
- case TEMPLDEP_ARRAY:
- tdt->u.array.type = CTemplTool_DeduceTypeCopy(deduce, tdt->u.array.type, &qual);
- return TYPE(tdt);
-
- case TEMPLDEP_QUALTEMPL:
- tdt->u.qualtempl.type = TYPE_TEMPLATE(CTemplTool_DeduceTemplDepType(deduce, tdt->u.qualtempl.type, &qual));
- for (arg = tdt->u.qualtempl.args; arg; arg = arg->next) {
- if (arg->pid.type == TPT_TYPE)
- arg->data.typeparam.type = CTemplTool_DeduceTypeCopy(deduce, arg->data.typeparam.type, &arg->data.typeparam.qual);
- }
- return TYPE(tdt);
-
- case TEMPLDEP_BITFIELD:
- tdt->u.bitfield.type = CTemplTool_DeduceTypeCopy(deduce, tdt->u.bitfield.type, &qual);
- return TYPE(tdt);
- }
- } else {
- switch (tdt->dtype) {
- case TEMPLDEP_ARGUMENT:
- if (deduce->x15 && tdt->u.pid.nindex == deduce->nindex)
- return TYPE(tdt);
-
- arg = CTemplTool_DeduceTemplArg(deduce, tdt->u.pid);
- if (arg->pid.type == TPT_TEMPLATE) {
- CError_ASSERT(2222, IS_TEMPL_CLASS(arg->data.typeparam.type));
- *resultQual = arg->data.typeparam.qual;
- return arg->data.typeparam.type;
- }
-
- CError_ASSERT(2226, arg->pid.type == TPT_TYPE);
- *resultQual = arg->data.typeparam.qual;
- return arg->data.typeparam.type;
-
- case TEMPLDEP_QUALNAME:
- type = CTemplTool_DeduceTypeCopy(deduce, TYPE(tdt->u.qual.type), &qual);
- if (IS_TYPE_CLASS(type)) {
- CDecl_CompleteType(type);
- if ((type = CScope_GetType(TYPE_CLASS(type)->nspace, tdt->u.qual.name, resultQual))) {
- return type;
- } else {
- CError_Error(CErrorStr150, tdt->u.qual.name->name);
- }
- } else {
- if ((deduce->x15 || !deduce->inst) && IS_TYPE_TEMPLATE(type)) {
- TypeTemplDep *tdtCopy = galloc(sizeof(TypeTemplDep));
- *tdtCopy = *tdt;
- tdtCopy->u.qual.type = TYPE_TEMPLATE(type);
- return TYPE(tdtCopy);
- } else {
- CError_Error(CErrorStr340, tdt->u.qual.name->name);
- }
- }
- return TYPE(&stsignedint);
-
- case TEMPLDEP_TEMPLATE:
- return CTemplTool_DeduceClassInstanceCopy(deduce, tdt->u.templ.templ, tdt->u.templ.args);
-
- case TEMPLDEP_ARRAY:
- return CTemplTool_DeduceArrayCopy(deduce, tdt->u.array.type, tdt->u.array.index, resultQual);
-
- case TEMPLDEP_QUALTEMPL:
- type = CTemplTool_DeduceTypeCopy(deduce, TYPE(tdt->u.qualtempl.type), &qual);
- if (!IS_TEMPL_CLASS(type)) {
- CError_Error(CErrorStr121);
- return TYPE(&stsignedint);
- }
- return CTemplTool_DeduceClassInstanceCopy(deduce, TEMPL_CLASS(type), tdt->u.qualtempl.args);
-
- case TEMPLDEP_BITFIELD:
- return CTemplTool_DeduceBitfieldCopy(deduce, tdt->u.bitfield.type, tdt->u.bitfield.size, resultQual);
- }
- }
-
- CError_FATAL(2275);
- return NULL;
-}
-
-static Type *CTemplTool_DeduceTypeQualCopy(TypeDeduce *deduce, Type *type, UInt32 *resultQual) {
- Type *innerType;
- UInt32 qual;
- UInt32 innerQual;
- TypePointer *newPtr;
-
- qual = *resultQual;
-
- if (IS_TYPE_POINTER_ONLY(type) && IS_TYPE_TEMPLATE(TPTR_TARGET(type))) {
- innerQual = 0;
- innerType = CTemplTool_DeduceTemplDepType(deduce, TYPE_TEMPLATE(TPTR_TARGET(type)), &innerQual);
-
- newPtr = galloc(sizeof(TypePointer));
- *newPtr = *TYPE_POINTER(type);
-
- if (IS_TYPE_POINTER_ONLY(innerType)) {
- newPtr->target = galloc(sizeof(TypePointer));
- *TYPE_POINTER(newPtr->target) = *TYPE_POINTER(innerType);
- *resultQual = innerQual & (Q_CONST | Q_VOLATILE);
- TPTR_QUAL(newPtr->target) |= qual & (Q_CONST | Q_VOLATILE);
- } else if (IS_TYPE_MEMBERPOINTER(innerType)) {
- newPtr->target = galloc(sizeof(TypeMemberPointer));
- *TYPE_MEMBER_POINTER(newPtr->target) = *TYPE_MEMBER_POINTER(innerType);
- *resultQual = innerQual & (Q_CONST | Q_VOLATILE);
- TYPE_MEMBER_POINTER(newPtr->target)->qual |= qual & (Q_CONST | Q_VOLATILE);
- } else {
- newPtr->target = innerType;
- *resultQual = (qual | innerQual) & (Q_CONST | Q_VOLATILE);
- }
-
- return TYPE(newPtr);
- }
-
- return CTemplTool_DeduceTypeCopy(deduce, type, resultQual);
-}
-
-FuncArg *CTemplTool_DeduceArgCopy(TypeDeduce *deduce, FuncArg *args) {
- FuncArg *resultArgs;
- FuncArg *last;
-
- if (args == &oldstyle || args == &elipsis)
- return args;
-
- resultArgs = NULL;
-
- while (args) {
- if (args == &elipsis) {
- last->next = args;
- break;
- }
-
- if (resultArgs) {
- last->next = galloc(sizeof(FuncArg));
- last = last->next;
- } else {
- last = galloc(sizeof(FuncArg));
- resultArgs = last;
- }
-
- *last = *args;
- last->type = CTemplTool_DeduceTypeQualCopy(deduce, last->type, &last->qual);
- CanCreateObject(last->type);
-
- args = args->next;
- }
-
- return resultArgs;
-}
-
-static ExceptSpecList *CTemplTool_DeduceExSpecCopy(TypeDeduce *deduce, ExceptSpecList *exspec) {
- ExceptSpecList *copy;
-
- copy = galloc(sizeof(ExceptSpecList));
- *copy = *exspec;
-
- if (copy->type && CTemplTool_IsTemplateArgumentDependentType(copy->type))
- copy->type = CTemplTool_DeduceTypeCopy(deduce, copy->type, &copy->qual);
-
- if (copy->next)
- copy->next = CTemplTool_DeduceExSpecCopy(deduce, copy->next);
-
- return copy;
-}
-
-Type *CTemplTool_DeduceTypeCopy(TypeDeduce *deduce, Type *type, UInt32 *resultQual) {
- TemplClassInst *inst;
- Type *deduced;
- UInt32 qual2;
- UInt32 qual;
-
- switch (type->type) {
- case TYPETEMPLATE:
- qual = 0;
- deduced = CTemplTool_DeduceTemplDepType(deduce, TYPE_TEMPLATE(type), &qual);
- if (*resultQual & (Q_CONST | Q_VOLATILE)) {
- if (IS_TYPE_POINTER_ONLY(deduced)) {
- TypePointer *newPtr = galloc(sizeof(TypePointer));
- *newPtr = *TYPE_POINTER(deduced);
- newPtr->qual |= *resultQual & (Q_CONST | Q_VOLATILE);
- *resultQual &= ~(Q_CONST | Q_VOLATILE);
- deduced = TYPE(newPtr);
- } else if (IS_TYPE_MEMBERPOINTER(deduced)) {
- TypeMemberPointer *newPtr = galloc(sizeof(TypeMemberPointer));
- *newPtr = *TYPE_MEMBER_POINTER(deduced);
- newPtr->qual |= *resultQual & (Q_CONST | Q_VOLATILE);
- *resultQual &= ~(Q_CONST | Q_VOLATILE);
- deduced = TYPE(newPtr);
- }
- }
- *resultQual |= qual;
- return deduced;
-
- case TYPEVOID:
- case TYPEINT:
- case TYPEFLOAT:
- case TYPESTRUCT:
- return type;
-
- case TYPEENUM:
- if (
- TYPE_ENUM(type)->nspace->theclass &&
- (TYPE_ENUM(type)->nspace->theclass->flags & CLASS_IS_TEMPL) &&
- !deduce->x14
- )
- {
- CError_ASSERT(2471, TYPE_ENUM(type)->enumname);
- inst = TEMPL_CLASS_INST(CTemplTool_FindTemplateInstance(deduce, TEMPL_CLASS(TYPE_ENUM(type)->nspace->theclass)));
- CError_ASSERT(2473, inst && inst->theclass.type == TYPECLASS);
-
- CDecl_CompleteType(TYPE(inst));
- type = CScope_GetLocalTagType(inst->theclass.nspace, TYPE_ENUM(type)->enumname);
- CError_ASSERT(2477, type);
- return type;
- }
- return type;
-
- case TYPECLASS:
- if (!deduce->x14) {
- if (TYPE_CLASS(type)->flags & CLASS_IS_TEMPL)
- return CTemplTool_FindTemplateInstance(deduce, TEMPL_CLASS(type));
-
- if (TYPE_CLASS(type)->nspace->theclass && (TYPE_CLASS(type)->nspace->theclass->flags & CLASS_IS_TEMPL)) {
- CError_ASSERT(2492, deduce->inst);
- CError_ASSERT(2493, TYPE_CLASS(type)->classname);
-
- type = CScope_GetLocalTagType(deduce->inst->theclass.nspace, TYPE_CLASS(type)->classname);
- CError_ASSERT(2496, type);
- return type;
- }
- }
-
- return type;
-
- case TYPEARRAY: {
- SInt32 elements;
-
- elements = TPTR_TARGET(type)->size;
- if (elements > 0)
- elements = type->size / elements;
-
- deduced = galloc(sizeof(TypePointer));
- *TYPE_POINTER(deduced) = *TYPE_POINTER(type);
- TPTR_TARGET(deduced) = CTemplTool_DeduceTypeCopy(deduce, TPTR_TARGET(type), resultQual);
-
- do {
- type = TPTR_TARGET(type);
- } while (IS_TYPE_ARRAY(type));
-
- if (IS_TYPE_TEMPLATE(type)) {
- CDecl_CompleteType(TPTR_TARGET(deduced));
- deduced->size = TPTR_TARGET(deduced)->size * elements;
- }
-
- return deduced;
- }
-
- case TYPEPOINTER:
- deduced = galloc(sizeof(TypePointer));
- *TYPE_POINTER(deduced) = *TYPE_POINTER(type);
- TPTR_TARGET(deduced) = CTemplTool_DeduceTypeCopy(deduce, TPTR_TARGET(type), resultQual);
- return deduced;
-
- case TYPEBITFIELD:
- deduced = galloc(sizeof(TypeBitfield));
- *TYPE_BITFIELD(deduced) = *TYPE_BITFIELD(type);
- TYPE_BITFIELD(deduced)->bitfieldtype = CTemplTool_DeduceTypeCopy(deduce, TYPE_BITFIELD(type)->bitfieldtype, resultQual);
- return deduced;
-
- case TYPEMEMBERPOINTER:
- deduced = galloc(sizeof(TypeMemberPointer));
- *TYPE_MEMBER_POINTER(deduced) = *TYPE_MEMBER_POINTER(type);
- TYPE_MEMBER_POINTER(deduced)->ty1 = CTemplTool_DeduceTypeCopy(deduce, TYPE_MEMBER_POINTER(type)->ty1, resultQual);
- qual2 = 0;
- TYPE_MEMBER_POINTER(deduced)->ty2 = CTemplTool_DeduceTypeCopy(deduce, TYPE_MEMBER_POINTER(type)->ty2, &qual2);
-
- if (
- !IS_TYPE_CLASS(TYPE_MEMBER_POINTER(deduced)->ty2) &&
- !deduce->x14 &&
- !deduce->x15 &&
- !deduce->x16
- )
- {
- CError_Error(CErrorStr232);
- return TYPE_MEMBER_POINTER(deduced)->ty1;
- }
- return deduced;
-
- case TYPEFUNC:
- if (TYPE_FUNC(type)->flags & FUNC_METHOD) {
- qual2 = 0;
- deduced = galloc(sizeof(TypeMemberFunc));
- *TYPE_METHOD(deduced) = *TYPE_METHOD(type);
- TYPE_METHOD(deduced)->funcid = 0;
- TYPE_METHOD(deduced)->theclass = TYPE_CLASS(CTemplTool_DeduceTypeQualCopy(deduce, TYPE(TYPE_METHOD(type)->theclass), &qual2));
- CError_ASSERT(2556, IS_TYPE_CLASS(TYPE_METHOD(deduced)->theclass));
- } else {
- deduced = galloc(sizeof(TypeFunc));
- *TYPE_FUNC(deduced) = *TYPE_FUNC(type);
- }
-
- TYPE_FUNC(deduced)->flags &= ~FUNC_IS_TEMPL;
-
- qual2 = TYPE_FUNC(type)->qual;
- TYPE_FUNC(deduced)->functype = CTemplTool_DeduceTypeQualCopy(deduce, TYPE_FUNC(type)->functype, &qual2);
- TYPE_FUNC(deduced)->qual = qual2;
-
- TYPE_FUNC(deduced)->args = CTemplTool_DeduceArgCopy(deduce, TYPE_FUNC(type)->args);
- if (TYPE_FUNC(type)->exspecs)
- TYPE_FUNC(deduced)->exspecs = CTemplTool_DeduceExSpecCopy(deduce, TYPE_FUNC(type)->exspecs);
-
- CDecl_SetResultReg(TYPE_FUNC(deduced));
- return deduced;
-
- case TYPETEMPLDEPEXPR:
- CError_Error(CErrorStr190);
- return &stvoid;
-
- default:
- CError_FATAL(2580);
- return NULL;
- }
-}
-
-Type *CTemplTool_ResolveMemberSelfRefs(TemplClass *templ, Type *type, UInt32 *resultQual) {
- TypeDeduce deduce;
-
- memclrw(&deduce, sizeof(deduce));
- deduce.tmclass = templ;
- deduce.x14 = 1;
-
- if (IS_TYPE_FUNC(type)) {
- TYPE_FUNC(type)->functype = CTemplTool_DeduceTypeCopy(&deduce, TYPE_FUNC(type)->functype, &TYPE_FUNC(type)->qual);
- TYPE_FUNC(type)->args = CTemplTool_DeduceArgCopy(&deduce, TYPE_FUNC(type)->args);
- CDecl_SetResultReg(TYPE_FUNC(type));
- } else {
- type = CTemplTool_DeduceTypeCopy(&deduce, type, resultQual);
- }
-
- return type;
-}
-
-Boolean CTemplTool_IsSameTemplateType(Type *a, Type *b) {
- return CTemplTool_GetSelfRefTemplate(b) == a;
-}