From 2fe209447e94f4cbf8d1acd4a37b38abe57e7e77 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Fri, 3 Jul 2020 13:54:45 -0700 Subject: [PATCH] Renamed TypeCode_Single to TypeCode_Float. Float struct interop fixes. --- BeefLibs/corlib/src/Type.bf | 3 +- IDEHelper/Backend/BeCOFFObject.cpp | 2 +- IDEHelper/Backend/BeIRCodeGen.cpp | 6 +- IDEHelper/Compiler/BfAst.h | 2 +- IDEHelper/Compiler/BfAutoComplete.cpp | 2 +- IDEHelper/Compiler/BfExprEvaluator.cpp | 11 +- IDEHelper/Compiler/BfIRBuilder.cpp | 72 ++++++- IDEHelper/Compiler/BfIRBuilder.h | 6 +- IDEHelper/Compiler/BfIRCodeGen.cpp | 8 +- IDEHelper/Compiler/BfMangler.cpp | 6 +- IDEHelper/Compiler/BfModule.cpp | 14 +- IDEHelper/Compiler/BfModuleTypeUtils.cpp | 12 +- IDEHelper/Compiler/BfParser.cpp | 4 +- IDEHelper/Compiler/BfResolvedTypeUtils.cpp | 132 +++++++++++-- IDEHelper/Compiler/BfResolvedTypeUtils.h | 4 +- IDEHelper/Compiler/BfSystem.cpp | 2 +- IDEHelper/DbgExprEvaluator.cpp | 4 +- IDEHelper/Tests/BeefProj.toml | 4 +- IDEHelper/Tests/CLib/main.cpp | 155 ++++++++++++++- IDEHelper/Tests/src/Interop.bf | 215 ++++++++++++++++++++- 20 files changed, 595 insertions(+), 69 deletions(-) diff --git a/BeefLibs/corlib/src/Type.bf b/BeefLibs/corlib/src/Type.bf index 8df7f21d..7ee8e1d9 100644 --- a/BeefLibs/corlib/src/Type.bf +++ b/BeefLibs/corlib/src/Type.bf @@ -538,7 +538,8 @@ namespace System Char16, Char32, Float, - Double, + Double, + Float2, Object, Interface, Struct, diff --git a/IDEHelper/Backend/BeCOFFObject.cpp b/IDEHelper/Backend/BeCOFFObject.cpp index 43a36597..93f52234 100644 --- a/IDEHelper/Backend/BeCOFFObject.cpp +++ b/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; diff --git a/IDEHelper/Backend/BeIRCodeGen.cpp b/IDEHelper/Backend/BeIRCodeGen.cpp index 5a87cb69..e1685d84 100644 --- a/IDEHelper/Backend/BeIRCodeGen.cpp +++ b/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)); diff --git a/IDEHelper/Compiler/BfAst.h b/IDEHelper/Compiler/BfAst.h index d7b15a1d..f4b8e8e3 100644 --- a/IDEHelper/Compiler/BfAst.h +++ b/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; } diff --git a/IDEHelper/Compiler/BfAutoComplete.cpp b/IDEHelper/Compiler/BfAutoComplete.cpp index 4e721c7d..d78b583a 100644 --- a/IDEHelper/Compiler/BfAutoComplete.cpp +++ b/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; diff --git a/IDEHelper/Compiler/BfExprEvaluator.cpp b/IDEHelper/Compiler/BfExprEvaluator.cpp index c66b543b..474a5a75 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.cpp +++ b/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& 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)) diff --git a/IDEHelper/Compiler/BfIRBuilder.cpp b/IDEHelper/Compiler/BfIRBuilder.cpp index b8448a8a..8f7edc62 100644 --- a/IDEHelper/Compiler/BfIRBuilder.cpp +++ b/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; diff --git a/IDEHelper/Compiler/BfIRBuilder.h b/IDEHelper/Compiler/BfIRBuilder.h index 32efe462..b1eab50e 100644 --- a/IDEHelper/Compiler/BfIRBuilder.h +++ b/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); diff --git a/IDEHelper/Compiler/BfIRCodeGen.cpp b/IDEHelper/Compiler/BfIRCodeGen.cpp index 0187ea38..f01ee5be 100644 --- a/IDEHelper/Compiler/BfIRCodeGen.cpp +++ b/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)); diff --git a/IDEHelper/Compiler/BfMangler.cpp b/IDEHelper/Compiler/BfMangler.cpp index a1073c7b..cee67307 100644 --- a/IDEHelper/Compiler/BfMangler.cpp +++ b/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; diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index d4b03ade..7ee4652b 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -5619,7 +5619,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& 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); } diff --git a/IDEHelper/Compiler/BfModuleTypeUtils.cpp b/IDEHelper/Compiler/BfModuleTypeUtils.cpp index caeb5ee2..f1f55d7a 100644 --- a/IDEHelper/Compiler/BfModuleTypeUtils.cpp +++ b/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); diff --git a/IDEHelper/Compiler/BfParser.cpp b/IDEHelper/Compiler/BfParser.cpp index 1fdab00f..3b88f01e 100644 --- a/IDEHelper/Compiler/BfParser.cpp +++ b/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; diff --git a/IDEHelper/Compiler/BfResolvedTypeUtils.cpp b/IDEHelper/Compiler/BfResolvedTypeUtils.cpp index cbd14e82..4a8821f6 100644 --- a/IDEHelper/Compiler/BfResolvedTypeUtils.cpp +++ b/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 _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; diff --git a/IDEHelper/Compiler/BfResolvedTypeUtils.h b/IDEHelper/Compiler/BfResolvedTypeUtils.h index 8e76d605..f1138200 100644 --- a/IDEHelper/Compiler/BfResolvedTypeUtils.h +++ b/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; } diff --git a/IDEHelper/Compiler/BfSystem.cpp b/IDEHelper/Compiler/BfSystem.cpp index 840099ca..f56bbe89 100644 --- a/IDEHelper/Compiler/BfSystem.cpp +++ b/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); } diff --git a/IDEHelper/DbgExprEvaluator.cpp b/IDEHelper/DbgExprEvaluator.cpp index b28c2491..2bfcd3cf 100644 --- a/IDEHelper/DbgExprEvaluator.cpp +++ b/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; diff --git a/IDEHelper/Tests/BeefProj.toml b/IDEHelper/Tests/BeefProj.toml index 39ebdaea..3f2f8467 100644 --- a/IDEHelper/Tests/BeefProj.toml +++ b/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"] diff --git a/IDEHelper/Tests/CLib/main.cpp b/IDEHelper/Tests/CLib/main.cpp index 46af9856..d7cf0587 100644 --- a/IDEHelper/Tests/CLib/main.cpp +++ b/IDEHelper/Tests/CLib/main.cpp @@ -1,4 +1,5 @@ #include +#include 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) diff --git a/IDEHelper/Tests/src/Interop.bf b/IDEHelper/Tests/src/Interop.bf index 36a54d5d..f048cb5f 100644 --- a/IDEHelper/Tests/src/Interop.bf +++ b/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; - Test.Assert(Func0(12, 34) == 3412); + 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);