mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-10 04:22:20 +02:00
Fixed bugs related to generic delegate type references
This commit is contained in:
parent
cd26d44a62
commit
7b9c994066
8 changed files with 240 additions and 62 deletions
|
@ -443,6 +443,7 @@ public:
|
||||||
bool IsSkippingExtraResolveChecks();
|
bool IsSkippingExtraResolveChecks();
|
||||||
int GetVTableMethodOffset();
|
int GetVTableMethodOffset();
|
||||||
BfType* CheckSymbolReferenceTypeRef(BfModule* module, BfTypeReference* typeRef);
|
BfType* CheckSymbolReferenceTypeRef(BfModule* module, BfTypeReference* typeRef);
|
||||||
|
void AddToRebuildTypeList(BfTypeInstance* typeInst, HashSet<BfTypeInstance*>& rebuildTypeInstList);
|
||||||
void AddDepsToRebuildTypeList(BfTypeInstance* typeInst, HashSet<BfTypeInstance*>& rebuildTypeInstList);
|
void AddDepsToRebuildTypeList(BfTypeInstance* typeInst, HashSet<BfTypeInstance*>& rebuildTypeInstList);
|
||||||
void CompileReified();
|
void CompileReified();
|
||||||
void PopulateReified();
|
void PopulateReified();
|
||||||
|
|
|
@ -372,6 +372,7 @@ public:
|
||||||
BfAllocPool<BfGenericInstanceTypeRef> mGenericTypeRefPool;
|
BfAllocPool<BfGenericInstanceTypeRef> mGenericTypeRefPool;
|
||||||
BfAllocPool<BfConcreteInterfaceType> mConcreteInterfaceTypePool;
|
BfAllocPool<BfConcreteInterfaceType> mConcreteInterfaceTypePool;
|
||||||
BfAllocPool<BfConstExprValueType> mConstExprValueTypePool;
|
BfAllocPool<BfConstExprValueType> mConstExprValueTypePool;
|
||||||
|
BfAllocPool<BfDelegateType> mDelegateTypePool;
|
||||||
BfPrimitiveType* mPrimitiveTypes[BfTypeCode_Length];
|
BfPrimitiveType* mPrimitiveTypes[BfTypeCode_Length];
|
||||||
BfPrimitiveType* mPrimitiveStructTypes[BfTypeCode_Length];
|
BfPrimitiveType* mPrimitiveStructTypes[BfTypeCode_Length];
|
||||||
|
|
||||||
|
|
|
@ -210,13 +210,25 @@ bool BfMethodMatcher::IsMemberAccessible(BfTypeInstance* typeInst, BfTypeDef* de
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BfMethodMatcher::InferGenericArgument(BfMethodInstance* methodInstance, BfType* argType, BfType* wantType, BfIRValue argValue)
|
bool BfMethodMatcher::InferGenericArgument(BfMethodInstance* methodInstance, BfType* argType, BfType* wantType, BfIRValue argValue, HashSet<BfType*>& checkedTypeSet)
|
||||||
{
|
{
|
||||||
if (argType == NULL)
|
if (argType == NULL)
|
||||||
return false;
|
return false;
|
||||||
if (argType->IsVar())
|
if (argType->IsVar())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (!wantType->IsUnspecializedType())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
bool alreadyChecked = false;
|
||||||
|
auto _AddToCheckedSet = [](BfType* type, HashSet<BfType*>& checkedTypeSet, bool& alreadyChecked)
|
||||||
|
{
|
||||||
|
if (alreadyChecked)
|
||||||
|
return true;
|
||||||
|
alreadyChecked = true;
|
||||||
|
return checkedTypeSet.Add(type);
|
||||||
|
};
|
||||||
|
|
||||||
if (wantType->IsGenericParam())
|
if (wantType->IsGenericParam())
|
||||||
{
|
{
|
||||||
auto wantGenericParam = (BfGenericParamType*)wantType;
|
auto wantGenericParam = (BfGenericParamType*)wantType;
|
||||||
|
@ -226,6 +238,13 @@ bool BfMethodMatcher::InferGenericArgument(BfMethodInstance* methodInstance, BfT
|
||||||
{
|
{
|
||||||
BF_ASSERT((argType == NULL) || (!argType->IsVar()));
|
BF_ASSERT((argType == NULL) || (!argType->IsVar()));
|
||||||
|
|
||||||
|
if (argType != NULL)
|
||||||
|
{
|
||||||
|
// Disallow illegal types
|
||||||
|
if (argType->IsRef())
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (mCheckMethodGenericArguments[wantGenericParam->mGenericParamIdx] != argType)
|
if (mCheckMethodGenericArguments[wantGenericParam->mGenericParamIdx] != argType)
|
||||||
{
|
{
|
||||||
if (methodGenericTypeConstraint != NULL)
|
if (methodGenericTypeConstraint != NULL)
|
||||||
|
@ -243,7 +262,7 @@ bool BfMethodMatcher::InferGenericArgument(BfMethodInstance* methodInstance, BfT
|
||||||
if (argGenericType->mTypeDef == wantGenericType->mTypeDef)
|
if (argGenericType->mTypeDef == wantGenericType->mTypeDef)
|
||||||
{
|
{
|
||||||
for (int genericArgIdx = 0; genericArgIdx < (int)argGenericType->mTypeGenericArguments.size(); genericArgIdx++)
|
for (int genericArgIdx = 0; genericArgIdx < (int)argGenericType->mTypeGenericArguments.size(); genericArgIdx++)
|
||||||
InferGenericArgument(methodInstance, argGenericType->mTypeGenericArguments[genericArgIdx], wantGenericType->mTypeGenericArguments[genericArgIdx], BfIRValue());
|
InferGenericArgument(methodInstance, argGenericType->mTypeGenericArguments[genericArgIdx], wantGenericType->mTypeGenericArguments[genericArgIdx], BfIRValue(), checkedTypeSet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (checkArgType->IsSizedArray())
|
else if (checkArgType->IsSizedArray())
|
||||||
|
@ -251,10 +270,10 @@ bool BfMethodMatcher::InferGenericArgument(BfMethodInstance* methodInstance, BfT
|
||||||
auto sizedArrayType = (BfSizedArrayType*)checkArgType;
|
auto sizedArrayType = (BfSizedArrayType*)checkArgType;
|
||||||
if (wantGenericType->mTypeDef == mModule->mCompiler->mSizedArrayTypeDef)
|
if (wantGenericType->mTypeDef == mModule->mCompiler->mSizedArrayTypeDef)
|
||||||
{
|
{
|
||||||
InferGenericArgument(methodInstance, sizedArrayType->mElementType, wantGenericType->mTypeGenericArguments[0], BfIRValue());
|
InferGenericArgument(methodInstance, sizedArrayType->mElementType, wantGenericType->mTypeGenericArguments[0], BfIRValue(), checkedTypeSet);
|
||||||
auto intType = mModule->GetPrimitiveType(BfTypeCode_IntPtr);
|
auto intType = mModule->GetPrimitiveType(BfTypeCode_IntPtr);
|
||||||
BfTypedValue arraySize = BfTypedValue(mModule->mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, (uint64)sizedArrayType->mElementCount), intType);
|
BfTypedValue arraySize = BfTypedValue(mModule->mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, (uint64)sizedArrayType->mElementCount), intType);
|
||||||
InferGenericArgument(methodInstance, mModule->CreateConstExprValueType(arraySize), wantGenericType->mTypeGenericArguments[1], BfIRValue());
|
InferGenericArgument(methodInstance, mModule->CreateConstExprValueType(arraySize), wantGenericType->mTypeGenericArguments[1], BfIRValue(), checkedTypeSet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (checkArgType->IsPointer())
|
else if (checkArgType->IsPointer())
|
||||||
|
@ -262,7 +281,7 @@ bool BfMethodMatcher::InferGenericArgument(BfMethodInstance* methodInstance, BfT
|
||||||
auto pointerType = (BfPointerType*)checkArgType;
|
auto pointerType = (BfPointerType*)checkArgType;
|
||||||
if (wantGenericType->mTypeDef == mModule->mCompiler->mPointerTTypeDef)
|
if (wantGenericType->mTypeDef == mModule->mCompiler->mPointerTTypeDef)
|
||||||
{
|
{
|
||||||
InferGenericArgument(methodInstance, pointerType->mElementType, wantGenericType->mTypeGenericArguments[0], BfIRValue());
|
InferGenericArgument(methodInstance, pointerType->mElementType, wantGenericType->mTypeGenericArguments[0], BfIRValue(), checkedTypeSet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -359,7 +378,7 @@ bool BfMethodMatcher::InferGenericArgument(BfMethodInstance* methodInstance, BfT
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wantType->IsGenericTypeInstance())
|
if ((wantType->IsGenericTypeInstance()) && (wantType->IsUnspecializedTypeVariation()))
|
||||||
{
|
{
|
||||||
auto wantGenericType = (BfGenericTypeInstance*)wantType;
|
auto wantGenericType = (BfGenericTypeInstance*)wantType;
|
||||||
if (!argType->IsGenericTypeInstance())
|
if (!argType->IsGenericTypeInstance())
|
||||||
|
@ -369,7 +388,14 @@ bool BfMethodMatcher::InferGenericArgument(BfMethodInstance* methodInstance, BfT
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
for (int genericArgIdx = 0; genericArgIdx < (int)argGenericType->mTypeGenericArguments.size(); genericArgIdx++)
|
for (int genericArgIdx = 0; genericArgIdx < (int)argGenericType->mTypeGenericArguments.size(); genericArgIdx++)
|
||||||
InferGenericArgument(methodInstance, argGenericType->mTypeGenericArguments[genericArgIdx], wantGenericType->mTypeGenericArguments[genericArgIdx], BfIRValue());
|
{
|
||||||
|
BfType* wantGenericArgument = wantGenericType->mTypeGenericArguments[genericArgIdx];
|
||||||
|
if (!wantGenericArgument->IsUnspecializedType())
|
||||||
|
continue;
|
||||||
|
if (!_AddToCheckedSet(argType, checkedTypeSet, alreadyChecked))
|
||||||
|
return true;
|
||||||
|
InferGenericArgument(methodInstance, argGenericType->mTypeGenericArguments[genericArgIdx], wantGenericArgument, BfIRValue(), checkedTypeSet);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -379,14 +405,14 @@ bool BfMethodMatcher::InferGenericArgument(BfMethodInstance* methodInstance, BfT
|
||||||
if (!argType->IsRef())
|
if (!argType->IsRef())
|
||||||
{
|
{
|
||||||
// Match to non-ref
|
// Match to non-ref
|
||||||
InferGenericArgument(methodInstance, argType, wantRefType->mElementType, BfIRValue());
|
InferGenericArgument(methodInstance, argType, wantRefType->mElementType, BfIRValue(), checkedTypeSet);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
auto argRefType = (BfRefType*)argType;
|
auto argRefType = (BfRefType*)argType;
|
||||||
//TODO: We removed this check so we still infer even if we have the wrong ref kind
|
//TODO: We removed this check so we still infer even if we have the wrong ref kind
|
||||||
//if (wantRefType->mRefKind != argRefType->mRefKind)
|
//if (wantRefType->mRefKind != argRefType->mRefKind)
|
||||||
//return true;
|
//return true;
|
||||||
InferGenericArgument(methodInstance, argRefType->mElementType, wantRefType->mElementType, BfIRValue());
|
InferGenericArgument(methodInstance, argRefType->mElementType, wantRefType->mElementType, BfIRValue(), checkedTypeSet);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -396,7 +422,7 @@ bool BfMethodMatcher::InferGenericArgument(BfMethodInstance* methodInstance, BfT
|
||||||
return true;
|
return true;
|
||||||
auto wantPointerType = (BfPointerType*) wantType;
|
auto wantPointerType = (BfPointerType*) wantType;
|
||||||
auto argPointerType = (BfPointerType*) argType;
|
auto argPointerType = (BfPointerType*) argType;
|
||||||
InferGenericArgument(methodInstance, argPointerType->mElementType, wantPointerType->mElementType, BfIRValue());
|
InferGenericArgument(methodInstance, argPointerType->mElementType, wantPointerType->mElementType, BfIRValue(), checkedTypeSet);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -406,14 +432,14 @@ bool BfMethodMatcher::InferGenericArgument(BfMethodInstance* methodInstance, BfT
|
||||||
if (argType->IsUnknownSizedArray())
|
if (argType->IsUnknownSizedArray())
|
||||||
{
|
{
|
||||||
auto argArrayType = (BfUnknownSizedArrayType*)argType;
|
auto argArrayType = (BfUnknownSizedArrayType*)argType;
|
||||||
InferGenericArgument(methodInstance, argArrayType->mElementCountSource, wantArrayType->mElementCountSource, BfIRValue());
|
InferGenericArgument(methodInstance, argArrayType->mElementCountSource, wantArrayType->mElementCountSource, BfIRValue(), checkedTypeSet);
|
||||||
}
|
}
|
||||||
else if (argType->IsSizedArray())
|
else if (argType->IsSizedArray())
|
||||||
{
|
{
|
||||||
auto argArrayType = (BfSizedArrayType*)argType;
|
auto argArrayType = (BfSizedArrayType*)argType;
|
||||||
BfTypedValue sizeValue(mModule->GetConstValue(argArrayType->mElementCount), mModule->GetPrimitiveType(BfTypeCode_IntPtr));
|
BfTypedValue sizeValue(mModule->GetConstValue(argArrayType->mElementCount), mModule->GetPrimitiveType(BfTypeCode_IntPtr));
|
||||||
auto sizedType = mModule->CreateConstExprValueType(sizeValue);
|
auto sizedType = mModule->CreateConstExprValueType(sizeValue);
|
||||||
InferGenericArgument(methodInstance, sizedType, wantArrayType->mElementCountSource, BfIRValue());
|
InferGenericArgument(methodInstance, sizedType, wantArrayType->mElementCountSource, BfIRValue(), checkedTypeSet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -423,7 +449,27 @@ bool BfMethodMatcher::InferGenericArgument(BfMethodInstance* methodInstance, BfT
|
||||||
{
|
{
|
||||||
auto wantArrayType = (BfSizedArrayType*)wantType;
|
auto wantArrayType = (BfSizedArrayType*)wantType;
|
||||||
auto argArrayType = (BfSizedArrayType*)argType;
|
auto argArrayType = (BfSizedArrayType*)argType;
|
||||||
InferGenericArgument(methodInstance, argArrayType->mElementType, wantArrayType->mElementType, BfIRValue());
|
InferGenericArgument(methodInstance, argArrayType->mElementType, wantArrayType->mElementType, BfIRValue(), checkedTypeSet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((wantType->IsDelegate()) || (wantType->IsFunction()))
|
||||||
|
{
|
||||||
|
if (((argType->IsDelegate()) || (argType->IsFunction())) &&
|
||||||
|
(wantType->IsDelegate() == argType->IsDelegate()))
|
||||||
|
{
|
||||||
|
if (!_AddToCheckedSet(argType, checkedTypeSet, alreadyChecked))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
auto argInvokeMethod = mModule->GetRawMethodByName(argType->ToTypeInstance(), "Invoke");
|
||||||
|
auto wantInvokeMethod = mModule->GetRawMethodByName(wantType->ToTypeInstance(), "Invoke");
|
||||||
|
|
||||||
|
if (argInvokeMethod->GetParamCount() == wantInvokeMethod->GetParamCount())
|
||||||
|
{
|
||||||
|
InferGenericArgument(methodInstance, argInvokeMethod->mReturnType, wantInvokeMethod->mReturnType, BfIRValue(), checkedTypeSet);
|
||||||
|
for (int argIdx = 0; argIdx < (int)argInvokeMethod->GetParamCount(); argIdx++)
|
||||||
|
InferGenericArgument(methodInstance, argInvokeMethod->GetParamType(argIdx), wantInvokeMethod->GetParamType(argIdx), BfIRValue(), checkedTypeSet);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -832,7 +878,6 @@ BfTypedValue BfMethodMatcher::ResolveArgTypedValue(BfResolvedArg& resolvedArg, B
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
argTypedValue = BfTypedValue(BfTypedValueKind_UntypedValue);
|
argTypedValue = BfTypedValue(BfTypedValueKind_UntypedValue);
|
||||||
//argTypedValue = BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), checkType);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ((resolvedArg.mArgFlags & BfArgFlag_LambdaBindAttempt) != 0)
|
else if ((resolvedArg.mArgFlags & BfArgFlag_LambdaBindAttempt) != 0)
|
||||||
|
@ -911,7 +956,7 @@ BfTypedValue BfMethodMatcher::ResolveArgTypedValue(BfResolvedArg& resolvedArg, B
|
||||||
expectType = refType->mElementType;
|
expectType = refType->mElementType;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (genericArgumentsSubstitute != NULL)
|
if ((genericArgumentsSubstitute != NULL) && (expectType->IsUnspecializedType()))
|
||||||
expectType = mModule->ResolveGenericType(expectType, *genericArgumentsSubstitute, true);
|
expectType = mModule->ResolveGenericType(expectType, *genericArgumentsSubstitute, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1238,7 +1283,7 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* typeInstance, BfMethodDef* che
|
||||||
checkType = genericParamInstance->mTypeConstraint;
|
checkType = genericParamInstance->mTypeConstraint;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((checkType != NULL) && (genericArgumentsSubstitute != NULL) && (checkType->IsUnspecializedTypeVariation()))
|
if ((checkType != NULL) && (genericArgumentsSubstitute != NULL) && (checkType->IsUnspecializedType()))
|
||||||
{
|
{
|
||||||
checkType = mModule->ResolveGenericType(origCheckType, *genericArgumentsSubstitute);
|
checkType = mModule->ResolveGenericType(origCheckType, *genericArgumentsSubstitute);
|
||||||
}
|
}
|
||||||
|
@ -1249,7 +1294,10 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* typeInstance, BfMethodDef* che
|
||||||
if (!argTypedValue.IsUntypedValue())
|
if (!argTypedValue.IsUntypedValue())
|
||||||
{
|
{
|
||||||
auto type = argTypedValue.mType;
|
auto type = argTypedValue.mType;
|
||||||
if ((!argTypedValue) || (!InferGenericArgument(methodInstance, type, wantType, argTypedValue.mValue)))
|
if (!argTypedValue)
|
||||||
|
goto NoMatch;
|
||||||
|
HashSet<BfType*> checkedTypeSet;
|
||||||
|
if (!InferGenericArgument(methodInstance, type, wantType, argTypedValue.mValue, checkedTypeSet))
|
||||||
goto NoMatch;
|
goto NoMatch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -155,7 +155,7 @@ public:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BfTypedValue ResolveArgTypedValue(BfResolvedArg& resolvedArg, BfType* checkType, BfTypeVector* genericArgumentsSubstitute);
|
BfTypedValue ResolveArgTypedValue(BfResolvedArg& resolvedArg, BfType* checkType, BfTypeVector* genericArgumentsSubstitute);
|
||||||
bool InferGenericArgument(BfMethodInstance* methodInstance, BfType* argType, BfType* wantType, BfIRValue argValue);
|
bool InferGenericArgument(BfMethodInstance* methodInstance, BfType* argType, BfType* wantType, BfIRValue argValue, HashSet<BfType*>& checkedTypeSet);
|
||||||
bool InferFromGenericConstraints(BfGenericParamInstance* genericParamInst, BfTypeVector* methodGenericArgs);
|
bool InferFromGenericConstraints(BfGenericParamInstance* genericParamInst, BfTypeVector* methodGenericArgs);
|
||||||
void CompareMethods(BfMethodInstance* prevMethodInstance, BfTypeVector* prevGenericArgumentsSubstitute,
|
void CompareMethods(BfMethodInstance* prevMethodInstance, BfTypeVector* prevGenericArgumentsSubstitute,
|
||||||
BfMethodInstance* newMethodInstance, BfTypeVector* genericArgumentsSubstitute,
|
BfMethodInstance* newMethodInstance, BfTypeVector* genericArgumentsSubstitute,
|
||||||
|
|
|
@ -19346,12 +19346,19 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool
|
||||||
|
|
||||||
if (defaultValue)
|
if (defaultValue)
|
||||||
{
|
{
|
||||||
BF_ASSERT(defaultValue.mValue.IsConst());
|
if (defaultValue.mType->IsVar())
|
||||||
while ((int)mCurMethodInstance->mDefaultValues.size() < paramDefIdx)
|
{
|
||||||
mCurMethodInstance->mDefaultValues.Add(BfIRValue());
|
AssertErrorState();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
BF_ASSERT(defaultValue.mValue.IsConst());
|
||||||
|
while ((int)mCurMethodInstance->mDefaultValues.size() < paramDefIdx)
|
||||||
|
mCurMethodInstance->mDefaultValues.Add(BfIRValue());
|
||||||
|
|
||||||
CurrentAddToConstHolder(defaultValue.mValue);
|
CurrentAddToConstHolder(defaultValue.mValue);
|
||||||
mCurMethodInstance->mDefaultValues.Add(defaultValue.mValue);
|
mCurMethodInstance->mDefaultValues.Add(defaultValue.mValue);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5446,6 +5446,9 @@ BfType* BfModule::ResolveGenericType(BfType* unspecializedType, const BfTypeVect
|
||||||
return unspecializedType;
|
return unspecializedType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!unspecializedType->IsUnspecializedType())
|
||||||
|
return unspecializedType;
|
||||||
|
|
||||||
if (unspecializedType->IsUnknownSizedArray())
|
if (unspecializedType->IsUnknownSizedArray())
|
||||||
{
|
{
|
||||||
auto* arrayType = (BfUnknownSizedArrayType*)unspecializedType;
|
auto* arrayType = (BfUnknownSizedArrayType*)unspecializedType;
|
||||||
|
@ -5535,6 +5538,121 @@ BfType* BfModule::ResolveGenericType(BfType* unspecializedType, const BfTypeVect
|
||||||
return CreateTupleType(genericArgs, names);
|
return CreateTupleType(genericArgs, names);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (unspecializedType->IsDelegate())
|
||||||
|
{
|
||||||
|
BfDelegateType* unspecializedDelegateType = (BfDelegateType*)unspecializedType;
|
||||||
|
BfDelegateType* delegateType = mContext->mDelegateTypePool.Get();
|
||||||
|
|
||||||
|
bool failed = false;
|
||||||
|
|
||||||
|
auto returnType = ResolveGenericType(unspecializedDelegateType->mReturnType, methodGenericArguments, allowFail);
|
||||||
|
if (returnType == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
auto baseDelegateType = ResolveTypeDef(mCompiler->mDelegateTypeDef)->ToTypeInstance();
|
||||||
|
|
||||||
|
delegateType->mIsUnspecializedType = false;
|
||||||
|
delegateType->mIsUnspecializedTypeVariation = false;
|
||||||
|
if (delegateType->mTypeDef != NULL)
|
||||||
|
delete delegateType->mTypeDef;
|
||||||
|
delegateType->mParams.Clear();
|
||||||
|
|
||||||
|
BfTypeDef* typeDef = new BfTypeDef();
|
||||||
|
|
||||||
|
typeDef->mProject = baseDelegateType->mTypeDef->mProject;
|
||||||
|
typeDef->mSystem = mCompiler->mSystem;
|
||||||
|
typeDef->mName = mSystem->mEmptyAtom;
|
||||||
|
typeDef->mTypeCode = unspecializedDelegateType->mTypeDef->mTypeCode;
|
||||||
|
typeDef->mIsDelegate = unspecializedDelegateType->mTypeDef->mIsDelegate;
|
||||||
|
typeDef->mIsFunction = unspecializedDelegateType->mTypeDef->mIsFunction;
|
||||||
|
|
||||||
|
BfMethodDef* methodDef = new BfMethodDef();
|
||||||
|
methodDef->mDeclaringType = typeDef;
|
||||||
|
methodDef->mName = "Invoke";
|
||||||
|
methodDef->mProtection = BfProtection_Public;
|
||||||
|
methodDef->mIdx = 0;
|
||||||
|
methodDef->mIsStatic = !typeDef->mIsDelegate;
|
||||||
|
|
||||||
|
auto directTypeRef = BfAstNode::ZeroedAlloc<BfDirectTypeReference>();
|
||||||
|
delegateType->mDirectAllocNodes.push_back(directTypeRef);
|
||||||
|
if (typeDef->mIsDelegate)
|
||||||
|
directTypeRef->Init(delegateType);
|
||||||
|
else
|
||||||
|
directTypeRef->Init(ResolveTypeDef(mCompiler->mFunctionTypeDef));
|
||||||
|
typeDef->mBaseTypes.push_back(directTypeRef);
|
||||||
|
|
||||||
|
directTypeRef = BfAstNode::ZeroedAlloc<BfDirectTypeReference>();
|
||||||
|
delegateType->mDirectAllocNodes.push_back(directTypeRef);
|
||||||
|
directTypeRef->Init(returnType);
|
||||||
|
methodDef->mReturnTypeRef = directTypeRef;
|
||||||
|
delegateType->mReturnType = returnType;
|
||||||
|
|
||||||
|
AddDependency(directTypeRef->mType, baseDelegateType, BfDependencyMap::DependencyFlag_ParamOrReturnValue);
|
||||||
|
|
||||||
|
BfMethodDef* unspecializedInvokeMethodDef = unspecializedDelegateType->mTypeDef->GetMethodByName("Invoke");
|
||||||
|
|
||||||
|
int paramIdx = 0;
|
||||||
|
for (auto param : unspecializedDelegateType->mParams)
|
||||||
|
{
|
||||||
|
auto paramType = ResolveGenericType(param, methodGenericArguments, allowFail);
|
||||||
|
if (paramType == NULL)
|
||||||
|
{
|
||||||
|
failed = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
BfParameterDef* unspecializedParamDef = unspecializedInvokeMethodDef->mParams[paramIdx];
|
||||||
|
|
||||||
|
if (paramType->IsUnspecializedType())
|
||||||
|
delegateType->mIsUnspecializedType = true;
|
||||||
|
if (paramType->IsUnspecializedTypeVariation())
|
||||||
|
delegateType->mIsUnspecializedTypeVariation = true;
|
||||||
|
if (!paramType->IsReified())
|
||||||
|
delegateType->mIsReified = false;
|
||||||
|
if (paramType->IsGenericParam())
|
||||||
|
{
|
||||||
|
delegateType->mIsUnspecializedTypeVariation = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto directTypeRef = BfAstNode::ZeroedAlloc<BfDirectTypeReference>();
|
||||||
|
delegateType->mDirectAllocNodes.push_back(directTypeRef);
|
||||||
|
directTypeRef->Init(paramType);
|
||||||
|
|
||||||
|
BfParameterDef* paramDef = new BfParameterDef();
|
||||||
|
|
||||||
|
paramDef->mTypeRef = directTypeRef;
|
||||||
|
paramDef->mName = unspecializedParamDef->mName;
|
||||||
|
methodDef->mParams.push_back(paramDef);
|
||||||
|
paramIdx++;
|
||||||
|
|
||||||
|
delegateType->mParams.Add(paramType);
|
||||||
|
AddDependency(paramType, baseDelegateType, BfDependencyMap::DependencyFlag_ParamOrReturnValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
typeDef->mMethods.push_back(methodDef);
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
BfDefBuilder::AddMethod(typeDef, BfMethodType_Ctor, BfProtection_Public, false, "");
|
||||||
|
if (typeDef->mIsDelegate)
|
||||||
|
BfDefBuilder::AddDynamicCastMethods(typeDef);
|
||||||
|
|
||||||
|
delegateType->mContext = mContext;
|
||||||
|
delegateType->mTypeDef = typeDef;
|
||||||
|
|
||||||
|
BfType* resolvedType = NULL;
|
||||||
|
if (!failed)
|
||||||
|
resolvedType = ResolveType(delegateType, BfPopulateType_Identity);
|
||||||
|
if (resolvedType != delegateType)
|
||||||
|
{
|
||||||
|
mContext->mDelegateTypePool.GiveBack(delegateType);
|
||||||
|
//mContext->mTypeDefTypeRefPool.GiveBack(typeRef);
|
||||||
|
}
|
||||||
|
BF_ASSERT((resolvedType == NULL) || resolvedType->IsTypeInstance() || resolvedType->IsPrimitiveType());
|
||||||
|
return resolvedType;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
return unspecializedType;
|
return unspecializedType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5623,7 +5741,9 @@ BfGenericParamInstance* BfModule::GetGenericTypeParamInstance(int genericParamId
|
||||||
BfGenericParamInstance* BfModule::GetGenericParamInstance(BfGenericParamType* type)
|
BfGenericParamInstance* BfModule::GetGenericParamInstance(BfGenericParamType* type)
|
||||||
{
|
{
|
||||||
if (type->mGenericParamKind == BfGenericParamKind_Method)
|
if (type->mGenericParamKind == BfGenericParamKind_Method)
|
||||||
|
{
|
||||||
return mCurMethodInstance->mMethodInfoEx->mGenericParams[type->mGenericParamIdx];
|
return mCurMethodInstance->mMethodInfoEx->mGenericParams[type->mGenericParamIdx];
|
||||||
|
}
|
||||||
|
|
||||||
return GetGenericTypeParamInstance(type->mGenericParamIdx);
|
return GetGenericTypeParamInstance(type->mGenericParamIdx);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2754,6 +2754,34 @@ bool BfResolvedTypeSet::Equals(BfType* lhs, BfType* rhs, LookupContext* ctx)
|
||||||
return lhsClosure->mClosureHash == rhsClosure->mClosureHash;
|
return lhsClosure->mClosureHash == rhsClosure->mClosureHash;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (lhs->IsDelegateFromTypeRef() || lhs->IsFunctionFromTypeRef())
|
||||||
|
{
|
||||||
|
if (!rhs->IsDelegateFromTypeRef() && !rhs->IsFunctionFromTypeRef())
|
||||||
|
return false;
|
||||||
|
if (lhs->IsDelegate() != rhs->IsDelegate())
|
||||||
|
return false;
|
||||||
|
BfDelegateType* lhsDelegateType = (BfDelegateType*)lhs;
|
||||||
|
BfDelegateType* rhsDelegateType = (BfDelegateType*)rhs;
|
||||||
|
if (lhsDelegateType->mTypeDef->mIsDelegate != rhsDelegateType->mTypeDef->mIsDelegate)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
auto lhsMethodDef = lhsDelegateType->mTypeDef->mMethods[0];
|
||||||
|
auto rhsMethodDef = rhsDelegateType->mTypeDef->mMethods[0];
|
||||||
|
|
||||||
|
if (lhsDelegateType->mReturnType != rhsDelegateType->mReturnType)
|
||||||
|
return false;
|
||||||
|
if (lhsDelegateType->mParams.size() != rhsDelegateType->mParams.size())
|
||||||
|
return false;
|
||||||
|
for (int paramIdx = 0; paramIdx < lhsDelegateType->mParams.size(); paramIdx++)
|
||||||
|
{
|
||||||
|
if (lhsDelegateType->mParams[paramIdx] != rhsDelegateType->mParams[paramIdx])
|
||||||
|
return false;
|
||||||
|
if (lhsMethodDef->mParams[paramIdx]->mName != rhsMethodDef->mParams[paramIdx]->mName)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (lhs->IsGenericTypeInstance())
|
if (lhs->IsGenericTypeInstance())
|
||||||
{
|
{
|
||||||
if (!rhs->IsGenericTypeInstance())
|
if (!rhs->IsGenericTypeInstance())
|
||||||
|
@ -2875,33 +2903,6 @@ bool BfResolvedTypeSet::Equals(BfType* lhs, BfType* rhs, LookupContext* ctx)
|
||||||
(lhsMethodRefType->mOwner == rhsMethodRefType->mOwner) &&
|
(lhsMethodRefType->mOwner == rhsMethodRefType->mOwner) &&
|
||||||
(lhsMethodRefType->mOwnerRevision == rhsMethodRefType->mOwnerRevision);
|
(lhsMethodRefType->mOwnerRevision == rhsMethodRefType->mOwnerRevision);
|
||||||
}
|
}
|
||||||
else if (lhs->IsDelegateFromTypeRef() || lhs->IsFunctionFromTypeRef())
|
|
||||||
{
|
|
||||||
if (!rhs->IsDelegateFromTypeRef() && !rhs->IsFunctionFromTypeRef())
|
|
||||||
return false;
|
|
||||||
if (lhs->IsDelegate() != rhs->IsDelegate())
|
|
||||||
return false;
|
|
||||||
BfDelegateType* lhsDelegateType = (BfDelegateType*)lhs;
|
|
||||||
BfDelegateType* rhsDelegateType = (BfDelegateType*)rhs;
|
|
||||||
if (lhsDelegateType->mTypeDef->mIsDelegate != rhsDelegateType->mTypeDef->mIsDelegate)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
auto lhsMethodDef = lhsDelegateType->mTypeDef->mMethods[0];
|
|
||||||
auto rhsMethodDef = rhsDelegateType->mTypeDef->mMethods[0];
|
|
||||||
|
|
||||||
if (lhsDelegateType->mReturnType != rhsDelegateType->mReturnType)
|
|
||||||
return false;
|
|
||||||
if (lhsDelegateType->mParams.size() != rhsDelegateType->mParams.size())
|
|
||||||
return false;
|
|
||||||
for (int paramIdx = 0; paramIdx < lhsDelegateType->mParams.size(); paramIdx++)
|
|
||||||
{
|
|
||||||
if (lhsDelegateType->mParams[paramIdx] != rhsDelegateType->mParams[paramIdx])
|
|
||||||
return false;
|
|
||||||
if (lhsMethodDef->mParams[paramIdx]->mName != rhsMethodDef->mParams[paramIdx]->mName)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if ((lhs->IsConstExprValue()) || (rhs->IsConstExprValue()))
|
else if ((lhs->IsConstExprValue()) || (rhs->IsConstExprValue()))
|
||||||
{
|
{
|
||||||
if (!lhs->IsConstExprValue() || !rhs->IsConstExprValue())
|
if (!lhs->IsConstExprValue() || !rhs->IsConstExprValue())
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue