1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-14 14:24:10 +02:00

Fixed incorrect caching of decltype/comptype

This commit is contained in:
Brian Fiete 2021-02-01 06:17:26 -08:00
parent aa21020255
commit f1b7f8151a
2 changed files with 40 additions and 13 deletions

View file

@ -3420,7 +3420,8 @@ int BfResolvedTypeSet::Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHash
} }
else if (auto exprModTypeRef = BfNodeDynCastExact<BfExprModTypeRef>(typeRef)) else if (auto exprModTypeRef = BfNodeDynCastExact<BfExprModTypeRef>(typeRef))
{ {
if (ctx->mResolvedType == NULL) auto cachedResolvedType = ctx->GetCachedResolvedType(typeRef);
if (cachedResolvedType == NULL)
{ {
if (exprModTypeRef->mTarget != NULL) if (exprModTypeRef->mTarget != NULL)
{ {
@ -3454,37 +3455,40 @@ int BfResolvedTypeSet::Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHash
} }
if ((result) && (exprModTypeRef->mToken->mToken == BfToken_Comptype)) if ((result) && (exprModTypeRef->mToken->mToken == BfToken_Comptype))
{ {
auto constant = ctx->mModule->mBfIRBuilder->GetConstant(result.mValue); auto constant = ctx->mModule->mBfIRBuilder->GetConstant(result.mValue);
if (constant != NULL) if (constant != NULL)
{ {
if ((constant->mConstType == BfConstType_TypeOf) || (constant->mConstType == BfConstType_TypeOf_WithData)) if ((constant->mConstType == BfConstType_TypeOf) || (constant->mConstType == BfConstType_TypeOf_WithData))
{ {
auto typeOf = (BfTypeOf_Const*)constant; auto typeOf = (BfTypeOf_Const*)constant;
ctx->mResolvedType = typeOf->mType; cachedResolvedType = typeOf->mType;
} }
else if (constant->mConstType == BfConstType_Undef) else if (constant->mConstType == BfConstType_Undef)
{ {
ctx->mHadVar = true; ctx->mHadVar = true;
ctx->mResolvedType = ctx->mModule->GetPrimitiveType(BfTypeCode_Var); cachedResolvedType = ctx->mModule->GetPrimitiveType(BfTypeCode_Var);
} }
} }
if (ctx->mResolvedType == NULL) if (cachedResolvedType == NULL)
ctx->mModule->Fail("Constant System.Type value required", exprModTypeRef->mTarget); ctx->mModule->Fail("Constant System.Type value required", exprModTypeRef->mTarget);
} }
else else
ctx->mResolvedType = result.mType; cachedResolvedType = result.mType;
if (cachedResolvedType != NULL)
ctx->SetCachedResolvedType(typeRef, cachedResolvedType);
} }
} }
if (ctx->mResolvedType == NULL) if (cachedResolvedType == NULL)
{ {
ctx->mFailed = true; ctx->mFailed = true;
return 0; return 0;
} }
return Hash(ctx->mResolvedType, ctx, flags); return Hash(cachedResolvedType, ctx, flags);
} }
else if (auto constExprTypeRef = BfNodeDynCastExact<BfConstExprTypeRef>(typeRef)) else if (auto constExprTypeRef = BfNodeDynCastExact<BfConstExprTypeRef>(typeRef))
{ {
@ -3850,6 +3854,24 @@ bool BfResolvedTypeSet::GenericTypeEquals(BfTypeInstance* lhsGenericType, BfType
return genericParamOffset == (int)lhsTypeGenericArguments->size(); return genericParamOffset == (int)lhsTypeGenericArguments->size();
} }
BfType* BfResolvedTypeSet::LookupContext::GetCachedResolvedType(BfTypeReference* typeReference)
{
if (typeReference == mRootTypeRef)
return mRootResolvedType;
BfType** typePtr = NULL;
if (mResolvedTypeMap.TryGetValue(typeReference, &typePtr))
return *typePtr;
return NULL;
}
void BfResolvedTypeSet::LookupContext::SetCachedResolvedType(BfTypeReference* typeReference, BfType* type)
{
if (typeReference == mRootTypeRef)
mRootResolvedType = type;
else
mResolvedTypeMap[typeReference] = type;
}
BfType* BfResolvedTypeSet::LookupContext::ResolveTypeRef(BfTypeReference* typeReference) BfType* BfResolvedTypeSet::LookupContext::ResolveTypeRef(BfTypeReference* typeReference)
{ {
return mModule->ResolveTypeRef(typeReference, BfPopulateType_Identity, BfResolveTypeRefFlag_AllowGenericParamConstValue); return mModule->ResolveTypeRef(typeReference, BfPopulateType_Identity, BfResolveTypeRefFlag_AllowGenericParamConstValue);
@ -3922,8 +3944,9 @@ bool BfResolvedTypeSet::Equals(BfType* lhs, BfTypeReference* rhs, LookupContext*
if (auto declTypeRef = BfNodeDynCastExact<BfExprModTypeRef>(rhs)) if (auto declTypeRef = BfNodeDynCastExact<BfExprModTypeRef>(rhs))
{ {
BF_ASSERT(ctx->mResolvedType != NULL); auto cachedResolveType = ctx->GetCachedResolvedType(rhs);
return lhs == ctx->mResolvedType; BF_ASSERT(cachedResolveType != NULL);
return lhs == cachedResolveType;
} }
// Strip off 'const' - it's just an error when applied to a typeRef in Beef // Strip off 'const' - it's just an error when applied to a typeRef in Beef

View file

@ -2488,7 +2488,8 @@ public:
BfTypeReference* mRootTypeRef; BfTypeReference* mRootTypeRef;
BfTypeDef* mRootTypeDef; BfTypeDef* mRootTypeDef;
BfTypeInstance* mRootOuterTypeInstance; BfTypeInstance* mRootOuterTypeInstance;
BfType* mResolvedType; BfType* mRootResolvedType;
Dictionary<BfTypeReference*, BfType*> mResolvedTypeMap;
BfResolveTypeRefFlags mResolveFlags; BfResolveTypeRefFlags mResolveFlags;
bool mHadVar; bool mHadVar;
bool mFailed; bool mFailed;
@ -2500,14 +2501,17 @@ public:
mRootTypeDef = NULL; mRootTypeDef = NULL;
mRootOuterTypeInstance = NULL; mRootOuterTypeInstance = NULL;
mModule = NULL; mModule = NULL;
mResolvedType = NULL; mRootResolvedType = NULL;
mFailed = false; mFailed = false;
mHadVar = false; mHadVar = false;
mResolveFlags = BfResolveTypeRefFlag_None; mResolveFlags = BfResolveTypeRefFlag_None;
} }
BfType* GetCachedResolvedType(BfTypeReference* typeReference);
void SetCachedResolvedType(BfTypeReference* typeReference, BfType* type);
BfType* ResolveTypeRef(BfTypeReference* typeReference); BfType* ResolveTypeRef(BfTypeReference* typeReference);
BfTypeDef* ResolveToTypeDef(BfTypeReference* typeReference, BfType** outType = NULL); BfTypeDef* ResolveToTypeDef(BfTypeReference* typeReference, BfType** outType = NULL);
}; };
public: public: