Kaynağa Gözat

Renamed TypeCode_Single to TypeCode_Float. Float struct interop fixes.

Brian Fiete 5 yıl önce
ebeveyn
işleme
2fe209447e

+ 2 - 1
BeefLibs/corlib/src/Type.bf

@@ -538,7 +538,8 @@ namespace System
 		Char16,
 	    Char32,
 	    Float,
-	    Double,         
+	    Double,
+		Float2,
 	    Object,
 	    Interface,
 	    Struct,

+ 1 - 1
IDEHelper/Backend/BeCOFFObject.cpp

@@ -1250,7 +1250,7 @@ void BeCOFFObject::DbgOutputLocalVar(BeDbgFunction* dbgFunc, BeDbgVariable* dbgV
 			if ((beConst->mType != NULL) && (!beConst->mType->IsPointer()))
 			{
 				int64 writeVal = beConst->mInt64;
-				if (beConst->mType->mTypeCode == BfTypeCode_Single)
+				if (beConst->mType->mTypeCode == BfTypeCode_Float)
 				{
 					// We need to do this because Singles are stored in mDouble, so we need to reduce here
 					float floatVal = (float)beConst->mDouble;

+ 3 - 3
IDEHelper/Backend/BeIRCodeGen.cpp

@@ -367,7 +367,7 @@ BeType* BeIRCodeGen::GetBeType(BfTypeCode typeCode, bool& isSigned)
 		return llvm::Type::getInt32Ty(*mLLVMContext);
 		else
 		return llvm::Type::getInt64Ty(*mLLVMContext);*/
-	case BfTypeCode_Single:
+	case BfTypeCode_Float:
 		beTypeCode = BeTypeCode_Float;
 		break;
 	case BfTypeCode_Double:	
@@ -483,7 +483,7 @@ BfTypeCode BeIRCodeGen::GetTypeCode(BeType * type, bool isSigned)
 	case BeTypeCode_Int64:
 		return (isSigned) ? BfTypeCode_Int64 : BfTypeCode_UInt64;
 	case BeTypeCode_Float:
-		return BfTypeCode_Single;
+		return BfTypeCode_Float;
 	case BeTypeCode_Double:
 		return BfTypeCode_Double;
 	default:
@@ -790,7 +790,7 @@ void BeIRCodeGen::Read(BeValue*& beValue)
 		bool isSigned = false;
 		BeType* llvmConstType = GetBeType(typeCode, isSigned);
 
-		if (typeCode == BfTypeCode_Single)
+		if (typeCode == BfTypeCode_Float)
 		{
 			float f;
 			mStream->Read(&f, sizeof(float));

+ 1 - 1
IDEHelper/Compiler/BfAst.h

@@ -94,7 +94,7 @@ struct BfVariant
 	{
 		if (mTypeCode == BfTypeCode_Double)
 			return mDouble;
-		if (mTypeCode == BfTypeCode_Single)
+		if (mTypeCode == BfTypeCode_Float)
 			return mSingle;
 		return (double)mInt64;
 	}

+ 1 - 1
IDEHelper/Compiler/BfAutoComplete.cpp

@@ -3163,7 +3163,7 @@ String BfAutoComplete::ConstantToString(BfIRConstHolder* constHolder, BfIRValue
 	case BfTypeCode_Int64:
 		return StrFormat(":(int64) %lld", constant->mInt64);		
 
-	case BfTypeCode_Single:		
+	case BfTypeCode_Float:		
 		{			
 			ExactMinimalFloatToStr((float)constant->mDouble, str);
 			String result;

+ 8 - 3
IDEHelper/Compiler/BfExprEvaluator.cpp

@@ -2945,7 +2945,7 @@ void BfExprEvaluator::GetLiteral(BfAstNode* refNode, const BfVariant& variant)
 		mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(variant.mTypeCode, variant.mUInt64), mModule->GetPrimitiveType(variant.mTypeCode));		
 		break;
 
-	case BfTypeCode_Single:
+	case BfTypeCode_Float:
 		mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(variant.mTypeCode, variant.mSingle), mModule->GetPrimitiveType(variant.mTypeCode));
 		break;
 	case BfTypeCode_Double:
@@ -5196,7 +5196,12 @@ void BfExprEvaluator::PushArg(BfTypedValue argVal, SizedArrayImpl<BfIRValue>& ir
 					{
 						auto primType2 = mModule->mBfIRBuilder->GetPrimitiveType(loweredTypeCode2);
 						auto ptrType2 = mModule->mBfIRBuilder->GetPointerTo(primType2);
-						BfIRValue primPtrVal2 = mModule->mBfIRBuilder->CreateBitCast(mModule->mBfIRBuilder->CreateInBoundsGEP(primPtrVal, 1), ptrType2);
+						BfIRValue primPtrVal2;
+						if (mModule->mBfIRBuilder->GetSize(loweredTypeCode) < mModule->mBfIRBuilder->GetSize(loweredTypeCode2))						
+							primPtrVal2 = mModule->mBfIRBuilder->CreateInBoundsGEP(mModule->mBfIRBuilder->CreateBitCast(primPtrVal, ptrType2), 1);						
+						else						
+							primPtrVal2 = mModule->mBfIRBuilder->CreateBitCast(mModule->mBfIRBuilder->CreateInBoundsGEP(primPtrVal, 1), ptrType2);
+						
 						auto primVal2 = mModule->mBfIRBuilder->CreateLoad(primPtrVal2);
 						irArgs.push_back(primVal2);
 					}
@@ -5474,7 +5479,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu
 				{
 					auto typeInst = argValue.mType->ToTypeInstance();
 
-					if (argValue.mType == mModule->GetPrimitiveType(BfTypeCode_Single))
+					if (argValue.mType == mModule->GetPrimitiveType(BfTypeCode_Float))
 						argValue = mModule->Cast(argValues[argIdx].mExpression, argValue, mModule->GetPrimitiveType(BfTypeCode_Double));
 
 					if ((typeInst != NULL) && (typeInst->mTypeDef == mModule->mCompiler->mStringTypeDef))

+ 62 - 10
IDEHelper/Compiler/BfIRBuilder.cpp

@@ -67,7 +67,7 @@ USING_NS_BF;
 	case BfTypeCode_Char32: val = OP(constLHS->mUInt32, constRHS->mUInt32); break; \
 	case BfTypeCode_Int64: val = OP(constLHS->mInt64, constRHS->mInt64); break; \
 	case BfTypeCode_UInt64: val = OP(constLHS->mUInt64, constRHS->mUInt64); break; \
-	case BfTypeCode_Single: \
+	case BfTypeCode_Float: \
 	case BfTypeCode_Double: \
 		return CreateConst(constLHS->mTypeCode, OP(constLHS->mDouble, constRHS->mDouble)); break; \
 	default: break; \
@@ -121,7 +121,7 @@ USING_NS_BF;
 	case BfTypeCode_Char32: val = constLHS->mUInt32 OP constRHS->mUInt32; break; \
 	case BfTypeCode_Int64: val = constLHS->mInt64 OP constRHS->mInt64; break; \
 	case BfTypeCode_UInt64: val = constLHS->mUInt64 OP constRHS->mUInt64; break; \
-	case BfTypeCode_Single: \
+	case BfTypeCode_Float: \
 	case BfTypeCode_Double: \
 		return CreateConst(constLHS->mTypeCode, constLHS->mDouble OP constRHS->mDouble); break; \
 	default: break; \
@@ -167,7 +167,7 @@ USING_NS_BF;
 	case BfTypeCode_Char32: val = OP constVal->mUInt32; break; \
 	case BfTypeCode_Int64: val = OP constVal->mInt64; break; \
 	case BfTypeCode_UInt64: val = OP constVal->mUInt64; break; \
-	case BfTypeCode_Single: \
+	case BfTypeCode_Float: \
 	case BfTypeCode_Double: \
 		return CreateConst(constVal->mTypeCode, OP constVal->mDouble); break; \
 	default: break; \
@@ -198,7 +198,7 @@ USING_NS_BF;
 		case BfTypeCode_UInt32: val = constLHS->mUInt32 OP constRHS->mUInt32; break; \
 		case BfTypeCode_Int64: val = constLHS->mInt64 OP constRHS->mInt64; break; \
 		case BfTypeCode_UInt64: val = constLHS->mUInt64 OP constRHS->mUInt64; break; \
-		case BfTypeCode_Single: val = constLHS->mDouble OP constRHS->mDouble; break; \
+		case BfTypeCode_Float: val = constLHS->mDouble OP constRHS->mDouble; break; \
 		case BfTypeCode_Double: val = constLHS->mDouble OP constRHS->mDouble; break; \
 		default: break; \
 		} \
@@ -289,6 +289,58 @@ void BfIRConstHolder::FixTypeCode(BfTypeCode& typeCode)
 	}
 }
 
+int BfIRConstHolder::GetSize(BfTypeCode typeCode)
+{
+	switch (typeCode)
+	{
+	case BfTypeCode_None: return 0;
+	case BfTypeCode_CharPtr: return mModule->mSystem->mPtrSize;
+	case BfTypeCode_StringId: return 4;
+	case BfTypeCode_Pointer: return mModule->mSystem->mPtrSize;
+	case BfTypeCode_NullPtr: return mModule->mSystem->mPtrSize;
+	case BfTypeCode_Self: return 0;
+	case BfTypeCode_Dot: return 0;
+	case BfTypeCode_Var: return 0;
+	case BfTypeCode_Let: return 0;
+	case BfTypeCode_Boolean: return 1;
+	case BfTypeCode_Int8: return 1;
+	case BfTypeCode_UInt8: return 1;
+	case BfTypeCode_Int16: return 2;
+	case BfTypeCode_UInt16: return 2;
+	case BfTypeCode_Int24: return 3;
+	case BfTypeCode_UInt24: return 3;
+	case BfTypeCode_Int32: return 4;
+	case BfTypeCode_UInt32: return 4;
+	case BfTypeCode_Int40: return 5;
+	case BfTypeCode_UInt40: return 5;
+	case BfTypeCode_Int48: return 6;
+	case BfTypeCode_UInt48: return 6;
+	case BfTypeCode_Int56: return 7;
+	case BfTypeCode_UInt56: return 7;
+	case BfTypeCode_Int64: return 8;
+	case BfTypeCode_UInt64: return 8;
+	case BfTypeCode_Int128: return 16;
+	case BfTypeCode_UInt128: return 16;
+	case BfTypeCode_IntPtr: return mModule->mSystem->mPtrSize;
+	case BfTypeCode_UIntPtr: return mModule->mSystem->mPtrSize;
+	case BfTypeCode_IntUnknown: return 0;
+	case BfTypeCode_UIntUnknown: return 0;
+	case BfTypeCode_Char8: return 1;
+	case BfTypeCode_Char16: return 2;
+	case BfTypeCode_Char32: return 4;
+	case BfTypeCode_Float: return 4;
+	case BfTypeCode_Double: return 8;
+	case BfTypeCode_Float2: return 8;
+	case BfTypeCode_Object: return mModule->mSystem->mPtrSize;
+	case BfTypeCode_Interface: return mModule->mSystem->mPtrSize;
+	case BfTypeCode_Struct: return 0;
+	case BfTypeCode_Enum: return 0;
+	case BfTypeCode_TypeAlias: return 0;
+	case BfTypeCode_Extension: return 0;
+	default: return 0;
+	}
+}
+
 
 bool BfIRConstHolder::IsInt(BfTypeCode typeCode)
 {
@@ -306,7 +358,7 @@ bool BfIRConstHolder::IsSigned(BfTypeCode typeCode)
 
 bool BfIRConstHolder::IsFloat(BfTypeCode typeCode)
 {
-	return (typeCode == BfTypeCode_Single) ||
+	return (typeCode == BfTypeCode_Float) ||
 		(typeCode == BfTypeCode_Double);
 }
 
@@ -580,7 +632,7 @@ BfIRValue BfIRConstHolder::CreateConst(BfConstant* fromConst, BfIRConstHolder* f
 	{		
 		return CreateConst(fromConst->mTypeCode, fromConst->mUInt64);		
 	}
-	else if ((fromConst->mTypeCode == BfTypeCode_Single) || (fromConst->mTypeCode == BfTypeCode_Double))
+	else if ((fromConst->mTypeCode == BfTypeCode_Float) || (fromConst->mTypeCode == BfTypeCode_Double))
 	{
 		return CreateConst(fromConst->mTypeCode, fromConst->mDouble);
 	}	
@@ -1152,7 +1204,7 @@ String BfIRBuilder::ToString(BfIRValue irValue)
 		{
 			return constant->mBool ? "true" : "false";
 		}
-		else if (constant->mTypeCode == BfTypeCode_Single)
+		else if (constant->mTypeCode == BfTypeCode_Float)
 		{
 			return StrFormat("Constant %ff", constant->mDouble);			
 		}
@@ -1705,7 +1757,7 @@ void BfIRBuilder::Write(const BfIRValue& irValue)
 		
 		switch ((int)constant->mTypeCode)
 		{
-		case (int)BfTypeCode_Single:
+		case (int)BfTypeCode_Float:
 			{
 				float f = (float)constant->mDouble;
 				mStream.Write(&f, sizeof(float));
@@ -2247,7 +2299,7 @@ void BfIRBuilder::CreateTypeDeclaration(BfType* type, bool forceDbgDefine)
 				case BfTypeCode_Char32:
 					dwarfType = llvm::dwarf::DW_ATE_unsigned_char;
 					break;
-				case BfTypeCode_Single:
+				case BfTypeCode_Float:
 				case BfTypeCode_Double:
 					dwarfType = llvm::dwarf::DW_ATE_float;
 					break;
@@ -2609,7 +2661,7 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type)
 							if (constant != NULL)
 							{								
 								int64 writeVal = constant->mInt64;
-								if (constant->mTypeCode == BfTypeCode_Single)
+								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;

+ 4 - 2
IDEHelper/Compiler/BfIRBuilder.h

@@ -115,8 +115,9 @@ enum BfTypeCode : uint8
 	BfTypeCode_Char8,
 	BfTypeCode_Char16,
 	BfTypeCode_Char32,
-	BfTypeCode_Single,
-	BfTypeCode_Double,			
+	BfTypeCode_Float,
+	BfTypeCode_Double,
+	BfTypeCode_Float2,
 	BfTypeCode_Object,
 	BfTypeCode_Interface,
 	BfTypeCode_Struct,
@@ -846,6 +847,7 @@ public:
 	
 public:
 	void FixTypeCode(BfTypeCode& typeCode);
+	int GetSize(BfTypeCode typeCode);
 	static bool IsInt(BfTypeCode typeCode);	
 	static bool IsSigned(BfTypeCode typeCode);	
 	static bool IsFloat(BfTypeCode typeCode);

+ 5 - 3
IDEHelper/Compiler/BfIRCodeGen.cpp

@@ -420,7 +420,7 @@ BfTypeCode BfIRCodeGen::GetTypeCode(llvm::Type* type, bool isSigned)
 	}
 
 	if (type->isFloatingPointTy())
-		return BfTypeCode_Single;
+		return BfTypeCode_Float;
 	if (type->isDoubleTy())
 		return BfTypeCode_Double;
 
@@ -509,10 +509,12 @@ llvm::Type* BfIRCodeGen::GetLLVMType(BfTypeCode typeCode, bool& isSigned)
 			return llvm::Type::getInt32Ty(*mLLVMContext);
 		else
 			return llvm::Type::getInt64Ty(*mLLVMContext);*/
-	case BfTypeCode_Single:
+	case BfTypeCode_Float:
 		return llvm::Type::getFloatTy(*mLLVMContext);
 	case BfTypeCode_Double:	
 		return llvm::Type::getDoubleTy(*mLLVMContext);
+	case BfTypeCode_Float2:
+		return llvm::VectorType::get(llvm::Type::getFloatTy(*mLLVMContext), 2);
 	default: break;
 	}
 	return NULL;
@@ -826,7 +828,7 @@ void BfIRCodeGen::Read(llvm::Value*& llvmValue, BfIRCodeGenEntry** codeGenEntry)
 		bool isSigned;
 		llvm::Type* llvmConstType = GetLLVMType(typeCode, isSigned);
 
-		if (typeCode == BfTypeCode_Single)
+		if (typeCode == BfTypeCode_Float)
 		{
 			float f;
 			mStream->Read(&f, sizeof(float));

+ 3 - 3
IDEHelper/Compiler/BfMangler.cpp

@@ -73,7 +73,7 @@ BfTypeCode BfGNUMangler::GetPrimTypeAt(MangleContext& mangleContext, StringImpl&
 		else if (name[strIdx + 1] == 's')
 			return BfTypeCode_Char16;
 		break;
-	case 'f': return BfTypeCode_Single;		
+	case 'f': return BfTypeCode_Float;		
 	case 'd': return BfTypeCode_Double;
 	}
 	return (BfTypeCode)-1;
@@ -485,7 +485,7 @@ void BfGNUMangler::Mangle(MangleContext& mangleContext, StringImpl& name, BfType
 			name += "Ds"; return;
 		case BfTypeCode_Char32:
 			name += "Di"; return;
-		case BfTypeCode_Single:
+		case BfTypeCode_Float:
 			name += "f"; return;
 		case BfTypeCode_Double:
 			name += "d"; return;
@@ -1495,7 +1495,7 @@ void BfMSMangler::Mangle(MangleContext& mangleContext, StringImpl& name, BfType*
 			name += "D"; return;
 		case BfTypeCode_Char16:
 			name += "_S"; return; //char16_t
-		case BfTypeCode_Single:
+		case BfTypeCode_Float:
 			name += "M"; return;
 		case BfTypeCode_Double:
 			name += "N"; return;

+ 9 - 5
IDEHelper/Compiler/BfModule.cpp

@@ -5619,7 +5619,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
 					{
 						PUSH_INT32(constant->mInt32);
 					}
-					else if (constant->mTypeCode == BfTypeCode_Single)
+					else if (constant->mTypeCode == BfTypeCode_Float)
 					{
 						float val = (float)constant->mDouble;
 						PUSH_INT32(*(int*)&val);
@@ -6696,7 +6696,7 @@ void BfModule::ResolveGenericParamConstraints(BfGenericParamInstance* genericPar
 				case BfTypeCode_UIntPtr:
 				case BfTypeCode_IntUnknown:
 				case BfTypeCode_UIntUnknown:
-				case BfTypeCode_Single:
+				case BfTypeCode_Float:
 				case BfTypeCode_Double:
 				case BfTypeCode_Char8:
 				case BfTypeCode_Char16:
@@ -9843,7 +9843,7 @@ BfTypedValue BfModule::GetTypedValueFromConstant(BfConstant* constant, BfIRConst
 	case BfTypeCode_Char8:
 	case BfTypeCode_Char16:
 	case BfTypeCode_Char32:
-	case BfTypeCode_Single:
+	case BfTypeCode_Float:
 	case BfTypeCode_Double:
 		{
 			auto constVal = mBfIRBuilder->CreateConst(constant, constHolder);
@@ -10586,7 +10586,7 @@ BfVariant BfModule::TypedValueToVariant(BfAstNode* refNode, const BfTypedValue&
 			case BfTypeCode_UIntPtr:
 			case BfTypeCode_IntUnknown:
 			case BfTypeCode_UIntUnknown:
-			case BfTypeCode_Single:
+			case BfTypeCode_Float:
 			case BfTypeCode_Double:
 			case BfTypeCode_Char8:
 			case BfTypeCode_Char16:
@@ -17267,7 +17267,11 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
 
 								auto primType2 = mBfIRBuilder->GetPrimitiveType(loweredTypeCode2);
 								auto primPtrType2 = mBfIRBuilder->GetPointerTo(primType2);
-								auto primPtrVal2 = mBfIRBuilder->CreateBitCast(mBfIRBuilder->CreateInBoundsGEP(primPtrVal, 1), primPtrType2);
+								BfIRValue primPtrVal2;
+								if (mBfIRBuilder->GetSize(loweredTypeCode) < mBfIRBuilder->GetSize(loweredTypeCode2))
+									primPtrVal2 = mBfIRBuilder->CreateInBoundsGEP(mBfIRBuilder->CreateBitCast(primPtrVal, primPtrType2), 1);
+								else
+									primPtrVal2 = mBfIRBuilder->CreateBitCast(mBfIRBuilder->CreateInBoundsGEP(primPtrVal, 1), primPtrType2);
 								mBfIRBuilder->CreateStore(mBfIRBuilder->GetArgument(argIdx + 1), primPtrVal2);
 							}
 

+ 6 - 6
IDEHelper/Compiler/BfModuleTypeUtils.cpp

@@ -1181,7 +1181,7 @@ bool BfModule::PopulateType(BfType* resolvedTypeRef, BfPopulateType populateType
 		case BfTypeCode_Char32:
 			PRIMITIVE_TYPE("char32", Int32, 4, DW_ATE_unsigned_char);
 			return true;
-		case BfTypeCode_Single:
+		case BfTypeCode_Float:
 			PRIMITIVE_TYPE("float", Float, 4, DW_ATE_float);
 			return true;
 		case BfTypeCode_Double:
@@ -4688,7 +4688,7 @@ BfPrimitiveType* BfModule::GetPrimitiveType(BfTypeCode typeCode)
 		case BfTypeCode_Char32:
 			primType = (BfPrimitiveType*)ResolveTypeDef(mSystem->mTypeChar32);
 			break;
-		case BfTypeCode_Single:
+		case BfTypeCode_Float:
 			primType = (BfPrimitiveType*)ResolveTypeDef(mSystem->mTypeSingle);
 			break;
 		case BfTypeCode_Double:
@@ -4968,7 +4968,7 @@ BfTypeInstance* BfModule::GetPrimitiveStructType(BfTypeCode typeCode)
 		typeInst = ResolveTypeDef(mSystem->FindTypeDef("System.Char16"), BfPopulateType_Identity)->ToTypeInstance(); break;
 	case BfTypeCode_Char32:
 		typeInst = ResolveTypeDef(mSystem->FindTypeDef("System.Char32"), BfPopulateType_Identity)->ToTypeInstance(); break;
-	case BfTypeCode_Single:
+	case BfTypeCode_Float:
 		typeInst = ResolveTypeDef(mSystem->FindTypeDef("System.Float"), BfPopulateType_Identity)->ToTypeInstance(); break;
 	case BfTypeCode_Double:
 		typeInst = ResolveTypeDef(mSystem->FindTypeDef("System.Double"), BfPopulateType_Identity)->ToTypeInstance(); break;
@@ -9646,7 +9646,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
 			default: break;
 			}
 			break;
-		case BfTypeCode_Single:
+		case BfTypeCode_Float:
 			switch (fromTypeCode)
 			{
 			case BfTypeCode_Int8:
@@ -9683,7 +9683,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
 			case BfTypeCode_UIntPtr:
 			case BfTypeCode_UIntUnknown:
 				allowCast = true; break;
-			case BfTypeCode_Single:
+			case BfTypeCode_Float:
 				allowCast = true; break;
 			default: break;
 			}
@@ -10764,7 +10764,7 @@ void BfModule::VariantToString(StringImpl& str, const BfVariant& variant)
 	case BfTypeCode_UInt64:
 		str += StrFormat("%llu", variant.mInt64);
 		break;
-	case BfTypeCode_Single:
+	case BfTypeCode_Float:
 		{
 			char cstr[64];
 			ExactMinimalFloatToStr(variant.mSingle, cstr);

+ 2 - 2
IDEHelper/Compiler/BfParser.cpp

@@ -2374,7 +2374,7 @@ void BfParser::NextToken(int endIdx)
 							if ((c == 'f') || (c == 'F'))
 							{
 								mTokenEnd = mSrcIdx;
-								mLiteral.mTypeCode = BfTypeCode_Single;
+								mLiteral.mTypeCode = BfTypeCode_Float;
 								mLiteral.mSingle = (float)ParseLiteralDouble();//(float)dVal;
 								mSyntaxToken = BfSyntaxToken_Literal;
 								return;
@@ -2547,7 +2547,7 @@ void BfParser::NextToken(int endIdx)
 					else if ((c == 'f') || (c == 'F'))
 					{
 						mTokenEnd = mSrcIdx;
-						mLiteral.mTypeCode = BfTypeCode_Single;
+						mLiteral.mTypeCode = BfTypeCode_Float;
 						mLiteral.mSingle = (float)ParseLiteralDouble();//(float)val;
 						mSyntaxToken = BfSyntaxToken_Literal;
 						return;

+ 113 - 19
IDEHelper/Compiler/BfResolvedTypeUtils.cpp

@@ -1470,27 +1470,121 @@ bool BfTypeInstance::GetLoweredType(BfTypeUsage typeUsage, BfTypeCode* outTypeCo
 			return false;
 	}
 	else
-	{		
+	{
 		// Non-Windows systems allow lowered splitting of composites over two int params
  		if (mModule->mSystem->mPtrSize == 8)
  		{
- 			if (mInstSize == 12)
- 			{
- 				if (outTypeCode != NULL)
- 					*outTypeCode = BfTypeCode_Int64;
- 				if (outTypeCode2 != NULL)
- 					*outTypeCode2 = BfTypeCode_Int32;
- 				return true;
- 			}
- 
- 			if (mInstSize == 16)
- 			{
- 				if (outTypeCode != NULL)
- 					*outTypeCode = BfTypeCode_Int64;
- 				if (outTypeCode2 != NULL)
- 					*outTypeCode2 = BfTypeCode_Int64;
- 				return true;
- 			}
+			if ((mInstSize >= 4) && (mInstSize <= 16))
+			{
+				BfTypeCode types[4] = { BfTypeCode_None };
+				
+				std::function<void(BfType*, int)> _CheckType = [&](BfType* type, int offset)
+				{
+					if (auto typeInst = type->ToTypeInstance())
+					{
+						if (typeInst->IsValueType())
+						{
+							if (typeInst->mBaseType != NULL)
+								_CheckType(typeInst->mBaseType, offset);
+
+							for (auto& fieldInstance : typeInst->mFieldInstances)
+							{
+								if (fieldInstance.mDataOffset >= 0)
+									_CheckType(fieldInstance.mResolvedType, offset + fieldInstance.mDataOffset);
+							}
+						}
+						else
+							types[offset / 4] = BfTypeCode_Object;
+					}
+					else if (type->IsPrimitiveType())
+					{
+						auto primType = (BfPrimitiveType*)type;
+						types[offset / 4] = primType->mTypeDef->mTypeCode;
+					}
+					else if (type->IsSizedArray())
+					{
+						auto sizedArray = (BfSizedArrayType*)type;
+						for (int i = 0; i < sizedArray->mElementCount; i++)
+							_CheckType(sizedArray->mElementType, offset + i * sizedArray->mElementType->GetStride());
+					}
+				};
+
+				_CheckType(this, 0);
+
+				bool handled = false;
+
+				if (mInstSize >= 8)
+				{
+					if (outTypeCode != NULL)
+						*outTypeCode = BfTypeCode_Int64;
+				}
+
+				if (mInstSize == 8)
+				{
+					handled = true;
+				}
+
+				if (mInstSize == 9)
+				{
+					handled = true;
+					if (outTypeCode2 != NULL)
+						*outTypeCode2 = BfTypeCode_Int8;					
+				}
+				if (mInstSize == 10)
+				{
+					handled = true;
+					if (outTypeCode2 != NULL)
+						*outTypeCode2 = BfTypeCode_Int16;
+				}
+				if (mInstSize == 12)
+				{					
+					handled = true;
+					if (outTypeCode2 != NULL)
+						*outTypeCode2 = BfTypeCode_Int32;					
+				}
+				if (mInstSize == 16)
+				{
+					handled = true;
+					if (outTypeCode2 != NULL)
+						*outTypeCode2 = BfTypeCode_Int64;					
+				}
+
+				if ((types[0] == BfTypeCode_Float) && (types[1] == BfTypeCode_None))
+				{
+					handled = true;
+					if (outTypeCode != NULL)
+						*outTypeCode = BfTypeCode_Float;
+				}
+				if ((types[0] == BfTypeCode_Float) && (types[1] == BfTypeCode_Float))
+				{					
+					if (outTypeCode != NULL)
+						*outTypeCode = BfTypeCode_Float2;
+				}
+				if (types[0] == BfTypeCode_Double)
+				{
+					if (outTypeCode != NULL)
+						*outTypeCode = BfTypeCode_Double;
+				}
+
+				if ((types[2] == BfTypeCode_Float) && (mInstSize == 12))
+				{
+					if (outTypeCode2 != NULL)
+						*outTypeCode2 = BfTypeCode_Float;
+				}
+				if ((types[2] == BfTypeCode_Float) && (types[3] == BfTypeCode_Float))
+				{
+					if (outTypeCode2 != NULL)
+						*outTypeCode2 = BfTypeCode_Float2;
+				}
+				if (types[2] == BfTypeCode_Double)
+				{
+					if (outTypeCode2 != NULL)
+						*outTypeCode2 = BfTypeCode_Double;
+				}
+
+				if (handled)
+					return true;
+			}		
  		}	
 	}
 
@@ -2267,7 +2361,7 @@ BfVariant BfResolvedTypeSet::EvaluateToVariant(LookupContext* ctx, BfExpression*
 			//  when the constraint requirement is int64 (but we don't know that at hash time)
 			if (BfIRConstHolder::IsInt(variant.mTypeCode))
 				variant.mTypeCode = BfTypeCode_Int64;
-			else if (variant.mTypeCode == BfTypeCode_Single)
+			else if (variant.mTypeCode == BfTypeCode_Float)
 			{
 				variant.mTypeCode = BfTypeCode_Double;
 				variant.mDouble = variant.mSingle;

+ 2 - 2
IDEHelper/Compiler/BfResolvedTypeUtils.h

@@ -588,13 +588,13 @@ public:
 	virtual bool IsSigned() override { return (mTypeDef->mTypeCode == BfTypeCode_Int8) || (mTypeDef->mTypeCode == BfTypeCode_Int16) || 
 		(mTypeDef->mTypeCode == BfTypeCode_Int32) || (mTypeDef->mTypeCode == BfTypeCode_Int64) || (mTypeDef->mTypeCode == BfTypeCode_IntPtr) || 
 		(mTypeDef->mTypeCode == BfTypeCode_IntUnknown) ||
-		(mTypeDef->mTypeCode == BfTypeCode_Single) || (mTypeDef->mTypeCode == BfTypeCode_Double); }
+		(mTypeDef->mTypeCode == BfTypeCode_Float) || (mTypeDef->mTypeCode == BfTypeCode_Double); }
 	virtual bool IsSignedInt() override { return (mTypeDef->mTypeCode == BfTypeCode_Int8) || (mTypeDef->mTypeCode == BfTypeCode_Int16) || 
 		(mTypeDef->mTypeCode == BfTypeCode_Int32) || (mTypeDef->mTypeCode == BfTypeCode_Int64) || (mTypeDef->mTypeCode == BfTypeCode_IntPtr) ||
 		(mTypeDef->mTypeCode == BfTypeCode_IntUnknown); }
 	virtual bool IsIntUnknown() override { return (mTypeDef->mTypeCode == BfTypeCode_IntUnknown) || (mTypeDef->mTypeCode == BfTypeCode_UIntUnknown); }
 	virtual bool IsChar() override { return (mTypeDef->mTypeCode == BfTypeCode_Char8) || (mTypeDef->mTypeCode == BfTypeCode_Char16) || (mTypeDef->mTypeCode == BfTypeCode_Char32); }
-	virtual bool IsFloat() override { return (mTypeDef->mTypeCode == BfTypeCode_Single) || (mTypeDef->mTypeCode == BfTypeCode_Double); }
+	virtual bool IsFloat() override { return (mTypeDef->mTypeCode == BfTypeCode_Float) || (mTypeDef->mTypeCode == BfTypeCode_Double); }
 	virtual bool IsNull() override { return mTypeDef->mTypeCode == BfTypeCode_NullPtr; }
 	virtual bool IsVoid() override { return mTypeDef->mTypeCode == BfTypeCode_None; }	
 	virtual bool CanBeValuelessType() override { return mTypeDef->mTypeCode == BfTypeCode_None; }

+ 1 - 1
IDEHelper/Compiler/BfSystem.cpp

@@ -2048,7 +2048,7 @@ void BfSystem::CreateBasicTypes()
 	SYSTEM_TYPE(mTypeChar8, "char8", BfTypeCode_Char8);
 	SYSTEM_TYPE(mTypeChar16, "char16", BfTypeCode_Char16);
 	SYSTEM_TYPE(mTypeChar32, "char32", BfTypeCode_Char32);
-	SYSTEM_TYPE(mTypeSingle, "float", BfTypeCode_Single);
+	SYSTEM_TYPE(mTypeSingle, "float", BfTypeCode_Float);
 	SYSTEM_TYPE(mTypeDouble, "double", BfTypeCode_Double);	
 }
 

+ 2 - 2
IDEHelper/DbgExprEvaluator.cpp

@@ -1381,7 +1381,7 @@ void DbgExprEvaluator::BeefTypeToString(const DbgTypedValue& val, String& outStr
 		case BfTypeCode_Char8: outStr += "char8"; break;
 		case BfTypeCode_Char16: outStr += "char16"; break;
 		case BfTypeCode_Char32: outStr += "char32"; break;
-		case BfTypeCode_Single: outStr += "float"; break;
+		case BfTypeCode_Float: outStr += "float"; break;
 		case BfTypeCode_Double: outStr += "double"; break;
 		}
 	}	
@@ -5432,7 +5432,7 @@ void DbgExprEvaluator::Visit(BfLiteralExpression* literalExpr)
 			mResult.mUInt32 = literalExpr->mValue.mUInt32;
 		}
 		break;
-	case BfTypeCode_Single:
+	case BfTypeCode_Float:
 		mResult.mType = mDbgModule->GetPrimitiveType(DbgType_Single, GetLanguage());
 		mResult.mSingle = literalExpr->mValue.mSingle;
 		break;

+ 2 - 2
IDEHelper/Tests/BeefProj.toml

@@ -14,8 +14,8 @@ LibPaths = ["$(ProjectDir)/CLib/Debug/CLib.lib"]
 
 [Configs.Test.Linux64]
 OtherLinkFlags = "$(LinkFlags) $(ProjectDir)/CLib/main.o -Wl,--export-dynamic"
-PreBuildCmds = ["/usr/bin/c++ $(ProjectDir)/CLib/main.cpp -c -o $(ProjectDir)/CLib/main.o"]
+PreBuildCmds = ["/usr/bin/c++ $(ProjectDir)/CLib/main.cpp -g -c -o $(ProjectDir)/CLib/main.o"]
 
 [Configs.Test.macOS]
 OtherLinkFlags = "$(LinkFlags) $(ProjectDir)/CLib/main.o"
-PreBuildCmds = ["/usr/bin/c++ $(ProjectDir)/CLib/main.cpp -c -o $(ProjectDir)/CLib/main.o"]
+PreBuildCmds = ["/usr/bin/c++ $(ProjectDir)/CLib/main.cpp -g -c -o $(ProjectDir)/CLib/main.o"]

+ 154 - 1
IDEHelper/Tests/CLib/main.cpp

@@ -1,4 +1,5 @@
 #include <inttypes.h>
+#include <stdio.h>
 
 namespace Tests
 {
@@ -199,16 +200,168 @@ namespace Tests
 				return ret;
 			}
 		};
+
+		struct StructK
+		{
+			float mX;
+			float mY;
+		};
+
+		struct StructL
+		{
+			float mX;
+			float mY;
+			float mZ;
+		};
+
+		struct StructM
+		{
+			float mX;
+			float mY;
+			float mZ;
+			float mW;
+		};
+
+		struct StructN
+		{
+			float mX;
+			float mY;
+			float mZ;
+			float mW;
+			float mU;
+		};
+
+		struct StructO
+		{
+			float mX;
+			int mY;
+		};
+
+		struct StructP
+		{
+			float mX;
+			float mY;
+			int mZ;
+		};
+
+		struct StructQ
+		{
+			float mX;
+			float mY;
+			int mZ;
+			int mW;
+		};
+
+		struct StructR
+		{
+			double mX;
+			double mY;
+		};
+
+		struct StructS
+		{
+			float mX;
+			double mY;
+		};
+
+		struct StructT
+		{
+			double mX;
+			double mY;
+			double mZ;
+		};
+
+		struct StructU
+		{
+			StructK mK;
+		};
+
+		struct StructV
+		{
+			int64_t mX;
+			short mY;
+		};
+
+		struct StructW
+		{
+			float mX;
+		};
 	};
 }
 
 using namespace Tests;
 
 extern "C" int Func0(int a, int b)
-{
+{	
 	return a + b * 100;
 }
 
+extern "C" int Func0K(int a, Interop::StructK b)
+{
+	//printf("Func0K: %d %f %f\n", a, b.mX, b.mY);
+	return a + (int)b.mX * 100 + (int)b.mY * 10000;
+}
+
+extern "C" int Func0L(int a, Interop::StructL b)
+{
+	return a + (int)b.mX * 100 + (int)b.mY * 10000;
+}
+
+extern "C" int Func0M(int a, Interop::StructM b)
+{
+	return a + (int)b.mX * 100 + (int)b.mY * 10000;
+}
+
+extern "C" int Func0N(int a, Interop::StructN b)
+{
+	return a + (int)b.mX * 100 + (int)b.mY * 10000;
+}
+
+extern "C" int Func0O(int a, Interop::StructO b)
+{
+	return a + (int)b.mX * 100 + (int)b.mY * 10000;
+}
+
+extern "C" int Func0P(int a, Interop::StructP b)
+{
+	return a + (int)b.mX * 100 + (int)b.mY * 10000;
+}
+
+extern "C" int Func0Q(int a, Interop::StructQ b)
+{
+	return a + (int)b.mX * 100 + (int)b.mY * 10000;
+}
+
+extern "C" int Func0R(int a, Interop::StructR b)
+{
+	return a + (int)b.mX * 100 + (int)b.mY * 10000;
+}
+
+extern "C" int Func0S(int a, Interop::StructS b)
+{
+	return a + (int)b.mX * 100 + (int)b.mY * 10000;
+}
+
+extern "C" int Func0T(int a, Interop::StructT b)
+{
+	return a + (int)b.mX * 100 + (int)b.mY * 10000;
+}
+
+extern "C" int Func0U(int a, Interop::StructU b)
+{
+	return a + (int)b.mK.mX * 100 + (int)b.mK.mY * 10000;
+}
+
+extern "C" int Func0V(int a, Interop::StructV b)
+{
+	return a + (int)b.mX * 100 + (int)b.mY * 10000;
+}
+
+extern "C" int Func0W(int a, Interop::StructW b)
+{
+	return a + (int)b.mX * 100;
+}
+
 //////////////////////////////////////////////////////////////////////////
 
 extern "C" int Func1A(Interop::StructA arg0, Interop::StructA arg1, int arg2)

+ 214 - 1
IDEHelper/Tests/src/Interop.bf

@@ -131,8 +131,133 @@ namespace Tests
 			public extern StructJ MethodJ1(StructJ sa, int32 arg0) mut;
 		}
 
+		[CRepr]
+		public struct StructK
+		{
+			public float mX;
+			public float mY;
+		}
+
+		[CRepr]
+		struct StructL
+		{
+			public float mX;
+			public float mY;
+			public float mZ;
+		}
+
+		[CRepr]
+		struct StructM
+		{
+			public float mX;
+			public float mY;
+			public float mZ;
+			public float mW;
+		}
+
+		[CRepr]
+		struct StructN
+		{
+			public float mX;
+			public float mY;
+			public float mZ;
+			public float mW;
+			public float mU;
+		}
+
+		[CRepr]
+		struct StructO
+		{
+			public float mX;
+			public int32 mY;
+		}
+
+		[CRepr]
+		struct StructP
+		{
+			public float mX;
+			public float mY;
+			public int32 mZ;
+		}
+
+		[CRepr]
+		struct StructQ
+		{
+			public float mX;
+			public float mY;
+			public int32 mZ;
+			public int32 mW;
+		}
+
+		[CRepr]
+		struct StructR
+		{
+			public double mX;
+			public double mY;
+		}
+
+		[CRepr]
+		struct StructS
+		{
+			public float mX;
+			public double mY;
+		}
+
+		[CRepr]
+		struct StructT
+		{
+			public double mX;
+			public double mY;
+			public double mZ;
+		}
+
+		[CRepr]
+		struct StructU
+		{
+			public StructK mK;
+		}
+
+		[CRepr]
+		struct StructV
+		{
+			public int64 mX;
+			public int16 mY;
+		}
+
+		[CRepr]
+		struct StructW
+		{
+			public float mX;
+		}
+
 		[LinkName(.C)]
 		public static extern int32 Func0(int32 a, int32 b);
+		[LinkName(.C)]
+		public static extern int32 Func0K(int32 a, StructK b);
+		[LinkName(.C)]
+		public static extern int32 Func0L(int32 a, StructL b);
+		[LinkName(.C)]
+		public static extern int32 Func0M(int32 a, StructM b);
+		[LinkName(.C)]
+		public static extern int32 Func0N(int32 a, StructN b);
+		[LinkName(.C)]
+		public static extern int32 Func0O(int32 a, StructO b);
+		[LinkName(.C)]
+		public static extern int32 Func0P(int32 a, StructP b);
+		[LinkName(.C)]
+		public static extern int32 Func0Q(int32 a, StructQ b);
+		[LinkName(.C)]
+		public static extern int32 Func0R(int32 a, StructR b);
+		[LinkName(.C)]
+		public static extern int32 Func0S(int32 a, StructS b);
+		[LinkName(.C)]
+		public static extern int32 Func0T(int32 a, StructT b);
+		[LinkName(.C)]
+		public static extern int32 Func0U(int32 a, StructU b);
+		[LinkName(.C)]
+		public static extern int32 Func0V(int32 a, StructV b);
+		[LinkName(.C)]
+		public static extern int32 Func0W(int32 a, StructW b);
 
 		[LinkName(.C)]
 		public static extern int32 Func1A(StructA arg0, StructA arg1, int32 arg2);
@@ -175,6 +300,20 @@ namespace Tests
 		[LinkName(.C)]
 		public static extern StructJ Func4J(StructJ arg0, StructJ arg1, StructJ arg2, StructJ arg3);
 
+		static int32 LocalFunc0K(int32 a, StructK b) => a + (int32)b.mX * 100 + (int32)b.mY * 10000;
+		static int32 LocalFunc0L(int32 a, StructL b) => a + (int32)b.mX * 100 + (int32)b.mY * 10000;
+		static int32 LocalFunc0M(int32 a, StructM b) => a + (int32)b.mX * 100 + (int32)b.mY * 10000;
+		static int32 LocalFunc0N(int32 a, StructN b) => a + (int32)b.mX * 100 + (int32)b.mY * 10000;
+		static int32 LocalFunc0O(int32 a, StructO b) => a + (int32)b.mX * 100 + (int32)b.mY * 10000;
+		static int32 LocalFunc0P(int32 a, StructP b) => a + (int32)b.mX * 100 + (int32)b.mY * 10000;
+		static int32 LocalFunc0Q(int32 a, StructQ b) => a + (int32)b.mX * 100 + (int32)b.mY * 10000;
+		static int32 LocalFunc0R(int32 a, StructR b) => a + (int32)b.mX * 100 + (int32)b.mY * 10000;
+		static int32 LocalFunc0S(int32 a, StructS b) => a + (int32)b.mX * 100 + (int32)b.mY * 10000;
+		static int32 LocalFunc0T(int32 a, StructT b) => a + (int32)b.mX * 100 + (int32)b.mY * 10000;
+		static int32 LocalFunc0U(int32 a, StructU b) => a + (int32)b.mK.mX * 100 + (int32)b.mK.mY * 10000;
+		static int32 LocalFunc0V(int32 a, StructV b) => a + (int32)b.mX * 100 + (int32)b.mY * 10000;
+		static int32 LocalFunc0W(int32 a, StructW b) => a + (int32)b.mX * 100;
+
 		[Test]
 		public static void TestBasics()
 		{
@@ -225,8 +364,82 @@ namespace Tests
 			StructI si1 = default;
 			si1.mA = 91;
 
+			StructK sk = .() { mX = 3, mY = 4};
+			StructL sl = .() { mX = 3, mY = 4};
+			StructM sm = .() { mX = 3, mY = 4};
+			StructN sn = .() { mX = 3, mY = 4};
+			StructO so = .() { mX = 3, mY = 4};
+			StructP sp = .() { mX = 3, mY = 4};
+			StructQ sq = .() { mX = 3, mY = 4};
+			StructR sr = .() { mX = 3, mY = 4};
+			StructS ss = .() { mX = 3, mY = 4};
+			StructT st = .() { mX = 3, mY = 4};
+			StructU su = .() { mK = .(){mX = 3, mY = 4}};
+			StructV sv = .() { mX = 3, mY = 4};
+			StructW sw = .() { mX = 3 };
+
+			void StartTest(String str)
+			{
+				//Console.WriteLine(str);
+			}
+
+			StartTest("Func0");
 			Test.Assert(Func0(12, 34) == 3412);
-
+			StartTest("Func0K");
+			Test.Assert(Func0K(12, sk) == 40312);
+			StartTest("Func0L");
+			Test.Assert(Func0L(12, sl) == 40312);
+			StartTest("Func0M");
+			Test.Assert(Func0M(12, sm) == 40312);
+			StartTest("Func0N");
+			Test.Assert(Func0N(12, sn) == 40312);
+			StartTest("Func0O");
+			Test.Assert(Func0O(12, so) == 40312);
+			StartTest("Func0P");
+			Test.Assert(Func0P(12, sp) == 40312);
+			StartTest("Func0Q");
+			Test.Assert(Func0Q(12, sq) == 40312);
+			StartTest("Func0R");
+			Test.Assert(Func0R(12, sr) == 40312);
+			StartTest("Func0S");
+			Test.Assert(Func0S(12, ss) == 40312);
+			StartTest("Func0T");
+			Test.Assert(Func0T(12, st) == 40312);
+			StartTest("Func0U");
+			Test.Assert(Func0U(12, su) == 40312);
+			StartTest("Func0V");
+			Test.Assert(Func0V(12, sv) == 40312);
+			StartTest("Func0W");
+			Test.Assert(Func0W(12, sw) == 312);
+
+			StartTest("LocalFunc0K");
+			Test.Assert(LocalFunc0K(12, sk) == 40312);
+			StartTest("LocalFunc0L");
+			Test.Assert(LocalFunc0L(12, sl) == 40312);
+			StartTest("LocalFunc0M");
+			Test.Assert(LocalFunc0M(12, sm) == 40312);
+			StartTest("LocalFunc0N");
+			Test.Assert(LocalFunc0N(12, sn) == 40312);
+			StartTest("LocalFunc0O");
+			Test.Assert(LocalFunc0O(12, so) == 40312);
+			StartTest("LocalFunc0P");
+			Test.Assert(LocalFunc0P(12, sp) == 40312);
+			StartTest("LocalFunc0Q");
+			Test.Assert(LocalFunc0Q(12, sq) == 40312);
+			StartTest("LocalFunc0R");
+			Test.Assert(LocalFunc0R(12, sr) == 40312);
+			StartTest("LocalFunc0S");
+			Test.Assert(LocalFunc0S(12, ss) == 40312);
+			StartTest("LocalFunc0T");
+			Test.Assert(LocalFunc0T(12, st) == 40312);
+			StartTest("LocalFunc0U");
+			Test.Assert(LocalFunc0U(12, su) == 40312);
+			StartTest("LocalFunc0V");
+			Test.Assert(LocalFunc0V(12, sv) == 40312);
+			StartTest("LocalFunc0W");
+			Test.Assert(LocalFunc0W(12, sw) == 312);
+
+			StartTest("Func1A");
 			Test.Assert(Func1A(sa0, sa1, 12) == 121110);
 			Test.Assert(sa0.MethodA0(12) == 1012);
 			Test.Assert(sa0.MethodA1(sa1, 12).mA == 33);