2
0
Эх сурвалжийг харах

Improved const handling of char8*

Brian Fiete 5 сар өмнө
parent
commit
7f3b3f2e09

+ 5 - 1
IDEHelper/Compiler/BfIRBuilder.cpp

@@ -322,6 +322,10 @@ String BfIRConstHolder::ToString(BfIRValue irValue)
 		{
 			return StrFormat("Constant %lld", constant->mInt64);
 		}
+		else if (constant->mTypeCode == BfTypeCode_CharPtr)
+		{
+			return StrFormat("CharPtr %d", constant->mInt64);
+		}
 		else if (constant->mTypeCode == BfTypeCode_StringId)
 		{
 			return StrFormat("StringId %d", constant->mInt64);
@@ -942,7 +946,7 @@ BfIRValue BfIRConstHolder::CreateConst(BfConstant* fromConst, BfIRConstHolder* f
 	{
 		return CreateConst(fromConst->mTypeCode, 0);
 	}
-	else if ((IsInt(fromConst->mTypeCode)) || (fromConst->mTypeCode == BfTypeCode_Boolean) || (fromConst->mTypeCode == BfTypeCode_StringId))
+	else if ((IsInt(fromConst->mTypeCode)) || (fromConst->mTypeCode == BfTypeCode_Boolean) || (fromConst->mTypeCode == BfTypeCode_StringId) || (fromConst->mTypeCode == BfTypeCode_CharPtr))
 	{
 		return CreateConst(fromConst->mTypeCode, fromConst->mUInt64);
 	}

+ 75 - 3
IDEHelper/Compiler/BfModule.cpp

@@ -1803,7 +1803,7 @@ int BfModule::GetStringPoolIdx(BfIRValue constantStr, BfIRConstHolder* constHold
 	if (constant == NULL)
 		return -1;
 
-	if (constant->mTypeCode == BfTypeCode_StringId)
+	if ((constant->mTypeCode == BfTypeCode_StringId) || (constant->mTypeCode == BfTypeCode_CharPtr))
 	{
 		return constant->mInt32;
 	}
@@ -1893,7 +1893,16 @@ BfIRValue BfModule::GetStringCharPtr(BfIRValue strValue, bool force)
 
 BfIRValue BfModule::GetStringCharPtr(const StringImpl& str, bool force)
 {
-	return GetStringCharPtr(GetStringObjectValue(str, force), force);
+	auto result = GetStringCharPtr(GetStringObjectValue(str, force), force);
+
+	if (result.IsConst())
+	{
+		auto constant = mBfIRBuilder->GetConstant(result);
+		if ((constant != NULL) && (constant->mTypeCode == BfTypeCode_StringId))
+			return mBfIRBuilder->CreateConst(BfTypeCode_CharPtr, constant->mInt32);
+	}
+
+	return result;
 }
 
 BfIRValue BfModule::GetStringObjectValue(int strId, bool define, bool force)
@@ -12273,6 +12282,8 @@ bool BfModule::HasUnactializedConstant(BfConstant* constant, BfIRConstHolder* co
 		return true;
 	if (constant->mTypeCode == BfTypeCode_StringId)
 		return true;
+	if (constant->mTypeCode == BfTypeCode_CharPtr)
+		return true;
 
 	if (constant->mConstType == BfConstType_Agg)
 	{
@@ -12284,6 +12295,46 @@ bool BfModule::HasUnactializedConstant(BfConstant* constant, BfIRConstHolder* co
 		}
 	}
 
+	if (constant->mConstType == BfConstType_PtrToInt)
+	{
+		auto fromPtrToInt = (BfConstantPtrToInt*)constant;
+		auto fromTarget = constHolder->GetConstantById(fromPtrToInt->mTarget);		
+		return HasUnactializedConstant(fromTarget, constHolder);
+	}
+
+	if (constant->mConstType == BfConstType_BitCast)
+	{
+		auto bitcast = (BfConstantBitCast*)constant;
+		auto fromTarget = constHolder->GetConstantById(bitcast->mTarget);
+		return HasUnactializedConstant(fromTarget, constHolder);
+	}
+
+	return false;
+}
+
+bool BfModule::HasGlobalVarReference(BfConstant* constant, BfIRConstHolder* constHolder)
+{
+	if ((constant->mConstType == BfConstType_TypeOf) || (constant->mConstType == BfConstType_TypeOf_WithData))
+		return true;
+	if (constant->mTypeCode == BfTypeCode_StringId)
+		return true;
+	if (constant->mConstType == BfConstType_GlobalVar)
+		return true;
+
+	// NullPtr is stand-in for GlobalVar during autocomplete
+	if (constant->mTypeCode == BfTypeCode_NullPtr)
+		return true;
+
+	if (constant->mConstType == BfConstType_Agg)
+	{
+		auto constArray = (BfConstantAgg*)constant;
+		for (auto val : constArray->mValues)
+		{
+			if (HasGlobalVarReference(constHolder->GetConstant(val), constHolder))
+				return true;
+		}
+	}	
+
 	return false;
 }
 
@@ -12300,7 +12351,28 @@ BfIRValue BfModule::ConstantToCurrent(BfConstant* constant, BfIRConstHolder* con
 		return GetDefaultValue(wantType);
 	}
 
-	if (constant->mTypeCode == BfTypeCode_StringId)
+	if ((constant->mTypeCode == BfTypeCode_StringId) || (constant->mTypeCode == BfTypeCode_CharPtr))
+	{
+		if (!allowUnactualized)
+		{
+			if ((wantType == NULL) ||
+				(wantType->IsInstanceOf(mCompiler->mStringTypeDef)) ||
+				((wantType->IsPointer()) && (wantType->GetUnderlyingType() == GetPrimitiveType(BfTypeCode_Char8))))
+			{
+				const StringImpl& str = mContext->mStringObjectIdMap[constant->mInt32].mString;
+				BfIRValue stringObjConst = GetStringObjectValue(str, false, true);
+
+				bool wantCharPtr = ((wantType != NULL) && (wantType->IsPointer()));
+				if ((wantType == NULL) && (constant->mTypeCode == BfTypeCode_CharPtr))
+					wantCharPtr = true;
+				if (wantCharPtr)
+					return GetStringCharPtr(stringObjConst, true);
+				return stringObjConst;
+			}
+		}
+	}
+
+	if (constant->mTypeCode == BfTypeCode_CharPtr)
 	{
 		if (!allowUnactualized)
 		{

+ 1 - 0
IDEHelper/Compiler/BfModule.h

@@ -1681,6 +1681,7 @@ public:
 	void CurrentAddToConstHolder(BfIRValue& irVal);
 	void ClearConstData();
 	bool HasUnactializedConstant(BfConstant* constant, BfIRConstHolder* constHolder);
+	bool HasGlobalVarReference(BfConstant* constant, BfIRConstHolder* constHolder);
 	BfTypedValue GetTypedValueFromConstant(BfConstant* constant, BfIRConstHolder* constHolder, BfType* wantType);
 	BfIRValue ConstantToCurrent(BfConstant* constant, BfIRConstHolder* constHolder, BfType* wantType, bool allowUnactualized = false);
 	void ValidateCustomAttributes(BfCustomAttributes* customAttributes, BfAttributeTargets attrTarget, bool force = false);

+ 17 - 0
IDEHelper/Tests/src/ConstExprs.bf

@@ -85,6 +85,20 @@ namespace Tests
 			}
 		}
 
+		struct SpecialId : int
+		{
+			public const Self CONST = (.)(int)(void*)(char8*)"ABC";
+			public static Self operator implicit(String str) => (.)(int)(void*)(char8*)str;
+		}
+
+		public static void TestStr(SpecialId specialId)
+		{
+			char8* ptr = (.)(void*)(int)specialId;
+
+			StringView sv = .(ptr);
+			Test.Assert(sv == "ABC");
+		}
+
 		[Test]
 		public static void TestBasics()
 		{
@@ -101,6 +115,9 @@ namespace Tests
 
 			Test.Assert(TestRangedArray<int32, -3...3>.cRangeEnd - TestRangedArray<int32, -3...3>.cRangeStart == 7);
 			Test.Assert(TestRangedArray<int32, -3...>.cError == "Invalid type: -3...^1");
+
+			TestStr(.CONST);
+			TestStr("ABC");
 		}
 	}
 }