diff options
Diffstat (limited to 'compiler_and_linker/unsorted/CTemplateTools.c')
-rw-r--r-- | compiler_and_linker/unsorted/CTemplateTools.c | 1962 |
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, ©->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; -} |