mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-10 04:22:20 +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)
|
||||
CheckCircularDataError();
|
||||
|
||||
bool underlyingTypeDeferred = false;
|
||||
BfType* underlyingType = NULL;
|
||||
if (typeInstance->mBaseType != NULL)
|
||||
if (typeInstance->mDefineState < BfTypeDefineState_Declaring)
|
||||
{
|
||||
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();
|
||||
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;
|
||||
typeInstance->mDefineState = BfTypeDefineState_Declaring;
|
||||
|
||||
if (typeInstance->IsGenericTypeInstance())
|
||||
{
|
||||
|
@ -2915,6 +2770,156 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
|||
else
|
||||
_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)
|
||||
{
|
||||
return;
|
||||
|
|
|
@ -430,6 +430,7 @@ class BfTypeDIReplaceCallback;
|
|||
enum BfTypeDefineState : uint8
|
||||
{
|
||||
BfTypeDefineState_Undefined,
|
||||
BfTypeDefineState_Declaring,
|
||||
BfTypeDefineState_Declared,
|
||||
BfTypeDefineState_ResolvingBaseType,
|
||||
BfTypeDefineState_HasInterfaces,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue