mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 19:48:20 +02:00
Improvements and safety for const exprs
This commit is contained in:
parent
da508156c1
commit
0a78b5cc35
8 changed files with 290 additions and 85 deletions
|
@ -67,7 +67,7 @@ public:
|
||||||
int mMethodDeclarations;
|
int mMethodDeclarations;
|
||||||
int mTypesPopulated;
|
int mTypesPopulated;
|
||||||
int mMethodsProcessed;
|
int mMethodsProcessed;
|
||||||
int mUnreifiedMethodsProcessed;
|
int mUnreifiedMethodsProcessed;
|
||||||
|
|
||||||
int mQueuedTypesProcessed;
|
int mQueuedTypesProcessed;
|
||||||
int mTypesQueued;
|
int mTypesQueued;
|
||||||
|
@ -82,7 +82,7 @@ public:
|
||||||
|
|
||||||
int mReifiedModuleCount;
|
int mReifiedModuleCount;
|
||||||
int mIRBytes;
|
int mIRBytes;
|
||||||
int mConstBytes;
|
int mConstBytes;
|
||||||
};
|
};
|
||||||
Stats mStats;
|
Stats mStats;
|
||||||
|
|
||||||
|
@ -122,7 +122,7 @@ public:
|
||||||
bool mDebugAlloc;
|
bool mDebugAlloc;
|
||||||
bool mOmitDebugHelpers;
|
bool mOmitDebugHelpers;
|
||||||
|
|
||||||
bool mUseDebugBackingParams;
|
bool mUseDebugBackingParams;
|
||||||
|
|
||||||
bool mWriteIR;
|
bool mWriteIR;
|
||||||
bool mGenerateObj;
|
bool mGenerateObj;
|
||||||
|
|
|
@ -423,13 +423,7 @@ void BfGNUMangler::Mangle(MangleContext& mangleContext, StringImpl& name, BfType
|
||||||
name += "v";
|
name += "v";
|
||||||
else
|
else
|
||||||
name += "U4void";
|
name += "U4void";
|
||||||
return;
|
return;
|
||||||
case BfTypeCode_Var:
|
|
||||||
if ((mangleContext.mCCompat) || (mangleContext.mInArgs))
|
|
||||||
name += "v";
|
|
||||||
else
|
|
||||||
name += "U3var";
|
|
||||||
return;
|
|
||||||
case BfTypeCode_Self:
|
case BfTypeCode_Self:
|
||||||
if ((mangleContext.mCCompat) || (mangleContext.mInArgs))
|
if ((mangleContext.mCCompat) || (mangleContext.mInArgs))
|
||||||
name += "U8concrete";
|
name += "U8concrete";
|
||||||
|
@ -494,6 +488,19 @@ void BfGNUMangler::Mangle(MangleContext& mangleContext, StringImpl& name, BfType
|
||||||
name += "f"; return;
|
name += "f"; return;
|
||||||
case BfTypeCode_Double:
|
case BfTypeCode_Double:
|
||||||
name += "d"; return;
|
name += "d"; return;
|
||||||
|
|
||||||
|
case BfTypeCode_Var:
|
||||||
|
if ((mangleContext.mCCompat) || (mangleContext.mInArgs))
|
||||||
|
name += "v";
|
||||||
|
else
|
||||||
|
name += "U3var";
|
||||||
|
return;
|
||||||
|
case BfTypeCode_Let:
|
||||||
|
name += "U3let"; return;
|
||||||
|
case BfTypeCode_IntUnknown:
|
||||||
|
name += "U4iunk"; return;
|
||||||
|
case BfTypeCode_UIntUnknown:
|
||||||
|
name += "U4uunk"; return;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1455,21 +1462,7 @@ void BfMSMangler::Mangle(MangleContext& mangleContext, StringImpl& name, BfType*
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
case BfTypeCode_None:
|
case BfTypeCode_None:
|
||||||
name += "X"; return;
|
name += "X"; return;
|
||||||
case BfTypeCode_Dot:
|
|
||||||
name += "Tdot@@"; return;
|
|
||||||
case BfTypeCode_Var:
|
|
||||||
if ((mangleContext.mCCompat) || (mangleContext.mInArgs))
|
|
||||||
name += "X";
|
|
||||||
else
|
|
||||||
name += "Tvar@@";
|
|
||||||
return;
|
|
||||||
case BfTypeCode_Self:
|
|
||||||
if ((mangleContext.mCCompat) || (mangleContext.mInArgs))
|
|
||||||
name += "X";
|
|
||||||
else
|
|
||||||
name += "Tself@@";
|
|
||||||
return;
|
|
||||||
case BfTypeCode_Int8:
|
case BfTypeCode_Int8:
|
||||||
name += "C"; return;
|
name += "C"; return;
|
||||||
case BfTypeCode_UInt8:
|
case BfTypeCode_UInt8:
|
||||||
|
@ -1512,6 +1505,28 @@ void BfMSMangler::Mangle(MangleContext& mangleContext, StringImpl& name, BfType*
|
||||||
}
|
}
|
||||||
isLongPrim = true;
|
isLongPrim = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case BfTypeCode_Dot:
|
||||||
|
name += "Tdot@@"; return;
|
||||||
|
case BfTypeCode_Var:
|
||||||
|
if ((mangleContext.mCCompat) || (mangleContext.mInArgs))
|
||||||
|
name += "X";
|
||||||
|
else
|
||||||
|
name += "Tvar@@";
|
||||||
|
return;
|
||||||
|
case BfTypeCode_Self:
|
||||||
|
if ((mangleContext.mCCompat) || (mangleContext.mInArgs))
|
||||||
|
name += "X";
|
||||||
|
else
|
||||||
|
name += "Tself@@";
|
||||||
|
return;
|
||||||
|
case BfTypeCode_Let:
|
||||||
|
name += "Tlet@@"; return;
|
||||||
|
case BfTypeCode_IntUnknown:
|
||||||
|
name += "Tiunk@@"; return;
|
||||||
|
case BfTypeCode_UIntUnknown:
|
||||||
|
name += "Tuunk@@"; return;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
name += "?"; return;
|
name += "?"; return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4766,7 +4766,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
||||||
return *irValuePtr;
|
return *irValuePtr;
|
||||||
}
|
}
|
||||||
|
|
||||||
BfTypeInstance* typeInstance = type->ToTypeInstance();
|
BfTypeInstance* typeInstance = type->ToTypeInstance();
|
||||||
|
|
||||||
BfType* typeInstanceType = ResolveTypeDef(mCompiler->mReflectTypeInstanceTypeDef);
|
BfType* typeInstanceType = ResolveTypeDef(mCompiler->mReflectTypeInstanceTypeDef);
|
||||||
mBfIRBuilder->PopulateType(typeInstanceType, BfIRPopulateType_Full_ForceDefinition);
|
mBfIRBuilder->PopulateType(typeInstanceType, BfIRPopulateType_Full_ForceDefinition);
|
||||||
|
@ -4855,6 +4855,11 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
||||||
BfMangler::Mangle(typeDataName, mCompiler->GetMangleKind(), type, mContext->mScratchModule);
|
BfMangler::Mangle(typeDataName, mCompiler->GetMangleKind(), type, mContext->mScratchModule);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (typeDataName == "sBfTypeData.?")
|
||||||
|
{
|
||||||
|
NOP;
|
||||||
|
}
|
||||||
|
|
||||||
int typeCode = BfTypeCode_None;
|
int typeCode = BfTypeCode_None;
|
||||||
|
|
||||||
if (typeInstance != NULL)
|
if (typeInstance != NULL)
|
||||||
|
@ -12042,13 +12047,20 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM
|
||||||
BF_ASSERT(instModule == mParentModule);
|
BF_ASSERT(instModule == mParentModule);
|
||||||
}
|
}
|
||||||
else if (instModule != this)
|
else if (instModule != this)
|
||||||
{
|
{
|
||||||
|
if ((mCurMethodInstance != NULL) && (mCurMethodInstance->mMethodInfoEx != NULL) && (mCurMethodInstance->mMethodInfoEx->mMinDependDepth >= 32))
|
||||||
|
flags = (BfGetMethodInstanceFlags)(flags | BfGetMethodInstanceFlag_DepthExceeded);
|
||||||
|
|
||||||
if ((!mIsReified) && (instModule->mIsReified))
|
if ((!mIsReified) && (instModule->mIsReified))
|
||||||
{
|
{
|
||||||
BF_ASSERT(!mCompiler->mIsResolveOnly);
|
BF_ASSERT(!mCompiler->mIsResolveOnly);
|
||||||
// A resolve-only module is specializing a method from a type in a reified module,
|
// A resolve-only module is specializing a method from a type in a reified module,
|
||||||
// we need to take care that this doesn't cause anything new to become reified
|
// we need to take care that this doesn't cause anything new to become reified
|
||||||
return mContext->mUnreifiedModule->GetMethodInstance(typeInst, methodDef, methodGenericArguments, (BfGetMethodInstanceFlags)(flags | BfGetMethodInstanceFlag_ExplicitResolveOnlyPass), foreignType);
|
BfModuleMethodInstance moduleMethodInstance = mContext->mUnreifiedModule->GetMethodInstance(typeInst, methodDef, methodGenericArguments, (BfGetMethodInstanceFlags)(flags | BfGetMethodInstanceFlag_ExplicitResolveOnlyPass), foreignType);
|
||||||
|
if (!moduleMethodInstance)
|
||||||
|
return moduleMethodInstance;
|
||||||
|
SetMethodDependency(moduleMethodInstance.mMethodInstance);
|
||||||
|
return moduleMethodInstance;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -12081,6 +12093,8 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM
|
||||||
// Not extern
|
// Not extern
|
||||||
// Create the instance in the proper module and then create a reference in this one
|
// Create the instance in the proper module and then create a reference in this one
|
||||||
moduleMethodInst = instModule->GetMethodInstance(typeInst, methodDef, methodGenericArguments, defFlags, foreignType);
|
moduleMethodInst = instModule->GetMethodInstance(typeInst, methodDef, methodGenericArguments, defFlags, foreignType);
|
||||||
|
if (!moduleMethodInst)
|
||||||
|
return moduleMethodInst;
|
||||||
tryModuleMethodLookup = true;
|
tryModuleMethodLookup = true;
|
||||||
|
|
||||||
if ((mIsReified) && (!moduleMethodInst.mMethodInstance->mIsReified))
|
if ((mIsReified) && (!moduleMethodInst.mMethodInstance->mIsReified))
|
||||||
|
@ -12091,7 +12105,10 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tryModuleMethodLookup)
|
if (tryModuleMethodLookup)
|
||||||
|
{
|
||||||
|
SetMethodDependency(moduleMethodInst.mMethodInstance);
|
||||||
return ReferenceExternalMethodInstance(moduleMethodInst.mMethodInstance, flags);
|
return ReferenceExternalMethodInstance(moduleMethodInst.mMethodInstance, flags);
|
||||||
|
}
|
||||||
|
|
||||||
if (((flags & BfGetMethodInstanceFlag_ForceInline) != 0) && (!methodDef->mAlwaysInline))
|
if (((flags & BfGetMethodInstanceFlag_ForceInline) != 0) && (!methodDef->mAlwaysInline))
|
||||||
{
|
{
|
||||||
|
@ -12422,6 +12439,8 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM
|
||||||
|
|
||||||
if ((methodInstance != NULL) && (!doingRedeclare))
|
if ((methodInstance != NULL) && (!doingRedeclare))
|
||||||
{
|
{
|
||||||
|
SetMethodDependency(methodInstance);
|
||||||
|
|
||||||
if (methodInstance->mMethodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_Decl_AwaitingReference)
|
if (methodInstance->mMethodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_Decl_AwaitingReference)
|
||||||
{
|
{
|
||||||
/*if ((!mCompiler->mIsResolveOnly) && (!isReified))
|
/*if ((!mCompiler->mIsResolveOnly) && (!isReified))
|
||||||
|
@ -12535,7 +12554,7 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM
|
||||||
GetMethodInstance(typeInst, methodDef, BfTypeVector(), BfGetMethodInstanceFlag_UnspecializedPass);
|
GetMethodInstance(typeInst, methodDef, BfTypeVector(), BfGetMethodInstanceFlag_UnspecializedPass);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (methodInstance == NULL)
|
if (methodInstance == NULL)
|
||||||
{
|
{
|
||||||
if (lookupMethodGenericArguments.size() == 0)
|
if (lookupMethodGenericArguments.size() == 0)
|
||||||
|
@ -12547,7 +12566,18 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM
|
||||||
BfLogSysM("Created Default MethodInst: %p TypeInst: %p Group: %p\n", methodInstance, typeInst, methodInstGroup);
|
BfLogSysM("Created Default MethodInst: %p TypeInst: %p Group: %p\n", methodInstance, typeInst, methodInstGroup);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
bool depthExceeded = ((flags & BfGetMethodInstanceFlag_DepthExceeded) != 0);
|
||||||
|
|
||||||
|
if ((mCurMethodInstance != NULL) && (mCurMethodInstance->mMethodInfoEx != NULL) && (mCurMethodInstance->mMethodInfoEx->mMinDependDepth >= 32))
|
||||||
|
depthExceeded = true;
|
||||||
|
|
||||||
|
if (depthExceeded)
|
||||||
|
{
|
||||||
|
Fail("Generic method dependency depth exceeded", methodDef->GetRefNode());
|
||||||
|
return BfModuleMethodInstance();
|
||||||
|
}
|
||||||
|
|
||||||
BfMethodInstance** methodInstancePtr = NULL;
|
BfMethodInstance** methodInstancePtr = NULL;
|
||||||
bool added = methodInstGroup->mMethodSpecializationMap->TryAdd(lookupMethodGenericArguments, NULL, &methodInstancePtr);
|
bool added = methodInstGroup->mMethodSpecializationMap->TryAdd(lookupMethodGenericArguments, NULL, &methodInstancePtr);
|
||||||
BF_ASSERT(added);
|
BF_ASSERT(added);
|
||||||
|
@ -12561,7 +12591,7 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((prevIRFunc) && (!prevIRFunc.IsFake()))
|
if ((prevIRFunc) && (!prevIRFunc.IsFake()))
|
||||||
methodInstance->mIRFunction = prevIRFunc; // Take it over
|
methodInstance->mIRFunction = prevIRFunc; // Take it over
|
||||||
}
|
}
|
||||||
|
|
||||||
/*// 24 bits for typeid, 20 for method id, 20 for specialization index
|
/*// 24 bits for typeid, 20 for method id, 20 for specialization index
|
||||||
|
@ -12679,7 +12709,9 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM
|
||||||
{
|
{
|
||||||
BF_ASSERT(!methodInstance->mIsReified);
|
BF_ASSERT(!methodInstance->mIsReified);
|
||||||
declareModule = mContext->mUnreifiedModule;
|
declareModule = mContext->mUnreifiedModule;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SetMethodDependency(methodInstance);
|
||||||
|
|
||||||
SetAndRestoreValue<BfMethodInstance*> prevMethodInstance(declareModule->mCurMethodInstance, methodInstance);
|
SetAndRestoreValue<BfMethodInstance*> prevMethodInstance(declareModule->mCurMethodInstance, methodInstance);
|
||||||
SetAndRestoreValue<BfTypeInstance*> prevTypeInstance(declareModule->mCurTypeInstance, typeInst);
|
SetAndRestoreValue<BfTypeInstance*> prevTypeInstance(declareModule->mCurTypeInstance, typeInst);
|
||||||
|
@ -20214,9 +20246,6 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool
|
||||||
{
|
{
|
||||||
BP_ZONE("BfModule::BfMethodDeclaration");
|
BP_ZONE("BfModule::BfMethodDeclaration");
|
||||||
|
|
||||||
// If we are doing this then we may end up creating methods when var types are unknown still, failing on splat/zero-sized info
|
|
||||||
BF_ASSERT((!mContext->mResolvingVarField) || (mBfIRBuilder->mIgnoreWrites));
|
|
||||||
|
|
||||||
// We could trigger a DoMethodDeclaration from a const resolver or other location, so we reset it here
|
// We could trigger a DoMethodDeclaration from a const resolver or other location, so we reset it here
|
||||||
// to effectively make mIgnoreWrites method-scoped
|
// to effectively make mIgnoreWrites method-scoped
|
||||||
SetAndRestoreValue<bool> prevIgnoreWrites(mBfIRBuilder->mIgnoreWrites, mWantsIRIgnoreWrites || mCurMethodInstance->mIsUnspecialized);
|
SetAndRestoreValue<bool> prevIgnoreWrites(mBfIRBuilder->mIgnoreWrites, mWantsIRIgnoreWrites || mCurMethodInstance->mIsUnspecialized);
|
||||||
|
@ -20228,6 +20257,10 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool
|
||||||
if (mCurMethodInstance->mMethodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_NoDecl_AwaitingReference)
|
if (mCurMethodInstance->mMethodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_NoDecl_AwaitingReference)
|
||||||
mCurMethodInstance->mMethodInstanceGroup->mOnDemandKind = BfMethodOnDemandKind_Decl_AwaitingReference;
|
mCurMethodInstance->mMethodInstanceGroup->mOnDemandKind = BfMethodOnDemandKind_Decl_AwaitingReference;
|
||||||
|
|
||||||
|
|
||||||
|
// If we are doing this then we may end up creating methods when var types are unknown still, failing on splat/zero-sized info
|
||||||
|
BF_ASSERT((!mCurTypeInstance->mResolvingVarField) || (mBfIRBuilder->mIgnoreWrites));
|
||||||
|
|
||||||
bool ignoreWrites = mBfIRBuilder->mIgnoreWrites;
|
bool ignoreWrites = mBfIRBuilder->mIgnoreWrites;
|
||||||
|
|
||||||
if ((!isTemporaryFunc) && (mCurTypeInstance->mDefineState < BfTypeDefineState_Defined))
|
if ((!isTemporaryFunc) && (mCurTypeInstance->mDefineState < BfTypeDefineState_Defined))
|
||||||
|
@ -22256,6 +22289,27 @@ bool BfModule::SlotInterfaceMethod(BfMethodInstance* methodInstance)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BfModule::SetMethodDependency(BfMethodInstance* methodInstance)
|
||||||
|
{
|
||||||
|
if (methodInstance->mMethodInfoEx == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int wantMinDepth = -1;
|
||||||
|
|
||||||
|
if (mCurTypeInstance != NULL)
|
||||||
|
wantMinDepth = mCurTypeInstance->mDependencyMap.mMinDependDepth + 1;
|
||||||
|
|
||||||
|
if ((mCurMethodInstance != NULL) && (mCurMethodInstance->mMethodInfoEx != NULL) && (mCurMethodInstance->mMethodInfoEx->mMinDependDepth != -1))
|
||||||
|
{
|
||||||
|
int wantTypeMinDepth = mCurMethodInstance->mMethodInfoEx->mMinDependDepth + 1;
|
||||||
|
if ((wantMinDepth == -1) || (wantTypeMinDepth < wantMinDepth))
|
||||||
|
wantMinDepth = wantTypeMinDepth;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((methodInstance->mMethodInfoEx->mMinDependDepth == -1) || (wantMinDepth < methodInstance->mMethodInfoEx->mMinDependDepth))
|
||||||
|
methodInstance->mMethodInfoEx->mMinDependDepth = wantMinDepth;
|
||||||
|
}
|
||||||
|
|
||||||
void BfModule::DbgFinish()
|
void BfModule::DbgFinish()
|
||||||
{
|
{
|
||||||
if ((mBfIRBuilder == NULL) || (mExtensionCount != 0))
|
if ((mBfIRBuilder == NULL) || (mExtensionCount != 0))
|
||||||
|
|
|
@ -1844,6 +1844,7 @@ public:
|
||||||
void CompareDeclTypes(BfTypeDef* newDeclType, BfTypeDef* prevDeclType, bool& isBetter, bool& isWorse);
|
void CompareDeclTypes(BfTypeDef* newDeclType, BfTypeDef* prevDeclType, bool& isBetter, bool& isWorse);
|
||||||
bool SlotVirtualMethod(BfMethodInstance* methodInstance, BfAmbiguityContext* ambiguityContext = NULL);
|
bool SlotVirtualMethod(BfMethodInstance* methodInstance, BfAmbiguityContext* ambiguityContext = NULL);
|
||||||
bool SlotInterfaceMethod(BfMethodInstance* methodInstance);
|
bool SlotInterfaceMethod(BfMethodInstance* methodInstance);
|
||||||
|
void SetMethodDependency(BfMethodInstance* methodInstance);
|
||||||
BfModuleMethodInstance ReferenceExternalMethodInstance(BfMethodInstance* methodInstance, BfGetMethodInstanceFlags flags = BfGetMethodInstanceFlag_None);
|
BfModuleMethodInstance ReferenceExternalMethodInstance(BfMethodInstance* methodInstance, BfGetMethodInstanceFlags flags = BfGetMethodInstanceFlag_None);
|
||||||
BfModule* GetOrCreateMethodModule(BfMethodInstance* methodInstance);
|
BfModule* GetOrCreateMethodModule(BfMethodInstance* methodInstance);
|
||||||
BfModuleMethodInstance GetMethodInstance(BfTypeInstance* typeInst, BfMethodDef* methodDef, const BfTypeVector& methodGenericArguments, BfGetMethodInstanceFlags flags = BfGetMethodInstanceFlag_None, BfTypeInstance* foreignType = NULL);
|
BfModuleMethodInstance GetMethodInstance(BfTypeInstance* typeInst, BfMethodDef* methodDef, const BfTypeVector& methodGenericArguments, BfGetMethodInstanceFlags flags = BfGetMethodInstanceFlag_None, BfTypeInstance* foreignType = NULL);
|
||||||
|
|
|
@ -330,9 +330,7 @@ bool BfModule::ValidateGenericConstraints(BfTypeReference* typeRef, BfTypeInstan
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto typeDef = genericTypeInst->mTypeDef;
|
auto typeDef = genericTypeInst->mTypeDef;
|
||||||
//for (int paramIdx = 0; paramIdx < (int)genericTypeInst->mGenericTypeInfo->mTypeGenericArguments.size(); paramIdx++)
|
|
||||||
|
|
||||||
for (int paramIdx = 0; paramIdx < (int)genericTypeInst->mGenericTypeInfo->mGenericParams.size(); paramIdx++)
|
for (int paramIdx = 0; paramIdx < (int)genericTypeInst->mGenericTypeInfo->mGenericParams.size(); paramIdx++)
|
||||||
{
|
{
|
||||||
auto genericParamInstance = genericTypeInst->mGenericTypeInfo->mGenericParams[paramIdx];
|
auto genericParamInstance = genericTypeInst->mGenericTypeInfo->mGenericParams[paramIdx];
|
||||||
|
@ -501,6 +499,18 @@ void BfModule::CheckInjectNewRevision(BfTypeInstance* typeInstance)
|
||||||
void BfModule::InitType(BfType* resolvedTypeRef, BfPopulateType populateType)
|
void BfModule::InitType(BfType* resolvedTypeRef, BfPopulateType populateType)
|
||||||
{
|
{
|
||||||
BP_ZONE("BfModule::InitType");
|
BP_ZONE("BfModule::InitType");
|
||||||
|
|
||||||
|
if (auto depType = resolvedTypeRef->ToDependedType())
|
||||||
|
{
|
||||||
|
if ((mCurMethodInstance != NULL) && (mCurMethodInstance->mMethodInfoEx != NULL))
|
||||||
|
{
|
||||||
|
depType->mDependencyMap.mMinDependDepth = mCurMethodInstance->mMethodInfoEx->mMinDependDepth + 1;
|
||||||
|
}
|
||||||
|
else if (mCurTypeInstance != NULL)
|
||||||
|
{
|
||||||
|
depType->mDependencyMap.mMinDependDepth = mCurTypeInstance->mDependencyMap.mMinDependDepth + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SetAndRestoreValue<BfTypeInstance*> prevTypeInstance(mCurTypeInstance, resolvedTypeRef->ToTypeInstance());
|
SetAndRestoreValue<BfTypeInstance*> prevTypeInstance(mCurTypeInstance, resolvedTypeRef->ToTypeInstance());
|
||||||
SetAndRestoreValue<BfMethodInstance*> prevMethodInstance(mCurMethodInstance, NULL);
|
SetAndRestoreValue<BfMethodInstance*> prevMethodInstance(mCurMethodInstance, NULL);
|
||||||
|
@ -2143,7 +2153,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
||||||
auto _AddStaticSearch = [&](BfTypeDef* typeDef)
|
auto _AddStaticSearch = [&](BfTypeDef* typeDef)
|
||||||
{
|
{
|
||||||
if (typeDef->mStaticSearch.IsEmpty())
|
if (typeDef->mStaticSearch.IsEmpty())
|
||||||
return;
|
return;
|
||||||
BfStaticSearch* staticSearch;
|
BfStaticSearch* staticSearch;
|
||||||
if (typeInstance->mStaticSearchMap.TryAdd(typeDef, NULL, &staticSearch))
|
if (typeInstance->mStaticSearchMap.TryAdd(typeDef, NULL, &staticSearch))
|
||||||
{
|
{
|
||||||
|
@ -2162,9 +2172,9 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
||||||
staticSearch->mStaticTypes.Add(staticTypeInst);
|
staticSearch->mStaticTypes.Add(staticTypeInst);
|
||||||
AddDependency(staticTypeInst, typeInstance, BfDependencyMap::DependencyFlag_StaticValue);
|
AddDependency(staticTypeInst, typeInstance, BfDependencyMap::DependencyFlag_StaticValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (typeDef->mIsCombinedPartial)
|
if (typeDef->mIsCombinedPartial)
|
||||||
|
@ -7090,7 +7100,7 @@ BfType* BfModule::ResolveTypeResult(BfTypeReference* typeRef, BfType* resolvedTy
|
||||||
populateModule->PopulateType(resolvedTypeRef, populateType);
|
populateModule->PopulateType(resolvedTypeRef, populateType);
|
||||||
|
|
||||||
if ((genericTypeInstance != NULL) && (genericTypeInstance != mCurTypeInstance) && (populateType > BfPopulateType_Identity))
|
if ((genericTypeInstance != NULL) && (genericTypeInstance != mCurTypeInstance) && (populateType > BfPopulateType_Identity))
|
||||||
{
|
{
|
||||||
bool doValidate = (genericTypeInstance->mGenericTypeInfo->mHadValidateErrors) ||
|
bool doValidate = (genericTypeInstance->mGenericTypeInfo->mHadValidateErrors) ||
|
||||||
(!genericTypeInstance->mGenericTypeInfo->mValidatedGenericConstraints) ||
|
(!genericTypeInstance->mGenericTypeInfo->mValidatedGenericConstraints) ||
|
||||||
(genericTypeInstance->mGenericTypeInfo->mIsUnspecializedVariation);
|
(genericTypeInstance->mGenericTypeInfo->mIsUnspecializedVariation);
|
||||||
|
@ -7102,6 +7112,13 @@ BfType* BfModule::ResolveTypeResult(BfTypeReference* typeRef, BfType* resolvedTy
|
||||||
doValidate = false;
|
doValidate = false;
|
||||||
if (auto curGenericTypeInstance = mCurTypeInstance->ToGenericTypeInstance())
|
if (auto curGenericTypeInstance = mCurTypeInstance->ToGenericTypeInstance())
|
||||||
{
|
{
|
||||||
|
if ((curGenericTypeInstance->mDependencyMap.mMinDependDepth > 32) &&
|
||||||
|
(genericTypeInstance->mDependencyMap.mMinDependDepth > 32))
|
||||||
|
{
|
||||||
|
Fail(StrFormat("Generic type dependency depth exceeded for type '{}'", TypeToString(genericTypeInstance).c_str()), typeRef);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (curGenericTypeInstance->mGenericTypeInfo->mHadValidateErrors)
|
if (curGenericTypeInstance->mGenericTypeInfo->mHadValidateErrors)
|
||||||
doValidate = false;
|
doValidate = false;
|
||||||
}
|
}
|
||||||
|
@ -7731,9 +7748,15 @@ BfTypedValue BfModule::TryLookupGenericConstVaue(BfIdentifierNode* identifierNod
|
||||||
|
|
||||||
BfExprEvaluator exprEvaluator(this);
|
BfExprEvaluator exprEvaluator(this);
|
||||||
exprEvaluator.mExpectingType = genericTypeConstraint;
|
exprEvaluator.mExpectingType = genericTypeConstraint;
|
||||||
exprEvaluator.GetLiteral(identifierNode, constExprValueType->mValue);
|
exprEvaluator.GetLiteral(identifierNode, constExprValueType->mValue);
|
||||||
|
|
||||||
|
if (exprEvaluator.mResult)
|
||||||
|
{
|
||||||
|
auto castedVal = CastToValue(identifierNode, exprEvaluator.mResult, genericTypeConstraint, (BfCastFlags)(BfCastFlags_Explicit | BfCastFlags_SilentFail));
|
||||||
|
if (castedVal)
|
||||||
|
return BfTypedValue(castedVal, genericTypeConstraint);
|
||||||
|
}
|
||||||
|
|
||||||
// We don't want to validate type here
|
|
||||||
return exprEvaluator.mResult;
|
return exprEvaluator.mResult;
|
||||||
}
|
}
|
||||||
else if (genericParamResult->IsGenericParam())
|
else if (genericParamResult->IsGenericParam())
|
||||||
|
@ -8732,7 +8755,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
|
||||||
|
|
||||||
for (auto genericArgRef : genericArguments)
|
for (auto genericArgRef : genericArguments)
|
||||||
{
|
{
|
||||||
auto genericArg = ResolveTypeRef(genericArgRef, BfPopulateType_Identity, BfResolveTypeRefFlag_AllowGenericMethodParamConstValue);
|
auto genericArg = ResolveTypeRef(genericArgRef, BfPopulateType_Identity, (BfResolveTypeRefFlags)(BfResolveTypeRefFlag_AllowGenericTypeParamConstValue | BfResolveTypeRefFlag_AllowGenericMethodParamConstValue));
|
||||||
if (genericArg == NULL)
|
if (genericArg == NULL)
|
||||||
{
|
{
|
||||||
mContext->mResolvedTypes.RemoveEntry(resolvedEntry);
|
mContext->mResolvedTypes.RemoveEntry(resolvedEntry);
|
||||||
|
@ -8816,10 +8839,16 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
|
||||||
auto genericArg = genericArgs[genericParamIdx + startDefGenericParamIdx];
|
auto genericArg = genericArgs[genericParamIdx + startDefGenericParamIdx];
|
||||||
genericTypeInst->mGenericTypeInfo->mTypeGenericArguments.push_back(genericArg);
|
genericTypeInst->mGenericTypeInfo->mTypeGenericArguments.push_back(genericArg);
|
||||||
genericTypeInst->mGenericTypeInfo->mTypeGenericArgumentRefs.push_back(genericArgRef);
|
genericTypeInst->mGenericTypeInfo->mTypeGenericArgumentRefs.push_back(genericArgRef);
|
||||||
|
|
||||||
|
if (genericArg->IsConstExprValue())
|
||||||
|
{
|
||||||
|
NOP;
|
||||||
|
}
|
||||||
|
|
||||||
genericParamIdx++;
|
genericParamIdx++;
|
||||||
}
|
}
|
||||||
|
|
||||||
resolvedEntry->mValue = genericTypeInst;
|
resolvedEntry->mValue = genericTypeInst;
|
||||||
|
|
||||||
CheckUnspecializedGenericType(genericTypeInst, populateType);
|
CheckUnspecializedGenericType(genericTypeInst, populateType);
|
||||||
populateModule->InitType(genericTypeInst, populateType);
|
populateModule->InitType(genericTypeInst, populateType);
|
||||||
|
@ -9290,22 +9319,29 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
|
||||||
return ResolveTypeRef(constTypeRef->mElementType, populateType, (BfResolveTypeRefFlags)(resolveFlags & BfResolveTypeRefFlag_NoResolveGenericParam));
|
return ResolveTypeRef(constTypeRef->mElementType, populateType, (BfResolveTypeRefFlags)(resolveFlags & BfResolveTypeRefFlag_NoResolveGenericParam));
|
||||||
}
|
}
|
||||||
else if (auto constExprTypeRef = BfNodeDynCastExact<BfConstExprTypeRef>(typeRef))
|
else if (auto constExprTypeRef = BfNodeDynCastExact<BfConstExprTypeRef>(typeRef))
|
||||||
{
|
{
|
||||||
|
if ((mCurTypeInstance != NULL) && (mCurTypeInstance->mDependencyMap.mMinDependDepth > 32))
|
||||||
|
{
|
||||||
|
Fail("Generic type dependency depth exceeded", typeRef);
|
||||||
|
mContext->mResolvedTypes.RemoveEntry(resolvedEntry);
|
||||||
|
return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags);
|
||||||
|
}
|
||||||
|
|
||||||
|
BfVariant result;
|
||||||
|
BfType* resultType = NULL;
|
||||||
|
if (constExprTypeRef->mConstExpr != NULL)
|
||||||
|
{
|
||||||
|
result = mContext->mResolvedTypes.EvaluateToVariant(&lookupCtx, constExprTypeRef->mConstExpr, resultType);
|
||||||
|
BF_ASSERT(resultType != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
auto constExprType = new BfConstExprValueType();
|
auto constExprType = new BfConstExprValueType();
|
||||||
constExprType->mContext = mContext;
|
constExprType->mContext = mContext;
|
||||||
|
|
||||||
BfVariant result;
|
constExprType->mType = resultType;
|
||||||
if (constExprTypeRef->mConstExpr != NULL)
|
|
||||||
{
|
|
||||||
BfType* constGenericParam = NULL;
|
|
||||||
result = mContext->mResolvedTypes.EvaluateToVariant(&lookupCtx, constExprTypeRef->mConstExpr, constGenericParam);
|
|
||||||
BF_ASSERT(constGenericParam == NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
constExprType->mType = GetPrimitiveType(result.mTypeCode);
|
|
||||||
BF_ASSERT(constExprType->mType != NULL);
|
BF_ASSERT(constExprType->mType != NULL);
|
||||||
if (constExprType->mType == NULL)
|
if (constExprType->mType == NULL)
|
||||||
constExprType->mType = GetPrimitiveType(BfTypeCode_IntPtr);
|
constExprType->mType = GetPrimitiveType(BfTypeCode_Let);
|
||||||
constExprType->mValue = result;
|
constExprType->mValue = result;
|
||||||
|
|
||||||
resolvedEntry->mValue = constExprType;
|
resolvedEntry->mValue = constExprType;
|
||||||
|
@ -9318,8 +9354,9 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
|
||||||
}
|
}
|
||||||
BF_ASSERT(BfResolvedTypeSet::Equals(constExprType, typeRef, &lookupCtx));
|
BF_ASSERT(BfResolvedTypeSet::Equals(constExprType, typeRef, &lookupCtx));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
populateModule->InitType(constExprType, populateType);
|
||||||
|
|
||||||
populateModule->InitType(constExprType, populateType);
|
|
||||||
return constExprType;
|
return constExprType;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -11689,6 +11726,9 @@ void BfModule::VariantToString(StringImpl& str, const BfVariant& variant)
|
||||||
str += ".0";
|
str += ".0";
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case BfTypeCode_Let:
|
||||||
|
str += "?";
|
||||||
|
break;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12165,7 +12205,7 @@ void BfModule::DoTypeToString(StringImpl& str, BfType* resolvedType, BfTypeNameF
|
||||||
{
|
{
|
||||||
auto constExprValueType = (BfConstExprValueType*)resolvedType;
|
auto constExprValueType = (BfConstExprValueType*)resolvedType;
|
||||||
str += "const ";
|
str += "const ";
|
||||||
|
|
||||||
DoTypeToString(str, constExprValueType->mType, typeNameFlags, genericMethodNameOverrides);
|
DoTypeToString(str, constExprValueType->mType, typeNameFlags, genericMethodNameOverrides);
|
||||||
str += " ";
|
str += " ";
|
||||||
|
|
||||||
|
|
|
@ -74,6 +74,16 @@ bool BfDependencyMap::AddUsedBy(BfType* dependentType, BfDependencyMap::Dependen
|
||||||
DependencyEntry* dependencyEntry = NULL;
|
DependencyEntry* dependencyEntry = NULL;
|
||||||
if (mTypeSet.TryAddRaw(dependentType, NULL, &dependencyEntry))
|
if (mTypeSet.TryAddRaw(dependentType, NULL, &dependencyEntry))
|
||||||
{
|
{
|
||||||
|
if ((flags & ~DependencyFlag_UnspecializedType) != 0)
|
||||||
|
{
|
||||||
|
if (auto dependentDepType = dependentType->ToDependedType())
|
||||||
|
{
|
||||||
|
int tryDepth = dependentDepType->mDependencyMap.mMinDependDepth + 1;
|
||||||
|
if (tryDepth < mMinDependDepth)
|
||||||
|
mMinDependDepth = tryDepth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
dependencyEntry->mRevision = dependentType->mRevision;
|
dependencyEntry->mRevision = dependentType->mRevision;
|
||||||
dependencyEntry->mFlags = flags;
|
dependencyEntry->mFlags = flags;
|
||||||
return true;
|
return true;
|
||||||
|
@ -1344,7 +1354,10 @@ void BfCustomAttributes::ReportMemory(MemReporter* memReporter)
|
||||||
BfModuleMethodInstance::BfModuleMethodInstance(BfMethodInstance* methodInstance)
|
BfModuleMethodInstance::BfModuleMethodInstance(BfMethodInstance* methodInstance)
|
||||||
{
|
{
|
||||||
mMethodInstance = methodInstance;
|
mMethodInstance = methodInstance;
|
||||||
mFunc = mMethodInstance->mIRFunction;
|
if (methodInstance != NULL)
|
||||||
|
mFunc = mMethodInstance->mIRFunction;
|
||||||
|
else
|
||||||
|
mFunc = BfIRValue();
|
||||||
// if (methodInstance->GetImportCallKind() == BfImportCallKind_Thunk)
|
// if (methodInstance->GetImportCallKind() == BfImportCallKind_Thunk)
|
||||||
// {
|
// {
|
||||||
// auto declModule = methodInstance->mDeclModule;
|
// auto declModule = methodInstance->mDeclModule;
|
||||||
|
@ -2515,18 +2528,19 @@ BfResolvedTypeSet::~BfResolvedTypeSet()
|
||||||
#define HASH_CONSTEXPR 12
|
#define HASH_CONSTEXPR 12
|
||||||
#define HASH_GLOBAL 13
|
#define HASH_GLOBAL 13
|
||||||
|
|
||||||
BfVariant BfResolvedTypeSet::EvaluateToVariant(LookupContext* ctx, BfExpression* expr, BfType*& constGenericParam)
|
BfVariant BfResolvedTypeSet::EvaluateToVariant(LookupContext* ctx, BfExpression* expr, BfType*& outType)
|
||||||
{
|
{
|
||||||
BfConstResolver constResolver(ctx->mModule);
|
BfConstResolver constResolver(ctx->mModule);
|
||||||
BfVariant variant = { BfTypeCode_None };
|
BfVariant variant = { BfTypeCode_None };
|
||||||
|
constResolver.mAllowGenericConstValue = true;
|
||||||
auto result = constResolver.Resolve(expr);
|
auto result = constResolver.Resolve(expr);
|
||||||
if (result)
|
outType = result.mType;
|
||||||
{
|
if (result)
|
||||||
|
{
|
||||||
if (result.mKind == BfTypedValueKind_GenericConstValue)
|
if (result.mKind == BfTypedValueKind_GenericConstValue)
|
||||||
{
|
{
|
||||||
constGenericParam = result.mType;
|
|
||||||
return variant;
|
return variant;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
variant = ctx->mModule->TypedValueToVariant(expr, result, true);
|
variant = ctx->mModule->TypedValueToVariant(expr, result, true);
|
||||||
|
@ -2709,7 +2723,9 @@ int BfResolvedTypeSet::Hash(BfType* type, LookupContext* ctx, bool allowRef)
|
||||||
else if (type->IsConstExprValue())
|
else if (type->IsConstExprValue())
|
||||||
{
|
{
|
||||||
BfConstExprValueType* constExprValueType = (BfConstExprValueType*)type;
|
BfConstExprValueType* constExprValueType = (BfConstExprValueType*)type;
|
||||||
return ((int)constExprValueType->mValue.mTypeCode << 17) ^ (constExprValueType->mValue.mInt32 << 3) ^ HASH_CONSTTYPE;
|
int hashVal = ((int)constExprValueType->mValue.mTypeCode << 17) ^ (constExprValueType->mValue.mInt32 << 3) ^ HASH_CONSTTYPE;
|
||||||
|
hashVal = ((hashVal ^ (Hash(constExprValueType->mType, ctx, BfHashFlag_AllowRef))) << 5) - hashVal;
|
||||||
|
return hashVal;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -3216,21 +3232,23 @@ int BfResolvedTypeSet::Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHash
|
||||||
else if (auto constExprTypeRef = BfNodeDynCastExact<BfConstExprTypeRef>(typeRef))
|
else if (auto constExprTypeRef = BfNodeDynCastExact<BfConstExprTypeRef>(typeRef))
|
||||||
{
|
{
|
||||||
BfVariant result;
|
BfVariant result;
|
||||||
|
BfType* resultType = NULL;
|
||||||
if (constExprTypeRef->mConstExpr != NULL)
|
if (constExprTypeRef->mConstExpr != NULL)
|
||||||
{
|
{
|
||||||
BfType* constGenericParam = NULL;
|
result = EvaluateToVariant(ctx, constExprTypeRef->mConstExpr, resultType);
|
||||||
result = EvaluateToVariant(ctx, constExprTypeRef->mConstExpr, constGenericParam);
|
if ((resultType != NULL) && (resultType->IsGenericParam()))
|
||||||
if (constGenericParam != NULL)
|
return Hash(resultType, ctx);
|
||||||
return Hash(constGenericParam, ctx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result.mTypeCode == BfTypeCode_None)
|
if (resultType == NULL)
|
||||||
{
|
{
|
||||||
ctx->mFailed = true;
|
ctx->mFailed = true;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ((int)result.mTypeCode << 17) ^ (result.mInt32 << 3) ^ HASH_CONSTTYPE;
|
auto hashVal = ((int)result.mTypeCode << 17) ^ (result.mInt32 << 3) ^ HASH_CONSTTYPE;
|
||||||
|
hashVal = ((hashVal ^ (Hash(resultType, ctx, BfHashFlag_AllowRef))) << 5) - hashVal;
|
||||||
|
return hashVal;
|
||||||
}
|
}
|
||||||
else if (auto dotTypeRef = BfNodeDynCastExact<BfDotTypeReference>(typeRef))
|
else if (auto dotTypeRef = BfNodeDynCastExact<BfDotTypeReference>(typeRef))
|
||||||
{
|
{
|
||||||
|
@ -3884,9 +3902,9 @@ bool BfResolvedTypeSet::Equals(BfType* lhs, BfTypeReference* rhs, LookupContext*
|
||||||
if (constExprTypeRef->mConstExpr == NULL)
|
if (constExprTypeRef->mConstExpr == NULL)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
BfType* constGenericParam = NULL;
|
BfType* resultType = NULL;
|
||||||
result = EvaluateToVariant(ctx, constExprTypeRef->mConstExpr, constGenericParam);
|
result = EvaluateToVariant(ctx, constExprTypeRef->mConstExpr, resultType);
|
||||||
return constGenericParam == lhs;
|
return resultType == lhs;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -3999,9 +4017,9 @@ bool BfResolvedTypeSet::Equals(BfType* lhs, BfTypeReference* rhs, LookupContext*
|
||||||
BfVariant result;
|
BfVariant result;
|
||||||
if (constExprTypeRef->mConstExpr != NULL)
|
if (constExprTypeRef->mConstExpr != NULL)
|
||||||
{
|
{
|
||||||
BfType* constGenericParam = NULL;
|
BfType* resultType = NULL;
|
||||||
result = EvaluateToVariant(ctx, constExprTypeRef->mConstExpr, constGenericParam);
|
result = EvaluateToVariant(ctx, constExprTypeRef->mConstExpr, resultType);
|
||||||
if (constGenericParam != NULL)
|
if (resultType != lhsConstExprType->mType)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4455,4 +4473,8 @@ int BfTypeUtils::GetSplatCount(BfType* type)
|
||||||
return splatCount;
|
return splatCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BfConstExprValueType::~BfConstExprValueType()
|
||||||
|
{
|
||||||
|
// mContext->mTypeConstExprCount--;
|
||||||
|
// BF_ASSERT(mContext->mTypeConstExprCount == 0);
|
||||||
|
}
|
||||||
|
|
|
@ -69,7 +69,8 @@ enum BfGetMethodInstanceFlags : uint16
|
||||||
BfGetMethodInstanceFlag_ForceInline = 0x80,
|
BfGetMethodInstanceFlag_ForceInline = 0x80,
|
||||||
BfGetMethodInstanceFlag_Friend = 0x100,
|
BfGetMethodInstanceFlag_Friend = 0x100,
|
||||||
BfGetMethodInstanceFlag_DisableObjectAccessChecks = 0x200,
|
BfGetMethodInstanceFlag_DisableObjectAccessChecks = 0x200,
|
||||||
BfGetMethodInstanceFlag_NoInline = 0x400
|
BfGetMethodInstanceFlag_NoInline = 0x400,
|
||||||
|
BfGetMethodInstanceFlag_DepthExceeded = 0x800
|
||||||
};
|
};
|
||||||
|
|
||||||
class BfDependencyMap
|
class BfDependencyMap
|
||||||
|
@ -109,12 +110,12 @@ public:
|
||||||
|
|
||||||
struct DependencyEntry
|
struct DependencyEntry
|
||||||
{
|
{
|
||||||
int mRevision;
|
int mRevision;
|
||||||
DependencyFlags mFlags;
|
DependencyFlags mFlags;
|
||||||
|
|
||||||
DependencyEntry(int revision, DependencyFlags flags)
|
DependencyEntry(int revision, DependencyFlags flags)
|
||||||
{
|
{
|
||||||
mRevision = revision;
|
mRevision = revision;
|
||||||
mFlags = flags;
|
mFlags = flags;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -122,8 +123,14 @@ public:
|
||||||
public:
|
public:
|
||||||
typedef Dictionary<BfType*, DependencyEntry> TypeMap;
|
typedef Dictionary<BfType*, DependencyEntry> TypeMap;
|
||||||
TypeMap mTypeSet;
|
TypeMap mTypeSet;
|
||||||
|
int mMinDependDepth;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
BfDependencyMap()
|
||||||
|
{
|
||||||
|
mMinDependDepth = 0;
|
||||||
|
}
|
||||||
|
|
||||||
bool AddUsedBy(BfType* dependentType, DependencyFlags flags);
|
bool AddUsedBy(BfType* dependentType, DependencyFlags flags);
|
||||||
bool IsEmpty();
|
bool IsEmpty();
|
||||||
TypeMap::iterator begin();
|
TypeMap::iterator begin();
|
||||||
|
@ -761,6 +768,7 @@ public:
|
||||||
BfTypeVector mMethodGenericArguments;
|
BfTypeVector mMethodGenericArguments;
|
||||||
Dictionary<int64, BfType*> mGenericTypeBindings;
|
Dictionary<int64, BfType*> mGenericTypeBindings;
|
||||||
BfMethodCustomAttributes* mMethodCustomAttributes;
|
BfMethodCustomAttributes* mMethodCustomAttributes;
|
||||||
|
int mMinDependDepth;
|
||||||
|
|
||||||
BfMethodInfoEx()
|
BfMethodInfoEx()
|
||||||
{
|
{
|
||||||
|
@ -768,6 +776,7 @@ public:
|
||||||
mForeignType = NULL;
|
mForeignType = NULL;
|
||||||
mClosureInstanceInfo = NULL;
|
mClosureInstanceInfo = NULL;
|
||||||
mMethodCustomAttributes = NULL;
|
mMethodCustomAttributes = NULL;
|
||||||
|
mMinDependDepth = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
~BfMethodInfoEx();
|
~BfMethodInfoEx();
|
||||||
|
@ -1701,7 +1710,7 @@ public:
|
||||||
bool mValidatedGenericConstraints;
|
bool mValidatedGenericConstraints;
|
||||||
bool mHadValidateErrors;
|
bool mHadValidateErrors;
|
||||||
bool mInitializedGenericParams;
|
bool mInitializedGenericParams;
|
||||||
bool mFinishedGenericParams;
|
bool mFinishedGenericParams;
|
||||||
Array<BfProject*> mProjectsReferenced; // Generic methods that only refer to these projects don't need a specialized extension
|
Array<BfProject*> mProjectsReferenced; // Generic methods that only refer to these projects don't need a specialized extension
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -2300,6 +2309,8 @@ public:
|
||||||
BfVariant mValue;
|
BfVariant mValue;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
~BfConstExprValueType();
|
||||||
|
|
||||||
virtual bool IsConstExprValue() override { return true; }
|
virtual bool IsConstExprValue() override { return true; }
|
||||||
virtual BfType* GetUnderlyingType() override { return mType; }
|
virtual BfType* GetUnderlyingType() override { return mType; }
|
||||||
};
|
};
|
||||||
|
@ -2397,7 +2408,7 @@ public:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static BfTypeDef* FindRootCommonOuterType(BfTypeDef* outerType, LookupContext* ctx, BfTypeInstance*& outCheckTypeInstance);
|
static BfTypeDef* FindRootCommonOuterType(BfTypeDef* outerType, LookupContext* ctx, BfTypeInstance*& outCheckTypeInstance);
|
||||||
static BfVariant EvaluateToVariant(LookupContext* ctx, BfExpression* expr, BfType*& constGenericParam);
|
static BfVariant EvaluateToVariant(LookupContext* ctx, BfExpression* expr, BfType*& outType);
|
||||||
static bool GenericTypeEquals(BfTypeInstance* lhsGenericType, BfTypeVector* lhsTypeGenericArguments, BfTypeReference* rhs, LookupContext* ctx, int& genericParamOffset);
|
static bool GenericTypeEquals(BfTypeInstance* lhsGenericType, BfTypeVector* lhsTypeGenericArguments, BfTypeReference* rhs, LookupContext* ctx, int& genericParamOffset);
|
||||||
static bool GenericTypeEquals(BfTypeInstance* lhsGenericType, BfTypeVector* typeGenericArguments, BfTypeReference* rhs, BfTypeDef* rhsTypeDef, LookupContext* ctx);
|
static bool GenericTypeEquals(BfTypeInstance* lhsGenericType, BfTypeVector* typeGenericArguments, BfTypeReference* rhs, BfTypeDef* rhsTypeDef, LookupContext* ctx);
|
||||||
static void HashGenericArguments(BfTypeReference* typeRef, LookupContext* ctx, int& hash);
|
static void HashGenericArguments(BfTypeReference* typeRef, LookupContext* ctx, int& hash);
|
||||||
|
|
62
IDEHelper/Tests/src/ConstExprs.bf
Normal file
62
IDEHelper/Tests/src/ConstExprs.bf
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
#pragma warning disable 168
|
||||||
|
using System;
|
||||||
|
namespace Tests
|
||||||
|
{
|
||||||
|
class ConstExprs
|
||||||
|
{
|
||||||
|
enum EnumA
|
||||||
|
{
|
||||||
|
A,
|
||||||
|
B,
|
||||||
|
C
|
||||||
|
}
|
||||||
|
|
||||||
|
class ClassA<T, TSize> where TSize : const int
|
||||||
|
{
|
||||||
|
public int GetVal()
|
||||||
|
{
|
||||||
|
return TSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ClassB<T, TSize> where TSize : const int
|
||||||
|
{
|
||||||
|
ClassA<T, TSize> mVal = new ClassA<T, const TSize>();
|
||||||
|
var mVal2 = new ClassA<T, const TSize + 100>();
|
||||||
|
|
||||||
|
public int GetVal()
|
||||||
|
{
|
||||||
|
return mVal.GetVal();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int GetVal2()
|
||||||
|
{
|
||||||
|
return mVal2.GetVal();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ClassC<TEnum> where TEnum : const EnumA
|
||||||
|
{
|
||||||
|
public int Test()
|
||||||
|
{
|
||||||
|
EnumA ea = TEnum;
|
||||||
|
if (TEnum == .A)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public static void TestBasics()
|
||||||
|
{
|
||||||
|
ClassB<float, const 123> cb = scope .();
|
||||||
|
Test.Assert(cb.GetVal() == 123);
|
||||||
|
Test.Assert(cb.GetVal2() == 223);
|
||||||
|
|
||||||
|
ClassC<const EnumA.A> cc = scope .();
|
||||||
|
Test.Assert(cc.Test() == 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue