瀏覽代碼

Unspec variation base fix, debugger default params, debug enum type

Brian Fiete 3 年之前
父節點
當前提交
cee266d6e6

+ 1 - 0
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")
 AssertEvalContains("ClassA.TEST_StaticMethodB()", "Unable to find address for method")
 AssertAutocompleteEquals("ClassA.TEST_", "TEST_StaticMethodA\nTEST_StaticMethodB")
 AssertAutocompleteEquals("ClassA.TEST_", "TEST_StaticMethodA\nTEST_StaticMethodB")
 AssertAutocompleteEquals("ca.TEST_", "TEST_MethodA\nTEST_MethodB")
 AssertAutocompleteEquals("ca.TEST_", "TEST_MethodA\nTEST_MethodB")
+AssertEvalEquals("Test0(EnumA.C, 200)", "1202")
 NavigateBackwards()
 NavigateBackwards()
 
 
 ToggleCommentAt("ClassA_MethodC")
 ToggleCommentAt("ClassA_MethodC")

+ 15 - 0
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()
 		public static void Test()
 		{
 		{
 			//Test_Start
 			//Test_Start
@@ -57,6 +71,7 @@ namespace IDETest
 			ca.TEST_MethodA();
 			ca.TEST_MethodA();
 			ClassA.TEST_StaticMethodA();
 			ClassA.TEST_StaticMethodA();
 			DoTest();
 			DoTest();
+			Test0(.A, 1, 2);
 		}
 		}
 	}
 	}
 }
 }

+ 1 - 1
IDEHelper/Compiler/BfCompiler.cpp

@@ -2321,7 +2321,7 @@ void BfCompiler::UpdateDependencyMap(bool deleteUnusued, bool& didWork)
 						auto dependentType = itr->mKey;							
 						auto dependentType = itr->mKey;							
 						if (dependentType->IsIncomplete())
 						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
 #endif

+ 1 - 6
IDEHelper/Compiler/BfIRBuilder.cpp

@@ -3206,12 +3206,7 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type)
 						if (fieldInstance->mResolvedType->IsComposite())
 						if (fieldInstance->mResolvedType->IsComposite())
 							PopulateType(fieldInstance->mResolvedType);
 							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()))
 						if ((fieldDef->mIsExtern) && (resolvedFieldType->IsPointer()))
 						{
 						{
 							auto underlyingType = resolvedFieldType->GetUnderlyingType();
 							auto underlyingType = resolvedFieldType->GetUnderlyingType();

+ 69 - 16
IDEHelper/Compiler/BfModule.cpp

@@ -20320,6 +20320,27 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup,
 				
 				
 				if (!paramVar->mIsSplat)
 				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())
 					if (paramVar->mResolvedType->IsValuelessType())
 					{
 					{
 						diVariable = mBfIRBuilder->DbgCreateAutoVariable(diFunction,
 						diVariable = mBfIRBuilder->DbgCreateAutoVariable(diFunction,
@@ -23787,6 +23808,10 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool
 			addToWorkList = false;
 			addToWorkList = false;
 		}
 		}
 	}
 	}
+	else
+	{
+		GetMethodCustomAttributes(methodInstance);
+	}
 
 
 	auto func = methodInstance->mIRFunction;
 	auto func = methodInstance->mIRFunction;
 
 
@@ -24379,25 +24404,43 @@ bool BfModule::SlotVirtualMethod(BfMethodInstance* methodInstance, BfAmbiguityCo
 					if ((!checkMethodDef->mIsVirtual) || (checkMethodDef->mIsOverride))
 					if ((!checkMethodDef->mIsVirtual) || (checkMethodDef->mIsOverride))
 						continue;
 						continue;
 
 
+					BfMethodInstance* baseMethodInstance = NULL;
+
+					int checkMethodIdx = -1;
 					BfMethodInstance* lookupMethodInstance = lookupType->mMethodInstanceGroups[checkMethodDef->mIdx].mDefault;
 					BfMethodInstance* lookupMethodInstance = lookupType->mMethodInstanceGroups[checkMethodDef->mIdx].mDefault;
 					if ((lookupMethodInstance == NULL) || (lookupMethodInstance->mVirtualTableIdx == -1))
 					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)
 					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)))
 					if ((baseMethodInstance != NULL) && (CompareMethodSignatures(baseMethodInstance, methodInstance)))
@@ -24405,7 +24448,9 @@ bool BfModule::SlotVirtualMethod(BfMethodInstance* methodInstance, BfAmbiguityCo
 						if (methodDef->mIsOverride)
 						if (methodDef->mIsOverride)
 						{
 						{
 							BfMethodInstance* checkMethodInstance;
 							BfMethodInstance* checkMethodInstance;
-							if (typeInstance->IsValueType())
+							if (checkMethodIdx == -2)
+								checkMethodInstance = baseMethodInstance;
+							else if (typeInstance->IsValueType())
 								checkMethodInstance = checkBase->mVirtualMethodTable[checkMethodIdx].mDeclaringMethod;
 								checkMethodInstance = checkBase->mVirtualMethodTable[checkMethodIdx].mDeclaringMethod;
 							else
 							else
 								checkMethodInstance = typeInstance->mVirtualMethodTable[checkMethodIdx].mDeclaringMethod;
 								checkMethodInstance = typeInstance->mVirtualMethodTable[checkMethodIdx].mDeclaringMethod;
@@ -24526,7 +24571,7 @@ bool BfModule::SlotVirtualMethod(BfMethodInstance* methodInstance, BfAmbiguityCo
 		if (bestOverrideMethodInstance != NULL)
 		if (bestOverrideMethodInstance != NULL)
 		{
 		{
 			if (ambiguousOverrideMethodInstance != NULL)
 			if (ambiguousOverrideMethodInstance != NULL)
-			{								
+			{
 				bool allow = false;
 				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.
 				// 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)
 				if (!canSeeEachOther)
 				{
 				{
-					BF_ASSERT(bestOverrideMethodInstance->GetOwner()->IsUnspecializedType() && ambiguousOverrideMethodInstance->GetOwner()->IsUnspecializedType());						
+					BF_ASSERT(bestOverrideMethodInstance->GetOwner()->IsUnspecializedType() && ambiguousOverrideMethodInstance->GetOwner()->IsUnspecializedType());
 				}
 				}
 				else
 				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(bestOverrideMethodInstance).c_str()), bestOverrideMethodInstance->mMethodDef->GetRefNode());
 						mCompiler->mPassInstance->MoreInfo(StrFormat("'%s' is a candidate", MethodToString(ambiguousOverrideMethodInstance).c_str()), ambiguousOverrideMethodInstance->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;
 			auto& baseVirtualMethodTable = checkBase->mVirtualMethodTable;
 			BfMethodInstance* baseVirtualMethodInstance = baseVirtualMethodTable[bestOverrideMethodIdx].mDeclaringMethod;
 			BfMethodInstance* baseVirtualMethodInstance = baseVirtualMethodTable[bestOverrideMethodIdx].mDeclaringMethod;
 			if ((baseVirtualMethodInstance != methodInstance) && (methodDef->mIsOverride))
 			if ((baseVirtualMethodInstance != methodInstance) && (methodDef->mIsOverride))

+ 3 - 5
IDEHelper/Compiler/BfModuleTypeUtils.cpp

@@ -3290,9 +3290,9 @@ void BfModule::DoPopulateType_FinishEnum(BfTypeInstance* typeInstance, bool unde
 		{
 		{
 			auto fieldInstance = &fieldInstanceRef;
 			auto fieldInstance = &fieldInstanceRef;
 			auto fieldDef = fieldInstance->GetFieldDef();
 			auto fieldDef = fieldInstance->GetFieldDef();
-			if ((fieldDef != NULL) && (fieldDef->IsEnumCaseEntry()))
+			if (fieldDef != NULL)
 			{
 			{
-				if (fieldInstance->mConstIdx == -1)
+				if ((fieldInstance->mConstIdx == -1) || (fieldInstance->mResolvedType != typeInstance))
 					continue;
 					continue;
 
 
 				auto constant = typeInstance->mConstHolder->GetConstantById(fieldInstance->mConstIdx);
 				auto constant = typeInstance->mConstHolder->GetConstantById(fieldInstance->mConstIdx);
@@ -3343,9 +3343,7 @@ void BfModule::DoPopulateType_FinishEnum(BfTypeInstance* typeInstance, bool unde
 				for (auto& fieldInstanceRef : typeInstance->mFieldInstances)
 				for (auto& fieldInstanceRef : typeInstance->mFieldInstances)
 				{
 				{
 					auto fieldInstance = &fieldInstanceRef;
 					auto fieldInstance = &fieldInstanceRef;
-					if (fieldInstance->mConstIdx == -1)
-						continue;
-					if (!fieldInstance->GetFieldDef()->IsEnumCaseEntry())
+					if ((fieldInstance->mConstIdx == -1) || (fieldInstance->mResolvedType != typeInstance))
 						continue;
 						continue;
 					auto constant = typeInstance->mConstHolder->GetConstantById(fieldInstance->mConstIdx);
 					auto constant = typeInstance->mConstHolder->GetConstantById(fieldInstance->mConstIdx);
 					if (constant->mTypeCode == typeCode)
 					if (constant->mTypeCode == typeCode)

+ 2 - 1
IDEHelper/Compiler/CeMachine.cpp

@@ -1586,7 +1586,8 @@ void CeBuilder::Build()
 				BfMethodInstance dupUnspecMethodInstance;
 				BfMethodInstance dupUnspecMethodInstance;
 				dupUnspecMethodInstance.CopyFrom(unspecializedMethodInstance);
 				dupUnspecMethodInstance.CopyFrom(unspecializedMethodInstance);
 				ProcessMethod(unspecializedMethodInstance, &dupUnspecMethodInstance, false);
 				ProcessMethod(unspecializedMethodInstance, &dupUnspecMethodInstance, false);
-				dupMethodInstance.GetMethodInfoEx()->mGenericTypeBindings = dupUnspecMethodInstance.mMethodInfoEx->mGenericTypeBindings;
+				if (dupUnspecMethodInstance.mMethodInfoEx != NULL)
+					dupMethodInstance.GetMethodInfoEx()->mGenericTypeBindings = dupUnspecMethodInstance.mMethodInfoEx->mGenericTypeBindings;
 			}
 			}
 		}
 		}
 		
 		

+ 8 - 1
IDEHelper/DbgExprEvaluator.cpp

@@ -7246,9 +7246,16 @@ DbgTypedValue DbgExprEvaluator::CreateCall(BfAstNode* targetSrc, DbgTypedValue t
 		}
 		}
 
 
 		BfExpression* arg = NULL;
 		BfExpression* arg = NULL;
+		DbgTypedValue argValue;
 		if (argIdx < (int) arguments.size())
 		if (argIdx < (int) arguments.size())
 		{
 		{
 			arg = arguments[argIdx];
 			arg = arguments[argIdx];
+			argValue = argValues[argIdx];
+		}
+		else if (param->mIsConst)
+		{
+			argValue.mType = param->mType;
+			argValue.mInt64 = param->mConstValue;
 		}
 		}
 		else if (mPassInstance != NULL)
 		else if (mPassInstance != NULL)
 		{
 		{
@@ -7276,7 +7283,7 @@ DbgTypedValue DbgExprEvaluator::CreateCall(BfAstNode* targetSrc, DbgTypedValue t
 			continue;
 			continue;
 		}
 		}
 
 
-		auto argValue = argValues[argIdx];
+		
 		if (argValue.mType == NULL)
 		if (argValue.mType == NULL)
 			return DbgTypedValue();
 			return DbgTypedValue();
 
 

+ 16 - 0
IDEHelper/Tests/src/Generics2.bf

@@ -5,6 +5,22 @@ namespace Tests
 {
 {
 	class Generics2
 	class Generics2
 	{
 	{
+		class ClassA<T, T2>
+		{
+			public virtual int32 GetWidth()
+			{
+				return 123;
+			}
+		}
+
+		class ClassB<T> : ClassA<T, T>
+		{
+			public override int32 GetWidth()
+			{
+				return base.GetWidth();
+			}
+		}
+
 		struct TestFunc<T, Del>
 		struct TestFunc<T, Del>
 		{
 		{
 			private int mId;
 			private int mId;