mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-14 14:24:10 +02:00
Fixed base type with 'static using' typeref lookup
This commit is contained in:
parent
b316b1412c
commit
5618718e8d
2 changed files with 98 additions and 92 deletions
|
@ -2679,154 +2679,9 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
||||||
if (!typeInstance->mTypeFailed)
|
if (!typeInstance->mTypeFailed)
|
||||||
CheckCircularDataError();
|
CheckCircularDataError();
|
||||||
|
|
||||||
bool underlyingTypeDeferred = false;
|
if (typeInstance->mDefineState < BfTypeDefineState_Declaring)
|
||||||
BfType* underlyingType = NULL;
|
|
||||||
if (typeInstance->mBaseType != NULL)
|
|
||||||
{
|
{
|
||||||
if (typeInstance->IsTypedPrimitive())
|
typeInstance->mDefineState = BfTypeDefineState_Declaring;
|
||||||
underlyingType = typeInstance->GetUnderlyingType();
|
|
||||||
if ((typeInstance->mRebuildFlags & BfTypeRebuildFlag_UnderlyingTypeDeferred) != 0)
|
|
||||||
underlyingTypeDeferred = true;
|
|
||||||
}
|
|
||||||
else if (typeInstance->IsEnum())
|
|
||||||
{
|
|
||||||
bool hasPayloads = false;
|
|
||||||
for (auto fieldDef : typeDef->mFields)
|
|
||||||
{
|
|
||||||
if ((fieldDef->IsEnumCaseEntry()) && (fieldDef->mTypeRef != NULL))
|
|
||||||
{
|
|
||||||
hasPayloads = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!hasPayloads)
|
|
||||||
{
|
|
||||||
bool hadType = false;
|
|
||||||
|
|
||||||
for (auto baseTypeRef : typeDef->mBaseTypes)
|
|
||||||
{
|
|
||||||
SetAndRestoreValue<BfTypeReference*> prevTypeRef(mContext->mCurTypeState->mCurBaseTypeRef, baseTypeRef);
|
|
||||||
SetAndRestoreValue<BfTypeDefineState> prevDefineState(typeInstance->mDefineState, BfTypeDefineState_ResolvingBaseType);
|
|
||||||
SetAndRestoreValue<bool> prevIgnoreError(mIgnoreErrors, true);
|
|
||||||
SetAndRestoreValue<bool> prevSkipTypeProtectionChecks(typeInstance->mSkipTypeProtectionChecks, true);
|
|
||||||
|
|
||||||
auto baseType = ResolveTypeRef(baseTypeRef, BfPopulateType_Declaration);
|
|
||||||
if (baseType != NULL)
|
|
||||||
{
|
|
||||||
if (baseType->IsIntegral())
|
|
||||||
{
|
|
||||||
if (!hadType)
|
|
||||||
{
|
|
||||||
hadType = true;
|
|
||||||
underlyingType = baseType;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Fail("Underlying enum type already specified", baseTypeRef);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Fail("Invalid underlying enum type", baseTypeRef);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
AssertErrorState();
|
|
||||||
typeInstance->mTypeFailed = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (underlyingType == NULL)
|
|
||||||
{
|
|
||||||
underlyingType = GetPrimitiveType(BfTypeCode_Int64);
|
|
||||||
underlyingTypeDeferred = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// else if (typeInstance->IsFunction())
|
|
||||||
// {
|
|
||||||
// underlyingType = GetPrimitiveType(BfTypeCode_NullPtr);
|
|
||||||
// }
|
|
||||||
else if (((typeInstance->IsStruct()) || (typeInstance->IsTypedPrimitive())) &&
|
|
||||||
(!typeInstance->mTypeFailed))
|
|
||||||
{
|
|
||||||
for (auto baseTypeRef : typeDef->mBaseTypes)
|
|
||||||
{
|
|
||||||
auto declTypeDef = typeDef;
|
|
||||||
if (typeDef->mIsCombinedPartial)
|
|
||||||
declTypeDef = typeDef->mPartials.front();
|
|
||||||
SetAndRestoreValue<BfTypeDef*> prevTypeDef(mContext->mCurTypeState->mCurTypeDef, declTypeDef);
|
|
||||||
SetAndRestoreValue<BfTypeDefineState> prevDefineState(typeInstance->mDefineState, BfTypeDefineState_ResolvingBaseType);
|
|
||||||
SetAndRestoreValue<BfTypeReference*> prevTypeRef(mContext->mCurTypeState->mCurBaseTypeRef, baseTypeRef);
|
|
||||||
// We ignore errors here to avoid double-errors for type lookups, but this is where data cycles are detected
|
|
||||||
// but that type of error supersedes the mIgnoreErrors setting
|
|
||||||
SetAndRestoreValue<bool> prevIgnoreError(mIgnoreErrors, true);
|
|
||||||
// Temporarily allow us to derive from private classes, to avoid infinite loop from TypeIsSubTypeOf
|
|
||||||
SetAndRestoreValue<bool> prevSkipTypeProtectionChecks(typeInstance->mSkipTypeProtectionChecks, true);
|
|
||||||
auto baseType = ResolveTypeRef(baseTypeRef, BfPopulateType_Declaration);
|
|
||||||
if (baseType != NULL)
|
|
||||||
{
|
|
||||||
if (baseType->IsPrimitiveType())
|
|
||||||
{
|
|
||||||
underlyingType = baseType;
|
|
||||||
}
|
|
||||||
else if (baseType->IsTypedPrimitive())
|
|
||||||
{
|
|
||||||
//PopulateType(baseType, true);
|
|
||||||
underlyingType = baseType->GetUnderlyingType();
|
|
||||||
BF_ASSERT(underlyingType != NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
AssertErrorState();
|
|
||||||
typeInstance->mTypeFailed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_CheckTypeDone())
|
|
||||||
{
|
|
||||||
prevDefineState.CancelRestore();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Incase we had re-entry, work this through ourselves again here
|
|
||||||
typeInstance->mIsTypedPrimitive = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (underlyingTypeDeferred)
|
|
||||||
typeInstance->mRebuildFlags = (BfTypeRebuildFlags)(typeInstance->mRebuildFlags | BfTypeRebuildFlag_UnderlyingTypeDeferred);
|
|
||||||
|
|
||||||
typeInstance->mIsTypedPrimitive = underlyingType != NULL;
|
|
||||||
int wantFieldCount = (int)typeDef->mFields.size() + (((underlyingType != NULL) || (typeInstance->IsPayloadEnum())) ? 1 : 0);
|
|
||||||
if ((int)typeInstance->mFieldInstances.size() < wantFieldCount)
|
|
||||||
{
|
|
||||||
// Closures don't include the enclosed fields on their first pass through PopulateType, and they have no typeDef of their own
|
|
||||||
// so we need to take care not to truncate their fieldInstance vector here (thus the 'wantFieldCount' check above)
|
|
||||||
typeInstance->mFieldInstances.Resize(wantFieldCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (underlyingType != NULL)
|
|
||||||
{
|
|
||||||
auto fieldInstance = &typeInstance->mFieldInstances.back();
|
|
||||||
fieldInstance->mDataOffset = 0;
|
|
||||||
fieldInstance->mDataSize = underlyingType->mSize;
|
|
||||||
fieldInstance->mOwner = typeInstance;
|
|
||||||
fieldInstance->mResolvedType = underlyingType;
|
|
||||||
|
|
||||||
typeInstance->mSize = underlyingType->mSize;
|
|
||||||
typeInstance->mAlign = underlyingType->mAlign;
|
|
||||||
typeInstance->mInstSize = underlyingType->mSize;
|
|
||||||
typeInstance->mInstAlign = underlyingType->mAlign;
|
|
||||||
typeInstance->mHasPackingHoles = underlyingType->HasPackingHoles();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Partial population break out point
|
|
||||||
if (typeInstance->mDefineState < BfTypeDefineState_Declared)
|
|
||||||
{
|
|
||||||
typeInstance->mDefineState = BfTypeDefineState_Declared;
|
|
||||||
|
|
||||||
if (typeInstance->IsGenericTypeInstance())
|
if (typeInstance->IsGenericTypeInstance())
|
||||||
{
|
{
|
||||||
|
@ -2915,6 +2770,156 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
||||||
else
|
else
|
||||||
_AddStaticSearch(typeDef);
|
_AddStaticSearch(typeDef);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool underlyingTypeDeferred = false;
|
||||||
|
BfType* underlyingType = NULL;
|
||||||
|
if (typeInstance->mBaseType != NULL)
|
||||||
|
{
|
||||||
|
if (typeInstance->IsTypedPrimitive())
|
||||||
|
underlyingType = typeInstance->GetUnderlyingType();
|
||||||
|
if ((typeInstance->mRebuildFlags & BfTypeRebuildFlag_UnderlyingTypeDeferred) != 0)
|
||||||
|
underlyingTypeDeferred = true;
|
||||||
|
}
|
||||||
|
else if (typeInstance->IsEnum())
|
||||||
|
{
|
||||||
|
bool hasPayloads = false;
|
||||||
|
for (auto fieldDef : typeDef->mFields)
|
||||||
|
{
|
||||||
|
if ((fieldDef->IsEnumCaseEntry()) && (fieldDef->mTypeRef != NULL))
|
||||||
|
{
|
||||||
|
hasPayloads = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasPayloads)
|
||||||
|
{
|
||||||
|
bool hadType = false;
|
||||||
|
|
||||||
|
for (auto baseTypeRef : typeDef->mBaseTypes)
|
||||||
|
{
|
||||||
|
SetAndRestoreValue<BfTypeReference*> prevTypeRef(mContext->mCurTypeState->mCurBaseTypeRef, baseTypeRef);
|
||||||
|
SetAndRestoreValue<BfTypeDefineState> prevDefineState(typeInstance->mDefineState, BfTypeDefineState_ResolvingBaseType);
|
||||||
|
SetAndRestoreValue<bool> prevIgnoreError(mIgnoreErrors, true);
|
||||||
|
SetAndRestoreValue<bool> prevSkipTypeProtectionChecks(typeInstance->mSkipTypeProtectionChecks, true);
|
||||||
|
|
||||||
|
auto baseType = ResolveTypeRef(baseTypeRef, BfPopulateType_Declaration);
|
||||||
|
if (baseType != NULL)
|
||||||
|
{
|
||||||
|
if (baseType->IsIntegral())
|
||||||
|
{
|
||||||
|
if (!hadType)
|
||||||
|
{
|
||||||
|
hadType = true;
|
||||||
|
underlyingType = baseType;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Fail("Underlying enum type already specified", baseTypeRef);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Fail("Invalid underlying enum type", baseTypeRef);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AssertErrorState();
|
||||||
|
TypeFailed(typeInstance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (underlyingType == NULL)
|
||||||
|
{
|
||||||
|
underlyingType = GetPrimitiveType(BfTypeCode_Int64);
|
||||||
|
underlyingTypeDeferred = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// else if (typeInstance->IsFunction())
|
||||||
|
// {
|
||||||
|
// underlyingType = GetPrimitiveType(BfTypeCode_NullPtr);
|
||||||
|
// }
|
||||||
|
else if (((typeInstance->IsStruct()) || (typeInstance->IsTypedPrimitive())) &&
|
||||||
|
(!typeInstance->mTypeFailed))
|
||||||
|
{
|
||||||
|
for (auto baseTypeRef : typeDef->mBaseTypes)
|
||||||
|
{
|
||||||
|
auto declTypeDef = typeDef;
|
||||||
|
if (typeDef->mIsCombinedPartial)
|
||||||
|
declTypeDef = typeDef->mPartials.front();
|
||||||
|
SetAndRestoreValue<BfTypeDef*> prevTypeDef(mContext->mCurTypeState->mCurTypeDef, declTypeDef);
|
||||||
|
SetAndRestoreValue<BfTypeDefineState> prevDefineState(typeInstance->mDefineState, BfTypeDefineState_ResolvingBaseType);
|
||||||
|
SetAndRestoreValue<BfTypeReference*> prevTypeRef(mContext->mCurTypeState->mCurBaseTypeRef, baseTypeRef);
|
||||||
|
// We ignore errors here to avoid double-errors for type lookups, but this is where data cycles are detected
|
||||||
|
// but that type of error supersedes the mIgnoreErrors setting
|
||||||
|
SetAndRestoreValue<bool> prevIgnoreError(mIgnoreErrors, true);
|
||||||
|
// Temporarily allow us to derive from private classes, to avoid infinite loop from TypeIsSubTypeOf
|
||||||
|
SetAndRestoreValue<bool> prevSkipTypeProtectionChecks(typeInstance->mSkipTypeProtectionChecks, true);
|
||||||
|
auto baseType = ResolveTypeRef(baseTypeRef, BfPopulateType_Declaration);
|
||||||
|
if (baseType != NULL)
|
||||||
|
{
|
||||||
|
if (baseType->IsPrimitiveType())
|
||||||
|
{
|
||||||
|
underlyingType = baseType;
|
||||||
|
}
|
||||||
|
else if (baseType->IsTypedPrimitive())
|
||||||
|
{
|
||||||
|
//PopulateType(baseType, true);
|
||||||
|
underlyingType = baseType->GetUnderlyingType();
|
||||||
|
BF_ASSERT(underlyingType != NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AssertErrorState();
|
||||||
|
TypeFailed(typeInstance);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_CheckTypeDone())
|
||||||
|
{
|
||||||
|
prevDefineState.CancelRestore();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Incase we had re-entry, work this through ourselves again here
|
||||||
|
typeInstance->mIsTypedPrimitive = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (underlyingTypeDeferred)
|
||||||
|
typeInstance->mRebuildFlags = (BfTypeRebuildFlags)(typeInstance->mRebuildFlags | BfTypeRebuildFlag_UnderlyingTypeDeferred);
|
||||||
|
|
||||||
|
typeInstance->mIsTypedPrimitive = underlyingType != NULL;
|
||||||
|
int wantFieldCount = (int)typeDef->mFields.size() + (((underlyingType != NULL) || (typeInstance->IsPayloadEnum())) ? 1 : 0);
|
||||||
|
if ((int)typeInstance->mFieldInstances.size() < wantFieldCount)
|
||||||
|
{
|
||||||
|
// Closures don't include the enclosed fields on their first pass through PopulateType, and they have no typeDef of their own
|
||||||
|
// so we need to take care not to truncate their fieldInstance vector here (thus the 'wantFieldCount' check above)
|
||||||
|
typeInstance->mFieldInstances.Resize(wantFieldCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (underlyingType != NULL)
|
||||||
|
{
|
||||||
|
auto fieldInstance = &typeInstance->mFieldInstances.back();
|
||||||
|
fieldInstance->mDataOffset = 0;
|
||||||
|
fieldInstance->mDataSize = underlyingType->mSize;
|
||||||
|
fieldInstance->mOwner = typeInstance;
|
||||||
|
fieldInstance->mResolvedType = underlyingType;
|
||||||
|
|
||||||
|
typeInstance->mSize = underlyingType->mSize;
|
||||||
|
typeInstance->mAlign = underlyingType->mAlign;
|
||||||
|
typeInstance->mInstSize = underlyingType->mSize;
|
||||||
|
typeInstance->mInstAlign = underlyingType->mAlign;
|
||||||
|
typeInstance->mHasPackingHoles = underlyingType->HasPackingHoles();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Partial population break out point
|
||||||
|
|
||||||
|
if (typeInstance->mDefineState < BfTypeDefineState_Declared)
|
||||||
|
typeInstance->mDefineState = BfTypeDefineState_Declared;
|
||||||
|
|
||||||
if (populateType == BfPopulateType_Declaration)
|
if (populateType == BfPopulateType_Declaration)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -430,6 +430,7 @@ class BfTypeDIReplaceCallback;
|
||||||
enum BfTypeDefineState : uint8
|
enum BfTypeDefineState : uint8
|
||||||
{
|
{
|
||||||
BfTypeDefineState_Undefined,
|
BfTypeDefineState_Undefined,
|
||||||
|
BfTypeDefineState_Declaring,
|
||||||
BfTypeDefineState_Declared,
|
BfTypeDefineState_Declared,
|
||||||
BfTypeDefineState_ResolvingBaseType,
|
BfTypeDefineState_ResolvingBaseType,
|
||||||
BfTypeDefineState_HasInterfaces,
|
BfTypeDefineState_HasInterfaces,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue