diff options
author | Ash Wolf <ninji@wuffs.org> | 2023-01-26 11:30:47 +0000 |
---|---|---|
committer | Ash Wolf <ninji@wuffs.org> | 2023-01-26 11:30:47 +0000 |
commit | 094b96ca1df4a035b5f93c351f773306c0241f3f (patch) | |
tree | 95ce05e3ebe816c7ee7996206bb37ea17d8ca33c /compiler_and_linker/unsorted/CTemplateFunc.c | |
parent | fc0c4c0df7b583b55a08317cf1ef6a71d27c0440 (diff) | |
download | MWCC-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/CTemplateFunc.c')
-rw-r--r-- | compiler_and_linker/unsorted/CTemplateFunc.c | 1383 |
1 files changed, 0 insertions, 1383 deletions
diff --git a/compiler_and_linker/unsorted/CTemplateFunc.c b/compiler_and_linker/unsorted/CTemplateFunc.c deleted file mode 100644 index 3c5de98..0000000 --- a/compiler_and_linker/unsorted/CTemplateFunc.c +++ /dev/null @@ -1,1383 +0,0 @@ -#include "compiler/CTemplateFunc.h" -#include "compiler/CABI.h" -#include "compiler/CDecl.h" -#include "compiler/CError.h" -#include "compiler/CExpr.h" -#include "compiler/CInline.h" -#include "compiler/CInt64.h" -#include "compiler/CParser.h" -#include "compiler/CTemplateTools.h" -#include "compiler/CompilerTools.h" -#include "compiler/objects.h" -#include "compiler/scopes.h" -#include "compiler/templates.h" -#include "compiler/types.h" - -static Boolean ctempl_conversion_deduction; -static UInt8 ctempl_explicitargs_nindex; -static int ctempl_explicitargs_num; -static Boolean ctempl_explicitargs_all; - -// forward decls -static Boolean CTempl_DeduceTypeTemplDep(TypeTemplDep *type1, UInt32 qual1, Type *type2, UInt32 qual2, TemplArg *argArray, Boolean flag); -static Boolean CTempl_DeduceType1(Type *type1, UInt32 qual1, Type *type2, UInt32 qual2, TemplArg *argArray, Boolean flag); - -static void CTemplFunc_SetupTypeDeduce(TypeDeduce *deduce, TemplateFunction *templ, TemplArg *args) { - memclrw(deduce, sizeof(TypeDeduce)); - if (templ->tfunc->nspace->theclass && (templ->tfunc->nspace->theclass->flags & CLASS_IS_TEMPL)) - deduce->tmclass = TEMPL_CLASS(templ->tfunc->nspace->theclass); - deduce->params = templ->params; - deduce->args = args; -} - -Boolean CTempl_CanDeduceFunc(Object *object, TypeFunc *tfunc, TemplArg *args) { - DeduceInfo info; - int i; - - if (CTemplTool_InitDeduceInfo(&info, CTemplTool_GetFuncTempl(object)->params, args, 0)) { - if (CTempl_DeduceType(object->type, 0, TYPE(tfunc), 0, info.args, 0, 0)) { - for (i = 0; i < info.maxCount; i++) { - if (!info.args[i].is_deduced) - return 0; - } - return 1; - } - } - - return 0; -} - -static TemplFuncInstance *CTempl_GetCreateFuncInstance(Object *funcobj, TemplArg *args, Object *object2) { - TemplFuncInstance *inst; - TemplateFunction *templ; - Object *instobj; - TemplParam *param; - TemplArg *arg; - TemplArg *last; - short paramCount; - short i; - TypeDeduce deduce; - - templ = CTemplTool_GetFuncTempl(funcobj); - - paramCount = 0; - param = templ->params; - while (param) { - param = param->next; - paramCount++; - } - - for (i = 1, arg = args; i < paramCount; i++, arg++) - arg->next = arg + 1; - arg->next = NULL; - - for (inst = templ->instances; inst; inst = inst->next) { - if (CTemplTool_EqualArgs(inst->args, args)) { - if (object2) - inst->object = object2; - return inst; - } - } - - inst = galloc(sizeof(TemplFuncInstance)); - memclrw(inst, sizeof(TemplFuncInstance)); - - for (i = 0, arg = NULL; i < paramCount; i++) { - if (arg) { - last->next = galloc(sizeof(TemplArg)); - last = last->next; - } else { - last = galloc(sizeof(TemplArg)); - arg = last; - } - - *last = *args; - last->next = NULL; - args++; - - if (last->pid.type == TPT_NONTYPE) { - CError_ASSERT(114, last->data.paramdecl.expr); - last->data.paramdecl.expr = CInline_CopyExpression(last->data.paramdecl.expr, CopyMode1); - } - } - - inst->args = arg; - inst->next = templ->instances; - templ->instances = inst; - - if (!object2) { - instobj = CParser_NewFunctionObject(NULL); - instobj->access = funcobj->access; - instobj->nspace = funcobj->nspace; - instobj->sclass = funcobj->sclass; - instobj->qual = funcobj->qual | Q_MANGLE_NAME; - instobj->name = templ->name; - instobj->u.func.inst = inst; - - CTemplFunc_SetupTypeDeduce(&deduce, templ, inst->args); - if (funcobj->nspace->theclass && (funcobj->nspace->theclass->flags & CLASS_IS_TEMPL_INST)) { - deduce.tmclass = TEMPL_CLASS_INST(funcobj->nspace->theclass)->templ; - deduce.inst = TEMPL_CLASS_INST(funcobj->nspace->theclass); - } - - instobj->type = CTemplTool_DeduceTypeCopy(&deduce, funcobj->type, &instobj->qual); - inst->object = instobj; - - if (IS_TYPE_FUNC(instobj->type)) { - TYPE_FUNC(instobj->type)->flags &= ~FUNC_DEFINED; - if (TYPE_FUNC(instobj->type)->flags & FUNC_IS_CTOR) { - FuncArg *funcarg; - CError_ASSERT(152, TYPE_FUNC(instobj->type)->flags & FUNC_METHOD); - CError_ASSERT(153, funcarg = TYPE_FUNC(instobj->type)->args); - - if (TYPE_METHOD(instobj->type)->theclass->flags & CLASS_HAS_VBASES) - CError_ASSERT(156, funcarg = funcarg->next); - - if (funcarg->next) - CDecl_CheckCtorIntegrity(funcarg->next, TYPE_METHOD(instobj->type)->theclass); - } - } - - if ((instobj->qual & Q_INLINE) && templ->stream.tokens) - CInline_AddTemplateFunctionAction(instobj, templ, inst); - - } else { - inst->object = object2; - } - - return inst; -} - -TemplFuncInstance *CTempl_CheckFuncInstance(Object *object1, TypeFunc *tfunc, TemplArg *args, Object *object2) { - DeduceInfo info; - int i; - - if (!CTemplTool_InitDeduceInfo(&info, CTemplTool_GetFuncTempl(object1)->params, args, 1)) - return NULL; - - if (!CTempl_DeduceType(object1->type, 0, TYPE(tfunc), 0, info.args, 0, 0)) - return NULL; - - i = 0; - while (i < info.maxCount) { - if (!info.args[i++].is_deduced) - return NULL; - } - - return CTempl_GetCreateFuncInstance(object1, info.args, object2); -} - -TemplFuncInstance *CTempl_DeduceFunc(Object *object1, TypeFunc *tfunc, TemplArg *args, Object *object2, Boolean flag) { - return CTempl_CheckFuncInstance(object1, tfunc, args, object2); -} - -static Boolean CTempl_FuncIsAtLeastAsSpecialized(Object *func1, Object *func2) { - int i; - FuncArg *arg1; - FuncArg *arg2; - Type *type1; - Type *type2; - UInt32 qual1; - UInt32 qual2; - DeduceInfo info; - - arg1 = TYPE_FUNC(func2->type)->args; - if (IS_TYPEFUNC_NONSTATIC_METHOD(TYPE_FUNC(func2->type))) - arg1 = arg1->next; - - i = 0; - while (1) { - if (!arg1) - break; - CError_ASSERT(231, arg1->type != &stvoid); - if (arg1 == &elipsis) - break; - if (arg1 == &oldstyle) - break; - arg1 = arg1->next; - i++; - } - - if (!CTemplTool_InitDeduceInfo(&info, CTemplTool_GetFuncTempl(func2)->params, NULL, 0)) - return 0; - - arg1 = TYPE_FUNC(func1->type)->args; - if (IS_TYPEFUNC_NONSTATIC_METHOD(TYPE_FUNC(func1->type))) - arg1 = arg1->next; - - arg2 = TYPE_FUNC(func2->type)->args; - if (IS_TYPEFUNC_NONSTATIC_METHOD(TYPE_FUNC(func2->type))) - arg2 = arg2->next; - - while (i > 0) { - if (!arg1) - break; - if (arg1 == &elipsis) - break; - if (arg1 == &oldstyle) - break; - - CError_ASSERT(255, arg2); - - type1 = arg1->type; - qual1 = arg1->qual & (Q_CONST | Q_VOLATILE); - qual2 = arg2->qual & (Q_CONST | Q_VOLATILE); - type2 = arg2->type; - - if (!CTemplTool_IsTemplateArgumentDependentType(type2)) { - if (IS_TYPE_REFERENCE(type1)) - type1 = TPTR_TARGET(type1); - type1 = CParser_RemoveTopMostQualifiers(type1, &qual1); - - if (IS_TYPE_REFERENCE(type2)) - type2 = TPTR_TARGET(type2); - type2 = CParser_RemoveTopMostQualifiers(type2, &qual2); - - if (!is_typesame(type1, type2) || qual1 != qual2) - return 0; - } else { - if (!CTempl_DeduceType(type2, qual2, type1, qual1, info.args, 0, 0)) - return 0; - } - - arg1 = arg1->next; - arg2 = arg2->next; - i--; - } - - return 1; -} - -Boolean CTempl_FuncIsMoreSpecialized(Object *object1, Object *object2) { - return CTempl_FuncIsAtLeastAsSpecialized(object1, object2) && !CTempl_FuncIsAtLeastAsSpecialized(object2, object1); -} - -Object *CTempl_PartialOrdering(Object *object, ObjectList *list, int count) { - int i; - int j; - Object **array; - ObjectList *scan; - Object *arrayBuffer[16]; - - for (count = 1, scan = list; scan; scan = scan->next) { - if (IS_TEMPL_FUNC(scan->object->type)) - count++; - } - - if (count > 16) - array = lalloc(sizeof(Object *) * count); - else - array = arrayBuffer; - - array[0] = object; - for (i = 1, scan = list; scan; scan = scan->next) { - if (IS_TEMPL_FUNC(scan->object->type)) - array[i++] = scan->object; - } - - for (i = 0; i < count; i++) { - if (array[i]) { - for (j = 0; j < count; j++) { - if (array[j] && i != j && CTempl_FuncIsMoreSpecialized(array[i], array[j])) - array[j] = NULL; - } - } - } - - object = NULL; - - for (i = 0; i < count; i++) { - if (array[i]) { - if (object) - return NULL; - object = array[i]; - } - } - - return object; -} - -int CTempl_GetTemplateArgumentExpressionIndex(TemplArg *arg) { - CError_ASSERT(529, arg->data.paramdecl.expr); - - if (ENODE_IS(arg->data.paramdecl.expr, ETEMPLDEP) && arg->data.paramdecl.expr->data.templdep.subtype == TDE_PARAM) - return arg->data.paramdecl.expr->data.templdep.u.pid.index; - - return -1; -} - -static Type *CTempl_GetSpecifiedType(TemplateFunction *templ, Type *type, UInt32 qual, TemplArg *args, UInt32 *resultQual) { - TypeDeduce deduce; - - CTemplFunc_SetupTypeDeduce(&deduce, templ, args); - *resultQual = qual; - return CTemplTool_DeduceTypeCopy(&deduce, type, resultQual); -} - -static Boolean CTempl_DeduceTemplateArgs(TemplArg *args1, TemplArg *args2, TemplArg *argArray) { - int index; - - while (1) { - if (!args1) - return !args2; - if (!args2) - return 0; - - if (args1->pid.type != args2->pid.type) - return 0; - - switch (args1->pid.type) { - case TPT_TYPE: - if (!CTempl_DeduceType1( - args1->data.typeparam.type, args1->data.typeparam.qual, - args2->data.typeparam.type, args2->data.typeparam.qual, - argArray, 1 - )) - return 0; - break; - - case TPT_NONTYPE: - if (CTemplTool_IsTemplateArgumentDependentExpression(args1->data.paramdecl.expr)) { - index = CTempl_GetTemplateArgumentExpressionIndex(args1); - if (index < 0) - return 1; - - if (argArray[index].is_deduced) { - if (!CTemplTool_EqualExprTypes(args2->data.paramdecl.expr, argArray[index].data.paramdecl.expr)) - return 0; - } else { - argArray[index].data.paramdecl.expr = args2->data.paramdecl.expr; - argArray[index].pid.type = TPT_NONTYPE; - argArray[index].is_deduced = 1; - } - } else { - if (!CTemplTool_EqualExprTypes(args2->data.paramdecl.expr, args1->data.paramdecl.expr)) - return 0; - } - break; - - case TPT_TEMPLATE: - if (!IS_TEMPL_CLASS(args2->data.ttargtype)) - return 0; - - index = args1->pid.index; - if (argArray[index].is_deduced) { - if (args2->data.ttargtype != argArray[index].data.ttargtype) - return 0; - } else { - argArray[index].data.ttargtype = args2->data.ttargtype; - argArray[index].pid.type = TPT_TEMPLATE; - argArray[index].is_deduced = 1; - } - break; - - default: - CError_FATAL(640); - } - - args1 = args1->next; - args2 = args2->next; - } -} - -static Boolean CTempl_DeduceTemplDepTemplate(TemplClass *templ1, TemplArg *args1, TemplClass *templ2, TemplArg *args2, TemplArg *argArray) { - if (templ1 != templ2) - return 0; - - return CTempl_DeduceTemplateArgs(args2, args1, argArray); -} - -static Boolean CTempl_DeduceTemplateType(TemplClass *templ, TemplArg *args, TemplClassInst *inst, TemplArg *argArray) { - TemplClassInst *scan; - - for (scan = templ->instances; scan; scan = scan->next) { - if (scan == inst) - return CTempl_DeduceTemplateArgs(args, scan->oargs ? scan->oargs : scan->inst_args, argArray); - } - - return 0; -} - -static Boolean CTempl_DeduceTemplateTypeBase(TemplClass *templ, TemplArg *args, TemplClassInst *inst, TemplArg *argArray, Boolean flag) { - ClassList *base; - - if (CTempl_DeduceTemplateType(templ, args, inst, argArray)) - return 1; - - if (flag) { - for (base = inst->theclass.bases; base; base = base->next) { - if (CTempl_DeduceTemplateType(templ, args, TEMPL_CLASS_INST(base->base), argArray)) { - ctempl_conversion_deduction = 1; - return 1; - } - } - - for (base = inst->theclass.bases; base; base = base->next) { - if (CTempl_DeduceTemplateTypeBase(templ, args, TEMPL_CLASS_INST(base->base), argArray, 1)) { - ctempl_conversion_deduction = 1; - return 1; - } - } - } - - return 0; -} - -static Boolean CTempl_DeduceQualTemplate(TypeTemplDep *type1, TemplArg *args1, Type *type2, TemplArg *argArray) { - int index; - - if (type1->dtype == TEMPLDEP_ARGUMENT && type1->u.pid.type == TPT_TEMPLATE) { - index = type1->u.pid.index; - if (IS_TEMPL_CLASS_INST(type2)) { - if (argArray[index].is_deduced) { - if (argArray[index].data.ttargtype != TYPE(TEMPL_CLASS_INST(type2)->templ)) - return 0; - } else { - argArray[index].data.ttargtype = TYPE(TEMPL_CLASS_INST(type2)->templ); - argArray[index].pid.type = TPT_TEMPLATE; - argArray[index].is_deduced = 1; - } - - return CTempl_DeduceTemplateArgs(args1, TEMPL_CLASS_INST(type2)->inst_args, argArray); - } - - if (IS_TYPE_TEMPLATE(type2)) { - if (TYPE_TEMPLATE(type2)->dtype == TEMPLDEP_TEMPLATE) { - if (argArray[index].is_deduced) { - if (argArray[index].data.ttargtype != TYPE(TYPE_TEMPLATE(type2)->u.templ.templ)) - return 0; - } else { - argArray[index].data.ttargtype = TYPE(TYPE_TEMPLATE(type2)->u.templ.templ); - argArray[index].pid.type = TPT_TEMPLATE; - argArray[index].is_deduced = 1; - } - - return CTempl_DeduceTemplateArgs(args1, TYPE_TEMPLATE(type2)->u.templ.args, argArray); - } - - if (TYPE_TEMPLATE(type2)->dtype == TEMPLDEP_QUALTEMPL) { - return - CTempl_DeduceTypeTemplDep(type1, 0, TYPE(TYPE_TEMPLATE(type2)->u.qualtempl.type), 0, argArray, 1) && - CTempl_DeduceTemplateArgs(args1, TYPE_TEMPLATE(type2)->u.qualtempl.args, argArray); - } - } - } - - return 0; -} - -static Boolean CTempl_DeduceTypeTemplDep(TypeTemplDep *type1, UInt32 qual1, Type *type2, UInt32 qual2, TemplArg *argArray, Boolean flag) { - Type *tmptype; - UInt32 tmpqual; - short index; - Boolean f; - UInt32 modqual; - - switch (type1->dtype) { - case TEMPLDEP_ARGUMENT: - index = type1->u.pid.index; - tmptype = type2; - if (type1->u.pid.type == TPT_TEMPLATE) { - if (argArray[index].is_deduced) { - if (!is_typesame(tmptype, argArray[index].data.ttargtype)) - return 0; - } else { - argArray[index].data.ttargtype = type2; - argArray[index].pid.type = TPT_TEMPLATE; - argArray[index].is_deduced = 1; - } - return 1; - } - - switch (type2->type) { - case TYPEPOINTER: - tmpqual = qual2; - f = 0; - qual2 = TPTR_QUAL(type2); - modqual = qual2; - - if ((modqual & Q_CONST) && (qual1 & Q_CONST)) { - modqual &= ~Q_CONST; - f = 1; - } - if ((modqual & Q_VOLATILE) && (qual1 & Q_VOLATILE)) { - modqual &= ~Q_VOLATILE; - f = 1; - } - - if (f) { - tmptype = galloc(sizeof(TypePointer)); - *TYPE_POINTER(tmptype) = *TYPE_POINTER(type2); - TPTR_QUAL(tmptype) = modqual; - } - - if (flag && (qual2 | modqual) != (qual1 | modqual)) - return 0; - - break; - - case TYPEMEMBERPOINTER: - tmpqual = qual2; - f = 0; - qual2 = TYPE_MEMBER_POINTER(type2)->qual; - modqual = qual2; - - if ((modqual & Q_CONST) && (qual1 & Q_CONST)) { - modqual &= ~Q_CONST; - f = 1; - } - if ((modqual & Q_VOLATILE) && (qual1 & Q_VOLATILE)) { - modqual &= ~Q_VOLATILE; - f = 1; - } - - if (f) { - tmptype = galloc(sizeof(TypeMemberPointer)); - *TYPE_MEMBER_POINTER(tmptype) = *TYPE_MEMBER_POINTER(type2); - TYPE_MEMBER_POINTER(tmptype)->qual = modqual; - } - - if (flag && (qual2 | modqual) != (qual1 | modqual)) - return 0; - - break; - - default: - tmpqual = 0; - if ((qual2 & Q_CONST) && !(qual1 & Q_CONST)) - tmpqual |= Q_CONST; - if ((qual2 & Q_VOLATILE) && !(qual1 & Q_VOLATILE)) - tmpqual |= Q_VOLATILE; - - if (flag && (qual2 | tmpqual) != (qual1 | tmpqual)) - return 0; - } - - if (argArray[index].is_deduced) { - if (!is_typesame(tmptype, argArray[index].data.typeparam.type) || tmpqual != argArray[index].data.typeparam.qual) - return 0; - } else { - argArray[index].data.typeparam.type = tmptype; - argArray[index].data.typeparam.qual = tmpqual; - argArray[index].pid.type = TPT_TYPE; - argArray[index].is_deduced = 1; - } - return 1; - - case TEMPLDEP_QUALNAME: - return 1; - - case TEMPLDEP_TEMPLATE: - if (IS_TYPE_CLASS(type2)) - return CTempl_DeduceTemplateTypeBase( - type1->u.templ.templ, type1->u.templ.args, - TEMPL_CLASS_INST(type2), argArray, 0); - - if (IS_TYPE_TEMPLATE(type2) && TYPE_TEMPLATE(type2)->dtype == TEMPLDEP_TEMPLATE) - return CTempl_DeduceTemplDepTemplate( - TYPE_TEMPLATE(type2)->u.templ.templ, TYPE_TEMPLATE(type2)->u.templ.args, - type1->u.templ.templ, type1->u.templ.args, - argArray - ); - - return 0; - - case TEMPLDEP_ARRAY: - if (IS_TYPE_ARRAY(type2)) { - SInt32 elements; - - if (!CTempl_DeduceType1(type1->u.array.type, qual1, TPTR_TARGET(type2), qual2, argArray, flag)) - return 0; - - if (ENODE_IS(type1->u.array.index, EINTCONST)) { - CError_ASSERT(961, TPTR_TARGET(type2)->size); - return (type2->size / TPTR_TARGET(type2)->size) == CInt64_GetULong(&type1->u.array.index->data.intval); - } - - if (!ENODE_IS(type1->u.array.index, ETEMPLDEP) || type1->u.array.index->data.templdep.subtype != TDE_PARAM) - return 1; - - CError_ASSERT(970, TPTR_TARGET(type2)->size); - - elements = type2->size / TPTR_TARGET(type2)->size; - index = type1->u.array.index->data.templdep.u.pid.index; - if (argArray[index].is_deduced) { - CError_ASSERT(976, ENODE_IS(argArray[index].data.paramdecl.expr, EINTCONST)); - return elements == CInt64_GetULong(&argArray[index].data.paramdecl.expr->data.intval); - } else { - argArray[index].data.paramdecl.expr = intconstnode(CABI_GetPtrDiffTType(), elements); - argArray[index].pid.type = TPT_NONTYPE; - argArray[index].is_deduced = 1; - return 1; - } - } else if (IS_TYPE_TEMPLATE(type2) && TYPE_TEMPLATE(type2)->dtype == TEMPLDEP_ARRAY) { - if (!CTempl_DeduceType1(type1->u.array.type, qual1, TYPE_TEMPLATE(type2)->u.array.type, qual2, argArray, flag)) - return 0; - - if (ENODE_IS(type1->u.array.index, EINTCONST)) { - return ENODE_IS(TYPE_TEMPLATE(type2)->u.array.index, EINTCONST) && - CInt64_Equal(type1->u.array.index->data.intval, TYPE_TEMPLATE(type2)->u.array.index->data.intval); - } - - if (!ENODE_IS(type1->u.array.index, ETEMPLDEP) || type1->u.array.index->data.templdep.subtype != TDE_PARAM) - return 1; - - index = type1->u.array.index->data.templdep.u.pid.index; - if (argArray[index].is_deduced) { - return CTemplTool_EqualExprTypes(TYPE_TEMPLATE(type2)->u.array.index, argArray[index].data.paramdecl.expr); - } else { - argArray[index].data.paramdecl.expr = TYPE_TEMPLATE(type2)->u.array.index; - argArray[index].pid.type = TPT_NONTYPE; - argArray[index].is_deduced = 1; - return 1; - } - } - - return 0; - - case TEMPLDEP_QUALTEMPL: - return CTempl_DeduceQualTemplate(type1->u.qualtempl.type, type1->u.qualtempl.args, type2, argArray); - - case TEMPLDEP_BITFIELD: - default: - CError_FATAL(1022); - return 1; - } -} - -static Boolean CTempl_DeduceFuncType(TypeFunc *tfunc1, TypeFunc *tfunc2, TemplArg *argArray) { - FuncArg *arg1; - FuncArg *arg2; - Type *type2; - Type *type1; - UInt32 qual2; - UInt32 qual1; - - arg1 = tfunc1->args; - arg2 = tfunc2->args; - - if (IS_TYPEFUNC_NONSTATIC_METHOD(tfunc1) && !IS_TYPEFUNC_METHOD(tfunc2)) { - CError_ASSERT(1045, arg1); - arg1 = arg1->next; - } - - while (1) { - if (arg1 == NULL) - return !arg2; - if (arg1 == &oldstyle) - return arg2 == &oldstyle; - if (arg1 == &elipsis) - return arg2 == &elipsis; - - if (arg2 == NULL || arg2 == &oldstyle || arg2 == &elipsis) - return 0; - - qual2 = arg2->qual; - type2 = CParser_RemoveTopMostQualifiers(arg2->type, &qual2); - - qual1 = arg1->qual; - type1 = CParser_RemoveTopMostQualifiers(arg1->type, &qual1); - - if (!CTempl_DeduceType1(type1, qual1, type2, qual2, argArray, 1)) - return 0; - - arg1 = arg1->next; - arg2 = arg2->next; - } -} - -static Boolean CTempl_DeduceType1(Type *type1, UInt32 qual1, Type *type2, UInt32 qual2, TemplArg *argArray, Boolean flag) { - while (1) { - switch (type1->type) { - case TYPETEMPLATE: - return CTempl_DeduceTypeTemplDep(TYPE_TEMPLATE(type1), qual1, type2, qual2, argArray, flag); - - case TYPEVOID: - case TYPEINT: - case TYPEFLOAT: - case TYPEENUM: - case TYPESTRUCT: - case TYPECLASS: - return type1 == type2; - - case TYPEMEMBERPOINTER: - if (type1->type != type2->type || TYPE_MEMBER_POINTER(type1)->qual != TYPE_MEMBER_POINTER(type2)->qual) - return 0; - if (!CTempl_DeduceType1(TYPE_MEMBER_POINTER(type1)->ty1, qual1, TYPE_MEMBER_POINTER(type2)->ty1, qual2, argArray, flag)) - return 0; - type1 = TYPE_MEMBER_POINTER(type1)->ty2; - type2 = TYPE_MEMBER_POINTER(type2)->ty2; - continue; - - case TYPEARRAY: - if (type2->type != TYPEARRAY) - return 0; - type1 = TPTR_TARGET(type1); - type2 = TPTR_TARGET(type2); - continue; - - case TYPEPOINTER: - if (type2->type != TYPEPOINTER || TPTR_QUAL(type1) != TPTR_QUAL(type2)) - return 0; - type1 = TPTR_TARGET(type1); - type2 = TPTR_TARGET(type2); - continue; - - case TYPEFUNC: - if (type1->type != type2->type) - return 0; - - if (CTempl_DeduceType1(TYPE_FUNC(type1)->functype, TYPE_FUNC(type1)->qual, TYPE_FUNC(type2)->functype, TYPE_FUNC(type2)->qual, argArray, flag)) - return CTempl_DeduceFuncType(TYPE_FUNC(type1), TYPE_FUNC(type2), argArray); - - return 0; - - default: - CError_FATAL(1124); - } - } -} - -static Boolean CTempl_DeduceType2(Type *type1, UInt32 qual1, Type *type2, UInt32 qual2, TemplArg *argArray) { - while (1) { - switch (type1->type) { - case TYPEPOINTER: - if (type2->type != TYPEPOINTER) - return 0; - if (!CParser_IsSameOrMoreCVQualified(TPTR_QUAL(type2), TPTR_QUAL(type1))) - return 0; - type1 = TPTR_TARGET(type1); - type2 = TPTR_TARGET(type2); - continue; - - case TYPEMEMBERPOINTER: - if (type2->type != TYPEMEMBERPOINTER) - return 0; - if (!CParser_IsSameOrMoreCVQualified(TYPE_MEMBER_POINTER(type2)->qual, TYPE_MEMBER_POINTER(type1)->qual)) - return 0; - if (!CTempl_DeduceType2(TYPE_MEMBER_POINTER(type1)->ty1, qual1, TYPE_MEMBER_POINTER(type2)->ty1, qual2, argArray)) - return 0; - type1 = TYPE_MEMBER_POINTER(type1)->ty2; - type2 = TYPE_MEMBER_POINTER(type2)->ty2; - continue; - - default: - if (CParser_IsSameOrMoreCVQualified(qual2, qual1)) - return CTempl_DeduceType1(type1, qual2, type2, qual2, argArray, 0); - return 0; - } - } -} - -static Boolean CTempl_DeduceType3(Type *type1, UInt32 qual1, Type *type2, UInt32 qual2, TemplArg *argArray) { - Boolean flag = 0; - - while (1) { - switch (type1->type) { - case TYPEPOINTER: - flag = 1; - if (type2->type != TYPEPOINTER) - return 0; - if (!CParser_IsSameOrMoreCVQualified(TPTR_QUAL(type2), TPTR_QUAL(type1))) - return 0; - type1 = TPTR_TARGET(type1); - type2 = TPTR_TARGET(type2); - continue; - - case TYPEMEMBERPOINTER: - flag = 1; - if (type2->type != TYPEMEMBERPOINTER) - return 0; - if (!CParser_IsSameOrMoreCVQualified(TYPE_MEMBER_POINTER(type2)->qual, TYPE_MEMBER_POINTER(type1)->qual)) - return 0; - if (!CTempl_DeduceType2(TYPE_MEMBER_POINTER(type1)->ty1, qual1, TYPE_MEMBER_POINTER(type2)->ty1, qual2, argArray)) - return 0; - type1 = TYPE_MEMBER_POINTER(type1)->ty2; - type2 = TYPE_MEMBER_POINTER(type2)->ty2; - continue; - - default: - if (!flag) - return 0; - if (CParser_IsSameOrMoreCVQualified(qual2, qual1)) - return CTempl_DeduceType1(type1, qual2, type2, qual2, argArray, 0); - return 0; - } - } -} - -static Boolean CTempl_DeduceType4(Type *type1, UInt32 qual1, Type *type2, UInt32 qual2, TemplArg *argArray) { - if (IS_TYPE_POINTER_ONLY(type1)) { - if (!IS_TYPE_POINTER_ONLY(type2)) - return 0; - - if (!CParser_IsSameOrMoreCVQualified(TPTR_QUAL(type1), TPTR_QUAL(type2))) - return 0; - - type1 = TPTR_TARGET(type1); - type2 = TPTR_TARGET(type2); - } - - if (IS_TYPE_TEMPLATE(type1) && TYPE_TEMPLATE(type1)->dtype == TEMPLDEP_TEMPLATE && IS_TYPE_CLASS(type2)) { - if (CParser_IsSameOrMoreCVQualified(qual1, qual2)) - return CTempl_DeduceTemplateTypeBase( - TYPE_TEMPLATE(type1)->u.templ.templ, - TYPE_TEMPLATE(type1)->u.templ.args, - TEMPL_CLASS_INST(type2), - argArray, - 1); - else - return 0; - } - - return 0; -} - -Boolean CTempl_DeduceType(Type *type1, UInt32 qual1, Type *type2, UInt32 qual2, TemplArg *argArray, Boolean flag1, Boolean flag2) { - Boolean flag31; - Boolean flag8; - - flag31 = 0; - flag8 = 1; - - if (flag1 || flag2) { - if (IS_TYPE_REFERENCE(type1)) { - type1 = TPTR_TARGET(type1); - flag31 = 1; - } else { - switch (type2->type) { - case TYPEFUNC: - type2 = CDecl_NewPointerType(type2); - break; - case TYPEARRAY: - type2 = CDecl_NewPointerType(TPTR_TARGET(type2)); - break; - } - - type1 = CParser_RemoveTopMostQualifiers(type1, &qual1); - type2 = CParser_RemoveTopMostQualifiers(type2, &qual2); - } - flag8 = 0; - } - - if (CTempl_DeduceType1(type1, qual1, type2, qual2, argArray, flag8)) - return 1; - - if (flag1 || flag2) { - if (flag31 && CTempl_DeduceType2(type1, qual1, type2, qual2, argArray)) - return 1; - if (CTempl_DeduceType3(type1, qual1, type2, qual2, argArray)) - return 1; - if (flag1 && CTempl_DeduceType4(type1, qual1, type2, qual2, argArray)) - return 1; - } - - return 0; -} - -static Boolean CTempl_TypeNeedsDeduction(Type *type) { - FuncArg *arg; - Boolean result; - - while (1) { - switch (type->type) { - case TYPETEMPLATE: - switch (TYPE_TEMPLATE(type)->dtype) { - case TEMPLDEP_ARGUMENT: - if ( - TYPE_TEMPLATE(type)->u.pid.index >= ctempl_explicitargs_num || - TYPE_TEMPLATE(type)->u.pid.nindex != ctempl_explicitargs_nindex - ) - ctempl_explicitargs_all = 0; - return 1; - - case TEMPLDEP_QUALNAME: - CTempl_TypeNeedsDeduction(TYPE(TYPE_TEMPLATE(type)->u.qual.type)); - return 1; - - case TEMPLDEP_TEMPLATE: - ctempl_explicitargs_all = 0; - return 1; - - case TEMPLDEP_ARRAY: - CTempl_TypeNeedsDeduction(TYPE_TEMPLATE(type)->u.array.type); - ctempl_explicitargs_all = 0; - return 1; - - case TEMPLDEP_QUALTEMPL: - CTempl_TypeNeedsDeduction(TYPE(TYPE_TEMPLATE(type)->u.qualtempl.type)); - ctempl_explicitargs_all = 0; - return 1; - - case TEMPLDEP_BITFIELD: - default: - CError_FATAL(1357); - } - - case TYPEVOID: - case TYPEINT: - case TYPEFLOAT: - case TYPEENUM: - case TYPESTRUCT: - case TYPECLASS: - return 0; - - case TYPEMEMBERPOINTER: - result = 0; - if (CTempl_TypeNeedsDeduction(TYPE_MEMBER_POINTER(type)->ty1)) - result = 1; - if (CTempl_TypeNeedsDeduction(TYPE_MEMBER_POINTER(type)->ty2)) - result = 1; - return result; - - case TYPEPOINTER: - case TYPEARRAY: - type = TPTR_TARGET(type); - continue; - - case TYPEFUNC: - result = 0; - for (arg = TYPE_FUNC(type)->args; arg && arg != &elipsis; arg = arg->next) { - if (CTempl_TypeNeedsDeduction(arg->type)) - result = 1; - } - - if (CTempl_TypeNeedsDeduction(TYPE_FUNC(type)->functype)) - result = 1; - return result; - - default: - CError_FATAL(1389); - } - } -} - -static Boolean CTempl_MatchTemplFunc(Object *object, DeduceInfo *info, FuncArg *args, ENodeList *exprs, Match13 *match13ptr) { - Match13 match13; - int i; - - memclrw(&match13, sizeof(match13)); - - while (1) { - if (!args || args->type == &stvoid) { - if (!exprs) - break; - return 0; - } - - if (args == &elipsis) - break; - if (args == &oldstyle) - break; - - if (!exprs) { - if (args->dexpr) - break; - return 0; - } - - ctempl_explicitargs_nindex = info->x12C; - ctempl_explicitargs_num = info->count; - ctempl_explicitargs_all = 1; - - if (CTempl_TypeNeedsDeduction(args->type)) { - if (!ctempl_explicitargs_all) { - UInt32 cv2; - UInt32 cv1; - Type *type2; - Type *type1; - UInt32 qual2; - UInt32 qual1; - - type1 = args->type; - qual1 = args->qual & (Q_CONST | Q_VOLATILE); - - type2 = exprs->node->rtype; - qual2 = ENODE_QUALS(exprs->node); - - if (IS_TYPE_REFERENCE(type1)) { - type1 = TPTR_TARGET(type1); - cv1 = CParser_GetCVTypeQualifiers(type1, qual1); - cv2 = CParser_GetCVTypeQualifiers(type2, qual2); - if ( - (!(cv1 & Q_CONST) && (cv2 & Q_CONST)) || - (!(cv1 & Q_VOLATILE) && (cv2 & Q_VOLATILE)) - ) - return 0; - - if (!(cv1 & Q_CONST) && !CExpr_IsLValue(exprs->node)) - return 0; - } - - type1 = CParser_RemoveTopMostQualifiers(type1, &qual1); - type2 = CParser_RemoveTopMostQualifiers(type2, &qual2); - - if (ENODE_IS(exprs->node, EOBJREF) && IS_TEMPL_FUNC(exprs->node->data.objref->type)) - return 0; - - if (ENODE_IS(exprs->node, EOBJLIST)) { - NameSpaceObjectList *list; - - for (list = exprs->node->data.objlist.list; list; list = list->next) { - if (list->object->otype == OT_OBJECT && IS_TEMPL_FUNC(OBJECT(list->object)->type)) - break; - } - - if (list) - return 0; - - if (IS_TYPE_FUNC(type2)) - type2 = CDecl_NewPointerType(type2); - } - - ctempl_conversion_deduction = 0; - if (!CTempl_DeduceType(type1, qual1, type2, qual2, info->args, 1, 0)) - return 0; - - if (ctempl_conversion_deduction) - match13.anotherm5.x4++; - else - match13.anotherm5.x0++; - - if (IS_TYPE_POINTER_ONLY(args->type)) - CExpr_MatchCV(type2, qual2, args->type, args->qual, &match13); - - } else { - Type *type; - UInt32 qual; - - type = CTempl_GetSpecifiedType(CTemplTool_GetFuncTempl(object), args->type, args->qual, info->args, &qual); - if (type && !CExpr_MatchAssign(type, qual, exprs->node, &match13)) - return 0; - } - } else { - if (copts.old_argmatch && !CExpr_MatchAssign(args->type, args->qual, exprs->node, &match13)) - return 0; - } - - exprs = exprs->next; - args = args->next; - } - - for (i = 0; i < info->maxCount; i++) { - if (!info->args[i].is_deduced) - return 0; - info->args[i].next = &info->args[i + 1]; - } - info->args[info->maxCount].next = NULL; - - return CExpr_MatchCompare(object, match13ptr, &match13); -} - -void CTempl_FuncMatch(NameSpaceObjectList *list, TemplArg *args, ENodeList *argexprs, Match13 *match13ptr, ENode *expr) { - Object *obj; - Object *success; - Object *object1; - FuncMatchArgs funcMatchArgs; - DeduceInfo info; - DeduceInfo info2; - - object1 = match13ptr->obj; - success = NULL; - while (list) { - obj = OBJECT(list->object); - if ( - obj->otype == OT_OBJECT && - IS_TEMPL_FUNC(obj->type) && - CExpr_GetFuncMatchArgs(obj, argexprs, expr, &funcMatchArgs) && - CTemplTool_InitDeduceInfo(&info, CTemplTool_GetFuncTempl(obj)->params, args, 0) && - CTempl_MatchTemplFunc(obj, &info, funcMatchArgs.args, funcMatchArgs.exprs, match13ptr) - ) - { - info2 = info; - if (info.args == info.argBuffer) - info2.args = info2.argBuffer; - success = obj; - } - list = list->next; - } - - if (success) { - if (match13ptr->list) { - ENodeList *argexpr = argexprs; - int argexprcount = 0; - while (argexpr) { - argexpr = argexpr->next; - argexprcount++; - } - - obj = CTempl_PartialOrdering(match13ptr->obj, match13ptr->list, argexprcount); - if (!obj) { - CError_OverloadedFunctionError(match13ptr->obj, match13ptr->list); - match13ptr->list = NULL; - if (object1) - match13ptr->obj = object1; - else - match13ptr->obj = CTempl_GetCreateFuncInstance(success, info2.args, NULL)->object; - } else { - NameSpaceObjectList mylist; - mylist.next = NULL; - mylist.object = OBJ_BASE(obj); - memclrw(match13ptr, sizeof(Match13)); - CTempl_FuncMatch(&mylist, args, argexprs, match13ptr, expr); - } - } else { - match13ptr->obj = CTempl_GetCreateFuncInstance(success, info2.args, NULL)->object; - } - } else { - match13ptr->obj = object1; - } -} - -static Boolean CExpr_DeduceFromObjList(FuncArg *arg, NameSpaceObjectList *list, DeduceInfo *info) { - TemplArg *savebuf; - NameSpaceObjectList *scan; - SInt32 size; - - for (scan = list; scan; scan = scan->next) { - if (scan->object->otype == OT_OBJECT && IS_TEMPL_FUNC(OBJECT(scan->object)->type)) - return 0; - } - - size = sizeof(TemplArg) * info->maxCount; - savebuf = lalloc(size); - - for (scan = list; scan; scan = scan->next) { - if (scan->object->otype == OT_OBJECT && IS_TYPE_FUNC(OBJECT(scan->object)->type)) { - Object *obj; - - memcpy(savebuf, info->args, size); - - obj = OBJECT(scan->object); - if (CTempl_DeduceType( - arg->type, arg->qual & (Q_CONST | Q_VOLATILE), - obj->type, obj->qual, - savebuf, 1, 0 - )) - { - memcpy(info->args, savebuf, size); - return 1; - } - } - } - - return 0; -} - -Object *CTempl_DeduceFromFunctionCall(Object *funcobj, TemplArg *templargs, ENodeList *argexprs) { - DeduceInfo info; - FuncArg *arg; - int i; - - CError_ASSERT(1655, IS_TEMPL_FUNC(funcobj->type)); - - if (CTemplTool_InitDeduceInfo(&info, CTemplTool_GetFuncTempl(funcobj)->params, templargs, 0)) { - arg = TYPE_FUNC(funcobj->type)->args; - if (IS_TYPEFUNC_NONSTATIC_METHOD(TYPE_FUNC(funcobj->type))) { - CError_ASSERT(1664, arg); - arg = arg->next; - } - - while (1) { - if (!arg || arg->type == &stvoid) { - if (argexprs) - return NULL; - break; - } - - if (arg == &elipsis) - break; - if (arg == &oldstyle) - break; - - if (!argexprs) { - if (arg->dexpr) - break; - return NULL; - } - - ctempl_explicitargs_nindex = info.x12C; - ctempl_explicitargs_num = info.count; - ctempl_explicitargs_all = 1; - - if (CTempl_TypeNeedsDeduction(arg->type) && !ctempl_explicitargs_all) { - ENode *node = argexprs->node; - - if (ENODE_IS(node, EOBJREF) && IS_TEMPL_FUNC(node->data.objref->type)) - return NULL; - - if (ENODE_IS(node, EOBJLIST)) { - if (!CExpr_DeduceFromObjList(arg, node->data.objlist.list, &info)) - return NULL; - } else { - if (!CTempl_DeduceType( - arg->type, arg->qual & (Q_CONST | Q_VOLATILE), - node->rtype, ENODE_QUALS(node), - info.args, 1, 0)) - return NULL; - } - } - - argexprs = argexprs->next; - arg = arg->next; - } - - for (i = 0; i < info.maxCount; i++) { - if (!info.args[i].is_deduced) - return 0; - info.args[i].next = &info.args[i + 1]; - } - info.args[info.maxCount].next = NULL; - - return CTempl_GetCreateFuncInstance(funcobj, info.args, NULL)->object; - } else { - return NULL; - } -} - -Object *CTempl_DeduceFromConversion(Object *funcobj, Type *type, UInt32 qual) { - DeduceInfo info; - int i; - - CError_ASSERT(1745, IS_TEMPL_FUNC(funcobj->type)); - - if (!CTemplTool_InitDeduceInfo(&info, CTemplTool_GetFuncTempl(funcobj)->params, NULL, 0)) - return NULL; - - ctempl_explicitargs_nindex = info.x12C; - ctempl_explicitargs_num = info.count; - ctempl_explicitargs_all = 1; - - if (!CTempl_TypeNeedsDeduction(TYPE_FUNC(funcobj->type)->functype)) - return NULL; - - if (!CTempl_DeduceType(TYPE_FUNC(funcobj->type)->functype, TYPE_FUNC(funcobj->type)->qual, type, qual, info.args, 0, 1)) - return NULL; - - for (i = 0; i < info.maxCount; i++) { - if (!info.args[i].is_deduced) - return 0; - info.args[i].next = &info.args[i + 1]; - } - info.args[info.maxCount].next = NULL; - - return CTempl_GetCreateFuncInstance(funcobj, info.args, NULL)->object; -} - -static int CTemplFunc_TemplateNestLevel(NameSpace *nspace) { - int level = 0; - - while (nspace) { - if (nspace->theclass && (nspace->theclass->flags & CLASS_IS_TEMPL_ANY)) - level++; - nspace = nspace->parent; - } - - return level; -} - -static Boolean CTemplFunc_SameFuncType(TypeFunc *a, TypeFunc *b) { - FuncArg *arg1; - FuncArg *arg2; - - CError_ASSERT(1800, IS_TYPE_FUNC(a) && IS_TYPE_FUNC(b)); - - if (!is_typesame(a->functype, b->functype)) - return 0; - - if (a->qual != b->qual) - return 0; - - if ((a->flags & FUNC_CALL_CONV_MASK) != (b->flags & FUNC_CALL_CONV_MASK)) - return 0; - - arg1 = a->args; - if ((a->flags & FUNC_METHOD) && !TYPE_METHOD(a)->is_static) { - CError_ASSERT(1808, arg1); - arg1 = arg1->next; - } - - arg2 = b->args; - if ((b->flags & FUNC_METHOD) && !TYPE_METHOD(b)->is_static) { - CError_ASSERT(1814, arg2); - arg2 = arg2->next; - } - - return is_arglistsame(arg1, arg2); -} - -Object *CTempl_TemplateFunctionCheck(DeclInfo *di, NameSpaceObjectList *nsol) { - TemplArg *arg; - TemplFuncInstance *inst; - Object *object; - - for (arg = di->expltargs; 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; - continue; - default: - CError_FATAL(1844); - } - - break; - } - - if (arg) { - while (nsol) { - object = OBJECT(nsol->object); - if ( - object->otype == OT_OBJECT && - IS_TEMPL_FUNC(object->type) && - CTemplTool_IsSameTemplate(CTemplTool_GetFuncTempl(object)->params, di->expltargs) && - CTemplFunc_SameFuncType(TYPE_FUNC(OBJECT(nsol->object)->type), TYPE_FUNC(di->thetype)) - ) - return OBJECT(nsol->object); - - nsol = nsol->next; - } - } else { - while (nsol) { - object = OBJECT(nsol->object); - if ( - object->otype == OT_OBJECT && - IS_TEMPL_FUNC(object->type) && - (inst = CTempl_DeduceFunc(object, TYPE_FUNC(di->thetype), di->expltargs, NULL, 1)) - ) - { - if (di->x3C) { - if (!(di->qual & Q_INLINE)) { - if (!inst->is_specialized) - inst->object->qual &= ~Q_INLINE; - } else { - inst->object->qual |= Q_INLINE; - } - - if (!inst->is_specialized && inst->is_instantiated) - CError_Error(CErrorStr335); - - if (di->x3C != (CTemplFunc_TemplateNestLevel(inst->object->nspace) + 1)) - CError_Warning(CErrorStr335); - - inst->is_specialized = 1; - di->x3C = 0; - } - - CTemplTool_MergeArgNames(TYPE_FUNC(di->thetype), TYPE_FUNC(inst->object->type)); - di->x38 = CTemplTool_GetFuncTempl(OBJECT(nsol->object)); - return inst->object; - } - nsol = nsol->next; - } - } - - CError_ResetErrorSkip(); - CError_Error(CErrorStr335); - di->x3C = 0; - return NULL; -} |