From cee266d6e6402cc5a8a24b44f0cd9ef649fbb5a3 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Tue, 31 May 2022 11:01:26 -0700 Subject: [PATCH] Unspec variation base fix, debugger default params, debug enum type --- IDE/Tests/Test1/scripts/Methods.txt | 1 + IDE/Tests/Test1/src/Methods.bf | 15 +++++ IDEHelper/Compiler/BfCompiler.cpp | 2 +- IDEHelper/Compiler/BfIRBuilder.cpp | 7 +- IDEHelper/Compiler/BfModule.cpp | 85 +++++++++++++++++++----- IDEHelper/Compiler/BfModuleTypeUtils.cpp | 8 +-- IDEHelper/Compiler/CeMachine.cpp | 3 +- IDEHelper/DbgExprEvaluator.cpp | 9 ++- IDEHelper/Tests/src/Generics2.bf | 16 +++++ 9 files changed, 116 insertions(+), 30 deletions(-) diff --git a/IDE/Tests/Test1/scripts/Methods.txt b/IDE/Tests/Test1/scripts/Methods.txt index e9df0150..668c2fff 100644 --- a/IDE/Tests/Test1/scripts/Methods.txt +++ b/IDE/Tests/Test1/scripts/Methods.txt @@ -12,6 +12,7 @@ AssertEvalEquals("ClassA.TEST_StaticMethodA()", "100") AssertEvalContains("ClassA.TEST_StaticMethodB()", "Unable to find address for method") AssertAutocompleteEquals("ClassA.TEST_", "TEST_StaticMethodA\nTEST_StaticMethodB") AssertAutocompleteEquals("ca.TEST_", "TEST_MethodA\nTEST_MethodB") +AssertEvalEquals("Test0(EnumA.C, 200)", "1202") NavigateBackwards() ToggleCommentAt("ClassA_MethodC") diff --git a/IDE/Tests/Test1/src/Methods.bf b/IDE/Tests/Test1/src/Methods.bf index 3a3936dd..e1a35992 100644 --- a/IDE/Tests/Test1/src/Methods.bf +++ b/IDE/Tests/Test1/src/Methods.bf @@ -50,6 +50,20 @@ namespace IDETest */ } + enum EnumA + { + case A; + case B; + case C; + + public const EnumA D = (EnumA)4; + } + + static int Test0(EnumA a, int b, int c = 1000) + { + return (int)a + (int)b + (int)c; + } + public static void Test() { //Test_Start @@ -57,6 +71,7 @@ namespace IDETest ca.TEST_MethodA(); ClassA.TEST_StaticMethodA(); DoTest(); + Test0(.A, 1, 2); } } } diff --git a/IDEHelper/Compiler/BfCompiler.cpp b/IDEHelper/Compiler/BfCompiler.cpp index d495581f..1e450468 100644 --- a/IDEHelper/Compiler/BfCompiler.cpp +++ b/IDEHelper/Compiler/BfCompiler.cpp @@ -2321,7 +2321,7 @@ void BfCompiler::UpdateDependencyMap(bool deleteUnusued, bool& didWork) auto dependentType = itr->mKey; if (dependentType->IsIncomplete()) { - BF_ASSERT(dependentType->IsDeleting() || dependentType->IsOnDemand() || !dependentType->HasBeenReferenced() || !madeFullPass || dependentType->IsSpecializedByAutoCompleteMethod()); + BF_ASSERT(dependentType->IsDeleting() || dependentType->IsOnDemand() || !dependentType->HasBeenReferenced() || mCanceling || !madeFullPass || dependentType->IsSpecializedByAutoCompleteMethod()); } } #endif diff --git a/IDEHelper/Compiler/BfIRBuilder.cpp b/IDEHelper/Compiler/BfIRBuilder.cpp index 3e47e63e..43d6b421 100644 --- a/IDEHelper/Compiler/BfIRBuilder.cpp +++ b/IDEHelper/Compiler/BfIRBuilder.cpp @@ -3206,12 +3206,7 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type) if (fieldInstance->mResolvedType->IsComposite()) PopulateType(fieldInstance->mResolvedType); - BfIRMDNode constDIType; - if (resolvedFieldType->IsTypedPrimitive()) - constDIType = DbgGetType(resolvedFieldType->GetUnderlyingType());//resolvedFieldType->GetUnderlyingType()->mDIType ; - else - constDIType = DbgCreateConstType(resolvedFieldDIType); - + BfIRMDNode constDIType = DbgCreateConstType(resolvedFieldDIType); if ((fieldDef->mIsExtern) && (resolvedFieldType->IsPointer())) { auto underlyingType = resolvedFieldType->GetUnderlyingType(); diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index c80e927d..68c5e56e 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -20320,6 +20320,27 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, if (!paramVar->mIsSplat) { + if ((paramVar->mParamIdx >= 0) && (paramVar->mParamIdx < methodInstance->mDefaultValues.mSize)) + { + auto defaultValue = methodInstance->mDefaultValues[paramVar->mParamIdx]; + auto constant = mCurTypeInstance->mConstHolder->GetConstant(defaultValue.mValue); + if ((constant != NULL) && + ((BfIRConstHolder::IsIntable(constant->mTypeCode)) || (BfIRConstHolder::IsFloat(constant->mTypeCode)))) + { + int64 writeVal = constant->mInt64; + if (constant->mTypeCode == BfTypeCode_Float) + { + // We need to do this because Singles are stored in mDouble, so we need to reduce here + float floatVal = (float)constant->mDouble; + writeVal = *(uint32*)&floatVal; + } + if (writeVal < 0) + paramName += StrFormat("$_%llu", -writeVal); + else + paramName += StrFormat("$%llu", writeVal); + } + } + if (paramVar->mResolvedType->IsValuelessType()) { diVariable = mBfIRBuilder->DbgCreateAutoVariable(diFunction, @@ -23787,6 +23808,10 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool addToWorkList = false; } } + else + { + GetMethodCustomAttributes(methodInstance); + } auto func = methodInstance->mIRFunction; @@ -24379,25 +24404,43 @@ bool BfModule::SlotVirtualMethod(BfMethodInstance* methodInstance, BfAmbiguityCo if ((!checkMethodDef->mIsVirtual) || (checkMethodDef->mIsOverride)) continue; + BfMethodInstance* baseMethodInstance = NULL; + + int checkMethodIdx = -1; BfMethodInstance* lookupMethodInstance = lookupType->mMethodInstanceGroups[checkMethodDef->mIdx].mDefault; if ((lookupMethodInstance == NULL) || (lookupMethodInstance->mVirtualTableIdx == -1)) - continue; - - int checkMethodIdx = lookupMethodInstance->mVirtualTableIdx; - if (checkMethodIdx >= baseVirtualMethodTable.mSize) - FatalError("SlotVirtualMethod OOB in baseVirtualMethodTable[checkMethodIdx]"); - auto& baseMethodRef = baseVirtualMethodTable[checkMethodIdx]; - if (baseMethodRef.mDeclaringMethod.mMethodNum == -1) { - BF_ASSERT(mCompiler->mOptions.mHasVDataExtender); - continue; + if (lookupType->IsUnspecializedTypeVariation()) + { + if (!lookupMethodInstance->mMethodDef->mIsOverride) + { + baseMethodInstance = lookupMethodInstance; + checkMethodIdx = -2; + } + } + + if (baseMethodInstance == NULL) + continue; } - BfMethodInstance* baseMethodInstance = baseVirtualMethodTable[checkMethodIdx].mDeclaringMethod; if (baseMethodInstance == NULL) { - AssertErrorState(); - continue; + checkMethodIdx = lookupMethodInstance->mVirtualTableIdx; + if (checkMethodIdx >= baseVirtualMethodTable.mSize) + FatalError("SlotVirtualMethod OOB in baseVirtualMethodTable[checkMethodIdx]"); + auto& baseMethodRef = baseVirtualMethodTable[checkMethodIdx]; + if (baseMethodRef.mDeclaringMethod.mMethodNum == -1) + { + BF_ASSERT(mCompiler->mOptions.mHasVDataExtender); + continue; + } + + baseMethodInstance = baseVirtualMethodTable[checkMethodIdx].mDeclaringMethod; + if (baseMethodInstance == NULL) + { + AssertErrorState(); + continue; + } } if ((baseMethodInstance != NULL) && (CompareMethodSignatures(baseMethodInstance, methodInstance))) @@ -24405,7 +24448,9 @@ bool BfModule::SlotVirtualMethod(BfMethodInstance* methodInstance, BfAmbiguityCo if (methodDef->mIsOverride) { BfMethodInstance* checkMethodInstance; - if (typeInstance->IsValueType()) + if (checkMethodIdx == -2) + checkMethodInstance = baseMethodInstance; + else if (typeInstance->IsValueType()) checkMethodInstance = checkBase->mVirtualMethodTable[checkMethodIdx].mDeclaringMethod; else checkMethodInstance = typeInstance->mVirtualMethodTable[checkMethodIdx].mDeclaringMethod; @@ -24526,7 +24571,7 @@ bool BfModule::SlotVirtualMethod(BfMethodInstance* methodInstance, BfAmbiguityCo if (bestOverrideMethodInstance != NULL) { if (ambiguousOverrideMethodInstance != NULL) - { + { bool allow = false; // If neither of these declarations "include" each other then it's okay. This can happen when we have two extensions that create the same virtual method but with different constraints. @@ -24547,7 +24592,7 @@ bool BfModule::SlotVirtualMethod(BfMethodInstance* methodInstance, BfAmbiguityCo if (!canSeeEachOther) { - BF_ASSERT(bestOverrideMethodInstance->GetOwner()->IsUnspecializedType() && ambiguousOverrideMethodInstance->GetOwner()->IsUnspecializedType()); + BF_ASSERT(bestOverrideMethodInstance->GetOwner()->IsUnspecializedType() && ambiguousOverrideMethodInstance->GetOwner()->IsUnspecializedType()); } else { @@ -24557,9 +24602,17 @@ bool BfModule::SlotVirtualMethod(BfMethodInstance* methodInstance, BfAmbiguityCo mCompiler->mPassInstance->MoreInfo(StrFormat("'%s' is a candidate", MethodToString(bestOverrideMethodInstance).c_str()), bestOverrideMethodInstance->mMethodDef->GetRefNode()); mCompiler->mPassInstance->MoreInfo(StrFormat("'%s' is a candidate", MethodToString(ambiguousOverrideMethodInstance).c_str()), ambiguousOverrideMethodInstance->mMethodDef->GetRefNode()); } - } + } } + } + if (bestOverrideMethodIdx == -2) + { + // Comes from an unspecialized variation + virtualMethodMatchIdx = bestOverrideMethodIdx; + } + else if ((bestOverrideMethodInstance != NULL) && (bestOverrideMethodIdx != -1)) + { auto& baseVirtualMethodTable = checkBase->mVirtualMethodTable; BfMethodInstance* baseVirtualMethodInstance = baseVirtualMethodTable[bestOverrideMethodIdx].mDeclaringMethod; if ((baseVirtualMethodInstance != methodInstance) && (methodDef->mIsOverride)) diff --git a/IDEHelper/Compiler/BfModuleTypeUtils.cpp b/IDEHelper/Compiler/BfModuleTypeUtils.cpp index 34ec848c..2386649b 100644 --- a/IDEHelper/Compiler/BfModuleTypeUtils.cpp +++ b/IDEHelper/Compiler/BfModuleTypeUtils.cpp @@ -3290,9 +3290,9 @@ void BfModule::DoPopulateType_FinishEnum(BfTypeInstance* typeInstance, bool unde { auto fieldInstance = &fieldInstanceRef; auto fieldDef = fieldInstance->GetFieldDef(); - if ((fieldDef != NULL) && (fieldDef->IsEnumCaseEntry())) + if (fieldDef != NULL) { - if (fieldInstance->mConstIdx == -1) + if ((fieldInstance->mConstIdx == -1) || (fieldInstance->mResolvedType != typeInstance)) continue; auto constant = typeInstance->mConstHolder->GetConstantById(fieldInstance->mConstIdx); @@ -3343,9 +3343,7 @@ void BfModule::DoPopulateType_FinishEnum(BfTypeInstance* typeInstance, bool unde for (auto& fieldInstanceRef : typeInstance->mFieldInstances) { auto fieldInstance = &fieldInstanceRef; - if (fieldInstance->mConstIdx == -1) - continue; - if (!fieldInstance->GetFieldDef()->IsEnumCaseEntry()) + if ((fieldInstance->mConstIdx == -1) || (fieldInstance->mResolvedType != typeInstance)) continue; auto constant = typeInstance->mConstHolder->GetConstantById(fieldInstance->mConstIdx); if (constant->mTypeCode == typeCode) diff --git a/IDEHelper/Compiler/CeMachine.cpp b/IDEHelper/Compiler/CeMachine.cpp index a34719fd..82b0a0c1 100644 --- a/IDEHelper/Compiler/CeMachine.cpp +++ b/IDEHelper/Compiler/CeMachine.cpp @@ -1586,7 +1586,8 @@ void CeBuilder::Build() BfMethodInstance dupUnspecMethodInstance; dupUnspecMethodInstance.CopyFrom(unspecializedMethodInstance); ProcessMethod(unspecializedMethodInstance, &dupUnspecMethodInstance, false); - dupMethodInstance.GetMethodInfoEx()->mGenericTypeBindings = dupUnspecMethodInstance.mMethodInfoEx->mGenericTypeBindings; + if (dupUnspecMethodInstance.mMethodInfoEx != NULL) + dupMethodInstance.GetMethodInfoEx()->mGenericTypeBindings = dupUnspecMethodInstance.mMethodInfoEx->mGenericTypeBindings; } } diff --git a/IDEHelper/DbgExprEvaluator.cpp b/IDEHelper/DbgExprEvaluator.cpp index 604c5790..2b2a78d3 100644 --- a/IDEHelper/DbgExprEvaluator.cpp +++ b/IDEHelper/DbgExprEvaluator.cpp @@ -7246,9 +7246,16 @@ DbgTypedValue DbgExprEvaluator::CreateCall(BfAstNode* targetSrc, DbgTypedValue t } BfExpression* arg = NULL; + DbgTypedValue argValue; if (argIdx < (int) arguments.size()) { arg = arguments[argIdx]; + argValue = argValues[argIdx]; + } + else if (param->mIsConst) + { + argValue.mType = param->mType; + argValue.mInt64 = param->mConstValue; } else if (mPassInstance != NULL) { @@ -7276,7 +7283,7 @@ DbgTypedValue DbgExprEvaluator::CreateCall(BfAstNode* targetSrc, DbgTypedValue t continue; } - auto argValue = argValues[argIdx]; + if (argValue.mType == NULL) return DbgTypedValue(); diff --git a/IDEHelper/Tests/src/Generics2.bf b/IDEHelper/Tests/src/Generics2.bf index cfd394bf..7f42cba0 100644 --- a/IDEHelper/Tests/src/Generics2.bf +++ b/IDEHelper/Tests/src/Generics2.bf @@ -5,6 +5,22 @@ namespace Tests { class Generics2 { + class ClassA + { + public virtual int32 GetWidth() + { + return 123; + } + } + + class ClassB : ClassA + { + public override int32 GetWidth() + { + return base.GetWidth(); + } + } + struct TestFunc { private int mId;