From e9ef8ed27cde3c012bc5737dcbbb847c325340cc Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Mon, 9 Mar 2020 13:10:34 -0700 Subject: [PATCH] Fix for sized array with const member size --- IDEHelper/Compiler/BfExprEvaluator.cpp | 10 +- IDEHelper/Compiler/BfModuleTypeUtils.cpp | 123 ++++++++++++----------- 2 files changed, 69 insertions(+), 64 deletions(-) diff --git a/IDEHelper/Compiler/BfExprEvaluator.cpp b/IDEHelper/Compiler/BfExprEvaluator.cpp index 3dd43a64..1413f9d1 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.cpp +++ b/IDEHelper/Compiler/BfExprEvaluator.cpp @@ -3236,12 +3236,7 @@ BfTypedValue BfExprEvaluator::LookupField(BfAstNode* targetSrc, BfTypedValue tar BfTypeInstance* startCheckType = mModule->mCurTypeInstance; mPropDef = NULL; mPropDefBypassVirtual = false; - - if ((target.mType != NULL) && (mModule->mCurMethodState != NULL)) - { - mModule->PopulateType(target.mType, BfPopulateType_BaseType); - } - + if (target) { if ((!target.mType->IsValueType()) && (target.IsAddr())) @@ -3265,6 +3260,9 @@ BfTypedValue BfExprEvaluator::LookupField(BfAstNode* targetSrc, BfTypedValue tar startCheckType = target.mType->ToTypeInstance(); } + if ((startCheckType != NULL) && (startCheckType->mBaseType == NULL)) + mModule->PopulateType(startCheckType, BfPopulateType_BaseType); + String findName; int varSkipCount = 0; if (fieldName.StartsWith('@')) diff --git a/IDEHelper/Compiler/BfModuleTypeUtils.cpp b/IDEHelper/Compiler/BfModuleTypeUtils.cpp index c668c27e..d12e84cc 100644 --- a/IDEHelper/Compiler/BfModuleTypeUtils.cpp +++ b/IDEHelper/Compiler/BfModuleTypeUtils.cpp @@ -2236,76 +2236,83 @@ bool BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy } int enumCaseEntryIdx = 0; - for (auto field : typeDef->mFields) + for (int pass = 0; pass < 2; pass++) { - auto fieldInstance = &typeInstance->mFieldInstances[field->mIdx]; - if ((fieldInstance->mResolvedType != NULL) || (!fieldInstance->mFieldIncluded)) - continue; - - SetAndRestoreValue prevTypeRef(mContext->mCurTypeState->mCurFieldDef, field); - - BfType* resolvedFieldType = NULL; - - if (field->IsEnumCaseEntry()) + for (auto field : typeDef->mFields) { - fieldInstance->mDataIdx = -(enumCaseEntryIdx++) - 1; - resolvedFieldType = typeInstance; + // Do consts then non-consts. Somewhat of a hack for using consts as sized array size + if (field->mIsConst != (pass == 0)) + continue; - BfType* payloadType = NULL; - if (field->mTypeRef != NULL) - payloadType = ResolveTypeRef(field->mTypeRef, BfPopulateType_Data, BfResolveTypeRefFlag_NoResolveGenericParam); - if (payloadType == NULL) + auto fieldInstance = &typeInstance->mFieldInstances[field->mIdx]; + if ((fieldInstance->mResolvedType != NULL) || (!fieldInstance->mFieldIncluded)) + continue; + + SetAndRestoreValue prevTypeRef(mContext->mCurTypeState->mCurFieldDef, field); + + BfType* resolvedFieldType = NULL; + + if (field->IsEnumCaseEntry()) { - if (!typeInstance->IsTypedPrimitive()) - payloadType = CreateTupleType(BfTypeVector(), Array()); + fieldInstance->mDataIdx = -(enumCaseEntryIdx++) - 1; + resolvedFieldType = typeInstance; + + BfType* payloadType = NULL; + if (field->mTypeRef != NULL) + payloadType = ResolveTypeRef(field->mTypeRef, BfPopulateType_Data, BfResolveTypeRefFlag_NoResolveGenericParam); + if (payloadType == NULL) + { + if (!typeInstance->IsTypedPrimitive()) + payloadType = CreateTupleType(BfTypeVector(), Array()); + } + if (payloadType != NULL) + { + AddDependency(payloadType, typeInstance, BfDependencyMap::DependencyFlag_ValueTypeMemberData); + BF_ASSERT(payloadType->IsTuple()); + resolvedFieldType = payloadType; + fieldInstance->mIsEnumPayloadCase = true; + } } - if (payloadType != NULL) + else if ((field->mTypeRef != NULL) && ((field->mTypeRef->IsExact()) || (field->mTypeRef->IsExact()) || (field->mTypeRef->IsExact()))) { - AddDependency(payloadType, typeInstance, BfDependencyMap::DependencyFlag_ValueTypeMemberData); - BF_ASSERT(payloadType->IsTuple()); - resolvedFieldType = payloadType; - fieldInstance->mIsEnumPayloadCase = true; + resolvedFieldType = GetPrimitiveType(BfTypeCode_Var); + + DeferredResolveEntry resolveEntry; + resolveEntry.mFieldDef = field; + resolveEntry.mTypeArrayIdx = (int)llvmFieldTypes.size(); + deferredVarResolves.push_back(resolveEntry); + + fieldInstance->mIsInferredType = true; + // For 'let', make read-only } - } - else if ((field->mTypeRef != NULL) && ((field->mTypeRef->IsExact()) || (field->mTypeRef->IsExact()) || (field->mTypeRef->IsExact()))) - { - resolvedFieldType = GetPrimitiveType(BfTypeCode_Var); - - DeferredResolveEntry resolveEntry; - resolveEntry.mFieldDef = field; - resolveEntry.mTypeArrayIdx = (int)llvmFieldTypes.size(); - deferredVarResolves.push_back(resolveEntry); - - fieldInstance->mIsInferredType = true; - // For 'let', make read-only - } - else - { - resolvedFieldType = ResolveTypeRef(field->mTypeRef, BfPopulateType_Declaration, BfResolveTypeRefFlag_NoResolveGenericParam); - if (resolvedFieldType == NULL) + else { - // Failed, just put in placeholder 'var' - AssertErrorState(); - resolvedFieldType = GetPrimitiveType(BfTypeCode_Var); + resolvedFieldType = ResolveTypeRef(field->mTypeRef, BfPopulateType_Declaration, BfResolveTypeRefFlag_NoResolveGenericParam); + if (resolvedFieldType == NULL) + { + // Failed, just put in placeholder 'var' + AssertErrorState(); + resolvedFieldType = GetPrimitiveType(BfTypeCode_Var); + } } - } - if (resolvedFieldType->IsMethodRef()) - { - auto methodRefType = (BfMethodRefType*)resolvedFieldType; - } + if (resolvedFieldType->IsMethodRef()) + { + auto methodRefType = (BfMethodRefType*)resolvedFieldType; + } - if (fieldInstance->mResolvedType == NULL) - fieldInstance->mResolvedType = resolvedFieldType; + if (fieldInstance->mResolvedType == NULL) + fieldInstance->mResolvedType = resolvedFieldType; - if (field->mIsConst) - { - // Resolve in ResolveConstField after we finish populating entire FieldInstance list - } - else if (field->mIsStatic) - { - // Don't allocate this until after we're finished populating entire FieldInstance list, - // because we may have re-entry and create multiple instances of this static field + if (field->mIsConst) + { + // Resolve in ResolveConstField after we finish populating entire FieldInstance list + } + else if (field->mIsStatic) + { + // Don't allocate this until after we're finished populating entire FieldInstance list, + // because we may have re-entry and create multiple instances of this static field + } } }