1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-08 11:38:21 +02:00

Bug fixes, installer, [Export]

Fixed a bunch of bugs in aggregate const initializers
Fixed ZIP bugs
Fixed a compilation case where we change protection while reifying a type
Added another project kind - Dynamic Library
Added [Export] for DLL method exporting
Fixed some issues of things being  generated as __NOINLINE incorrectly
Fixed an issue with module extensions with not-yet-demanded on-demand methods
Started adding Installer
This commit is contained in:
Brian Fiete 2019-08-27 08:04:41 -07:00
parent efa22e51fb
commit 09016c8dc0
135 changed files with 3615 additions and 2337 deletions

View file

@ -477,7 +477,13 @@ bool BfCompiler::IsTypeUsed(BfType* checkType, BfProject* curProject)
BfTypeInstance* typeInst = checkType->ToTypeInstance();
if (typeInst != NULL)
{
{
if ((typeInst->mTypeDef->mProject != NULL) && (typeInst->mTypeDef->mProject != curProject))
{
if (typeInst->mTypeDef->mProject->mTargetType == BfTargetType_BeefDynLib)
return false;
}
if (checkType->IsInterface())
return typeInst->mIsReified;
@ -757,6 +763,211 @@ BfIRFunction BfCompiler::CreateLoadSharedLibraries(BfVDataModule* bfModule, Arra
return loadSharedLibFunc;
}
void BfCompiler::GetTestMethods(BfVDataModule* bfModule, Array<TestMethod>& testMethods, HashContext& vdataHashCtx)
{
vdataHashCtx.Mixin(0xBEEF0001); // Marker
auto _CheckMethod = [&](BfTypeInstance* typeInstance, BfMethodInstance* methodInstance)
{
auto project = typeInstance->mTypeDef->mProject;
if (project->mTargetType != BfTargetType_BeefTest)
return;
if (project != bfModule->mProject)
return;
bool isTest = false;
if ((methodInstance->GetCustomAttributes() != NULL) &&
(methodInstance->GetCustomAttributes()->Contains(mTestAttributeTypeDef)))
isTest = true;
if (!isTest)
return;
if (!methodInstance->mMethodDef->mIsStatic)
{
bfModule->Fail(StrFormat("Method '%s' cannot be used for testing because it is not static", bfModule->MethodToString(methodInstance).c_str()),
methodInstance->mMethodDef->GetRefNode());
bfModule->mHadBuildError = true;
return;
}
if (methodInstance->GetParamCount() > 0)
{
if ((methodInstance->GetParamInitializer(0) == NULL) &&
(methodInstance->GetParamKind(0) != BfParamKind_Params))
{
bfModule->Fail(StrFormat("Method '%s' cannot be used for testing because it contains parameters without defaults", bfModule->MethodToString(methodInstance).c_str()),
methodInstance->mMethodDef->GetRefNode());
bfModule->mHadBuildError = true;
return;
}
}
BF_ASSERT(typeInstance->IsReified());
TestMethod testMethod;
testMethod.mMethodInstance = methodInstance;
testMethods.Add(testMethod);
if (!bfModule->mProject->mUsedModules.Contains(typeInstance->mModule))
bfModule->mProject->mUsedModules.Add(typeInstance->mModule);
vdataHashCtx.Mixin(methodInstance->GetOwner()->mTypeId);
vdataHashCtx.Mixin(methodInstance->mMethodDef->mIdx);
};
for (auto type : mContext->mResolvedTypes)
{
auto typeInstance = type->ToTypeInstance();
if (typeInstance == NULL)
continue;
for (auto& methodInstanceGroup : typeInstance->mMethodInstanceGroups)
{
if (methodInstanceGroup.mDefault != NULL)
{
_CheckMethod(typeInstance, methodInstanceGroup.mDefault);
}
}
}
}
void BfCompiler::EmitTestMethod(BfVDataModule* bfModule, Array<TestMethod>& testMethods, BfIRValue& retValue)
{
for (auto& testMethod : testMethods)
{
auto methodInstance = testMethod.mMethodInstance;
auto typeInstance = methodInstance->GetOwner();
testMethod.mName += bfModule->TypeToString(typeInstance);
testMethod.mName += ".";
testMethod.mName += methodInstance->mMethodDef->mName;
testMethod.mName += "\t";
auto testAttribute = methodInstance->GetCustomAttributes()->Get(mTestAttributeTypeDef);
for (auto& field : testAttribute->mSetField)
{
auto constant = typeInstance->mConstHolder->GetConstant(field.mParam.mValue);
if ((constant != NULL) && (constant->mTypeCode == BfTypeCode_Boolean) && (constant->mBool))
{
BfFieldDef* fieldDef = field.mFieldRef;
if (fieldDef->mName == "ShouldFail")
{
testMethod.mName += "Sf";
}
else if (fieldDef->mName == "Profile")
{
testMethod.mName += "Pr";
}
else if (fieldDef->mName == "Ignore")
{
testMethod.mName += "Ig";
}
}
}
bfModule->UpdateSrcPos(methodInstance->mMethodDef->GetRefNode(), (BfSrcPosFlags)(BfSrcPosFlag_NoSetDebugLoc | BfSrcPosFlag_Force));
testMethod.mName += StrFormat("\t%s\t%d\t%d", bfModule->mCurFilePosition.mFileInstance->mParser->mFileName.c_str(), bfModule->mCurFilePosition.mCurLine, bfModule->mCurFilePosition.mCurColumn);
}
std::stable_sort(testMethods.begin(), testMethods.end(),
[](const TestMethod& lhs, const TestMethod& rhs)
{
return lhs.mName < rhs.mName;
});
String methodData;
for (int methodIdx = 0; methodIdx < (int)testMethods.size(); methodIdx++)
{
String& methodName = testMethods[methodIdx].mName;
if (!methodData.IsEmpty())
methodData += "\n";
methodData += methodName;
}
//////////////////////////////////////////////////////////////////////////
auto testInitMethod = bfModule->GetInternalMethod("Test_Init");
auto testQueryMethod = bfModule->GetInternalMethod("Test_Query");
auto testFinishMethod = bfModule->GetInternalMethod("Test_Finish");
auto char8PtrType = bfModule->CreatePointerType(bfModule->GetPrimitiveType(BfTypeCode_Char8));
BfIRType strCharType = bfModule->mBfIRBuilder->GetSizedArrayType(bfModule->mBfIRBuilder->GetPrimitiveType(BfTypeCode_Char8), (int)methodData.length() + 1);
BfIRValue strConstant = bfModule->mBfIRBuilder->CreateConstString(methodData);
BfIRValue gv = bfModule->mBfIRBuilder->CreateGlobalVariable(strCharType,
true, BfIRLinkageType_External,
strConstant, "__bfTestData");
BfIRValue strPtrVal = bfModule->mBfIRBuilder->CreateBitCast(gv, bfModule->mBfIRBuilder->MapType(char8PtrType));
SizedArray<BfIRValue, 4> irArgs;
irArgs.Add(strPtrVal);
bfModule->mBfIRBuilder->CreateCall(testInitMethod.mFunc, irArgs);
BfIRBlock testHeadBlock = bfModule->mBfIRBuilder->CreateBlock("testHead");
BfIRBlock testEndBlock = bfModule->mBfIRBuilder->CreateBlock("testEnd");
bfModule->mBfIRBuilder->CreateBr(testHeadBlock);
bfModule->mBfIRBuilder->AddBlock(testHeadBlock);
bfModule->mBfIRBuilder->SetInsertPoint(testHeadBlock);
irArgs.clear();
auto testVal = bfModule->mBfIRBuilder->CreateCall(testQueryMethod.mFunc, irArgs);
auto switchVal = bfModule->mBfIRBuilder->CreateSwitch(testVal, testEndBlock, (int)testMethods.size());
for (int methodIdx = 0; methodIdx < (int)testMethods.size(); methodIdx++)
{
auto methodInstance = testMethods[methodIdx].mMethodInstance;
String& methodName = testMethods[methodIdx].mName;
auto testBlock = bfModule->mBfIRBuilder->CreateBlock(StrFormat("test%d", methodIdx));
bfModule->mBfIRBuilder->AddSwitchCase(switchVal, bfModule->mBfIRBuilder->CreateConst(BfTypeCode_Int32, methodIdx), testBlock);
bfModule->mBfIRBuilder->AddBlock(testBlock);
bfModule->mBfIRBuilder->SetInsertPoint(testBlock);
auto moduleMethodInstance = bfModule->ReferenceExternalMethodInstance(methodInstance);
irArgs.clear();
if (methodInstance->GetParamCount() > 0)
{
if (methodInstance->GetParamKind(0) == BfParamKind_Params)
{
auto paramType = methodInstance->GetParamType(0);
auto paramTypeInst = paramType->ToTypeInstance();
BfTypedValue paramVal = BfTypedValue(bfModule->mBfIRBuilder->CreateAlloca(bfModule->mBfIRBuilder->MapTypeInst(paramTypeInst)), paramType);
bfModule->InitTypeInst(paramVal, NULL, false, BfIRValue());
//TODO: Assert 'length' var is at slot 1
auto arrayBits = bfModule->mBfIRBuilder->CreateBitCast(paramVal.mValue, bfModule->mBfIRBuilder->MapType(paramTypeInst->mBaseType));
auto addr = bfModule->mBfIRBuilder->CreateInBoundsGEP(arrayBits, 0, 1);
auto storeInst = bfModule->mBfIRBuilder->CreateAlignedStore(bfModule->GetConstValue(0), addr, 4);
irArgs.Add(paramVal.mValue);
}
else
{
for (int defaultIdx = 0; defaultIdx < (int)methodInstance->mDefaultValues.size(); defaultIdx++)
{
irArgs.Add(methodInstance->mDefaultValues[defaultIdx]);
}
}
}
BfExprEvaluator exprEvaluator(bfModule);
exprEvaluator.CreateCall(moduleMethodInstance.mMethodInstance, moduleMethodInstance.mFunc, false, irArgs);
bfModule->mBfIRBuilder->CreateBr(testHeadBlock);
}
bfModule->mBfIRBuilder->AddBlock(testEndBlock);
bfModule->mBfIRBuilder->SetInsertPoint(testEndBlock);
irArgs.clear();
bfModule->mBfIRBuilder->CreateCall(testFinishMethod.mFunc, irArgs);
retValue = bfModule->mBfIRBuilder->CreateConst(BfTypeCode_Int32, 0);
}
void BfCompiler::CreateVData(BfVDataModule* bfModule)
{
bool isHotCompile = IsHotCompile();
@ -842,81 +1053,9 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule)
vdataHashCtx.Mixin(bfModule->mProject->mVDataConfigHash);
struct _TestMethod
{
String mName;
BfMethodInstance* mMethodInstance;
};
Array<_TestMethod> testMethods;
Array<TestMethod> testMethods;
if (project->mTargetType == BfTargetType_BeefTest)
{
vdataHashCtx.Mixin(0xBEEF0001); // Marker
auto _CheckMethod = [&](BfTypeInstance* typeInstance, BfMethodInstance* methodInstance)
{
auto project = typeInstance->mTypeDef->mProject;
if (project->mTargetType != BfTargetType_BeefTest)
return;
if (project != bfModule->mProject)
return;
bool isTest = false;
if ((methodInstance->GetCustomAttributes() != NULL) &&
(methodInstance->GetCustomAttributes()->Contains(mTestAttributeTypeDef)))
isTest = true;
if (!isTest)
return;
if (!methodInstance->mMethodDef->mIsStatic)
{
bfModule->Fail(StrFormat("Method '%s' cannot be used for testing because it is not static", bfModule->MethodToString(methodInstance).c_str()),
methodInstance->mMethodDef->GetRefNode());
bfModule->mHadBuildError = true;
return;
}
if (methodInstance->GetParamCount() > 0)
{
if ((methodInstance->GetParamInitializer(0) == NULL) &&
(methodInstance->GetParamKind(0) != BfParamKind_Params))
{
bfModule->Fail(StrFormat("Method '%s' cannot be used for testing because it contains parameters without defaults", bfModule->MethodToString(methodInstance).c_str()),
methodInstance->mMethodDef->GetRefNode());
bfModule->mHadBuildError = true;
return;
}
}
BF_ASSERT(typeInstance->IsReified());
_TestMethod testMethod;
testMethod.mMethodInstance = methodInstance;
testMethods.Add(testMethod);
if (!bfModule->mProject->mUsedModules.Contains(typeInstance->mModule))
bfModule->mProject->mUsedModules.Add(typeInstance->mModule);
vdataHashCtx.Mixin(methodInstance->GetOwner()->mTypeId);
vdataHashCtx.Mixin(methodInstance->mMethodDef->mIdx);
};
for (auto type : mContext->mResolvedTypes)
{
auto typeInstance = type->ToTypeInstance();
if (typeInstance == NULL)
continue;
for (auto& methodInstanceGroup : typeInstance->mMethodInstanceGroups)
{
if (methodInstanceGroup.mDefault != NULL)
{
_CheckMethod(typeInstance, methodInstanceGroup.mDefault);
}
}
}
}
GetTestMethods(bfModule, testMethods, vdataHashCtx);
Array<BfType*> vdataTypeList;
std::multimap<String, BfTypeInstance*> sortedStaticInitMap;
@ -956,7 +1095,7 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule)
auto module = typeInst->mModule;
if (module == NULL)
continue;
if (type->IsInterface())
vdataHashCtx.Mixin(typeInst->mSlotNum);
@ -997,7 +1136,14 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule)
{
vdataHashCtx.Mixin(baseType->mTypeDef->mSignatureHash);
baseType = baseType->mBaseType;
}
}
if (module->mProject != bfModule->mProject)
{
if ((module->mProject != NULL) && (module->mProject->mTargetType == BfTargetType_BeefDynLib))
continue;
}
if (typeInst->mHasStaticInitMethod)
sortedStaticInitMap.insert(std::make_pair(bfModule->TypeToString(type), typeInst));
else if (typeInst->mHasStaticDtorMethod) // Only store types not already in the static init map
@ -1437,6 +1583,17 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule)
mainFuncType = bfModule->mBfIRBuilder->CreateFunctionType(int32Type, paramTypes, false);
mainFunc = bfModule->mBfIRBuilder->CreateFunction(mainFuncType, BfIRLinkageType_External, "main");
}
else if (project->mTargetType == BfTargetType_BeefDynLib)
{
SmallVector<BfIRType, 4> paramTypes;
paramTypes.push_back(nullPtrType); // hinstDLL
paramTypes.push_back(int32Type); // fdwReason
paramTypes.push_back(nullPtrType); // lpvReserved
mainFuncType = bfModule->mBfIRBuilder->CreateFunctionType(int32Type, paramTypes, false);
mainFunc = bfModule->mBfIRBuilder->CreateFunction(mainFuncType, BfIRLinkageType_External, "DllMain");
if (mSystem->mPtrSize == 4)
bfModule->mBfIRBuilder->SetFuncCallingConv(mainFunc, BfIRCallingConv_StdCall);
}
else if (project->mTargetType == BfTargetType_BeefWindowsApplication)
{
SmallVector<BfIRType, 4> paramTypes;
@ -1478,6 +1635,17 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule)
}
#endif
BfIRBlock initSkipBlock;
if (project->mTargetType == BfTargetType_BeefDynLib)
{
auto initBlock = bfModule->mBfIRBuilder->CreateBlock("doInit", false);
initSkipBlock = bfModule->mBfIRBuilder->CreateBlock("skipInit", false);
auto cmpResult = bfModule->mBfIRBuilder->CreateCmpEQ(bfModule->mBfIRBuilder->GetArgument(1), bfModule->mBfIRBuilder->CreateConst(BfTypeCode_Int32, 1));
bfModule->mBfIRBuilder->CreateCondBr(cmpResult, initBlock, initSkipBlock);
bfModule->mBfIRBuilder->AddBlock(initBlock);
bfModule->mBfIRBuilder->SetInsertPoint(initBlock);
}
// Do the LoadLibrary calls below priority 100
bool didSharedLibLoad = false;
auto _CheckSharedLibLoad = [&]()
@ -1516,6 +1684,13 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule)
_CheckSharedLibLoad();
if (initSkipBlock)
{
bfModule->mBfIRBuilder->CreateBr(initSkipBlock);
bfModule->mBfIRBuilder->AddBlock(initSkipBlock);
bfModule->mBfIRBuilder->SetInsertPoint(initSkipBlock);
}
BfIRValue retValue;
if ((project->mTargetType == BfTargetType_BeefConsoleApplication) || (project->mTargetType == BfTargetType_BeefWindowsApplication))
{
@ -1655,142 +1830,24 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule)
if (!hadRet)
retValue = bfModule->GetConstValue32(0);
}
}
else if (project->mTargetType == BfTargetType_BeefDynLib)
{
retValue = bfModule->GetConstValue32(1);
}
if (project->mTargetType == BfTargetType_BeefTest)
EmitTestMethod(bfModule, testMethods, retValue);
BfIRBlock deinitSkipBlock;
if (project->mTargetType == BfTargetType_BeefDynLib)
{
for (auto& testMethod : testMethods)
{
auto methodInstance = testMethod.mMethodInstance;
auto typeInstance = methodInstance->GetOwner();
testMethod.mName += bfModule->TypeToString(typeInstance);
testMethod.mName += ".";
testMethod.mName += methodInstance->mMethodDef->mName;
testMethod.mName += "\t";
auto testAttribute = methodInstance->GetCustomAttributes()->Get(mTestAttributeTypeDef);
for (auto& field : testAttribute->mSetField)
{
auto constant = typeInstance->mConstHolder->GetConstant(field.mParam.mValue);
if ((constant != NULL) && (constant->mTypeCode == BfTypeCode_Boolean) && (constant->mBool))
{
BfFieldDef* fieldDef = field.mFieldRef;
if (fieldDef->mName == "ShouldFail")
{
testMethod.mName += "Sf";
}
else if (fieldDef->mName == "Profile")
{
testMethod.mName += "Pr";
}
else if (fieldDef->mName == "Ignore")
{
testMethod.mName += "Ig";
}
}
}
bfModule->UpdateSrcPos(methodInstance->mMethodDef->GetRefNode(), (BfSrcPosFlags)(BfSrcPosFlag_NoSetDebugLoc | BfSrcPosFlag_Force));
testMethod.mName += StrFormat("\t%s\t%d\t%d", bfModule->mCurFilePosition.mFileInstance->mParser->mFileName.c_str(), bfModule->mCurFilePosition.mCurLine, bfModule->mCurFilePosition.mCurColumn);
}
std::stable_sort(testMethods.begin(), testMethods.end(),
[](const _TestMethod& lhs, const _TestMethod& rhs)
{
return lhs.mName < rhs.mName;
});
String methodData;
for (int methodIdx = 0; methodIdx < (int)testMethods.size(); methodIdx++)
{
String& methodName = testMethods[methodIdx].mName;
if (!methodData.IsEmpty())
methodData += "\n";
methodData += methodName;
}
//////////////////////////////////////////////////////////////////////////
auto testInitMethod = bfModule->GetInternalMethod("Test_Init");
auto testQueryMethod = bfModule->GetInternalMethod("Test_Query");
auto testFinishMethod = bfModule->GetInternalMethod("Test_Finish");
auto char8PtrType = bfModule->CreatePointerType(bfModule->GetPrimitiveType(BfTypeCode_Char8));
BfIRType strCharType = bfModule->mBfIRBuilder->GetSizedArrayType(bfModule->mBfIRBuilder->GetPrimitiveType(BfTypeCode_Char8), (int)methodData.length() + 1);
BfIRValue strConstant = bfModule->mBfIRBuilder->CreateConstString(methodData);
BfIRValue gv = bfModule->mBfIRBuilder->CreateGlobalVariable(strCharType,
true, BfIRLinkageType_External,
strConstant, "__bfTestData");
BfIRValue strPtrVal = bfModule->mBfIRBuilder->CreateBitCast(gv, bfModule->mBfIRBuilder->MapType(char8PtrType));
SizedArray<BfIRValue, 4> irArgs;
irArgs.Add(strPtrVal);
bfModule->mBfIRBuilder->CreateCall(testInitMethod.mFunc, irArgs);
BfIRBlock testHeadBlock = bfModule->mBfIRBuilder->CreateBlock("testHead");
BfIRBlock testEndBlock = bfModule->mBfIRBuilder->CreateBlock("testEnd");
bfModule->mBfIRBuilder->CreateBr(testHeadBlock);
bfModule->mBfIRBuilder->AddBlock(testHeadBlock);
bfModule->mBfIRBuilder->SetInsertPoint(testHeadBlock);
irArgs.clear();
auto testVal = bfModule->mBfIRBuilder->CreateCall(testQueryMethod.mFunc, irArgs);
auto switchVal = bfModule->mBfIRBuilder->CreateSwitch(testVal, testEndBlock, (int)testMethods.size());
for (int methodIdx = 0; methodIdx < (int)testMethods.size(); methodIdx++)
{
auto methodInstance = testMethods[methodIdx].mMethodInstance;
String& methodName = testMethods[methodIdx].mName;
auto testBlock = bfModule->mBfIRBuilder->CreateBlock(StrFormat("test%d", methodIdx));
bfModule->mBfIRBuilder->AddSwitchCase(switchVal, bfModule->mBfIRBuilder->CreateConst(BfTypeCode_Int32, methodIdx), testBlock);
bfModule->mBfIRBuilder->AddBlock(testBlock);
bfModule->mBfIRBuilder->SetInsertPoint(testBlock);
auto moduleMethodInstance = bfModule->ReferenceExternalMethodInstance(methodInstance);
irArgs.clear();
if (methodInstance->GetParamCount() > 0)
{
if (methodInstance->GetParamKind(0) == BfParamKind_Params)
{
auto paramType = methodInstance->GetParamType(0);
auto paramTypeInst = paramType->ToTypeInstance();
BfTypedValue paramVal = BfTypedValue(bfModule->mBfIRBuilder->CreateAlloca(bfModule->mBfIRBuilder->MapTypeInst(paramTypeInst)), paramType);
bfModule->InitTypeInst(paramVal, NULL, false, BfIRValue());
//TODO: Assert 'length' var is at slot 1
auto arrayBits = bfModule->mBfIRBuilder->CreateBitCast(paramVal.mValue, bfModule->mBfIRBuilder->MapType(paramTypeInst->mBaseType));
auto addr = bfModule->mBfIRBuilder->CreateInBoundsGEP(arrayBits, 0, 1);
auto storeInst = bfModule->mBfIRBuilder->CreateAlignedStore(bfModule->GetConstValue(0), addr, 4);
irArgs.Add(paramVal.mValue);
}
else
{
for (int defaultIdx = 0; defaultIdx < (int)methodInstance->mDefaultValues.size(); defaultIdx++)
{
irArgs.Add(methodInstance->mDefaultValues[defaultIdx]);
}
}
}
BfExprEvaluator exprEvaluator(bfModule);
exprEvaluator.CreateCall(moduleMethodInstance.mMethodInstance, moduleMethodInstance.mFunc, false, irArgs);
bfModule->mBfIRBuilder->CreateBr(testHeadBlock);
}
bfModule->mBfIRBuilder->AddBlock(testEndBlock);
bfModule->mBfIRBuilder->SetInsertPoint(testEndBlock);
irArgs.clear();
bfModule->mBfIRBuilder->CreateCall(testFinishMethod.mFunc, irArgs);
retValue = bfModule->mBfIRBuilder->CreateConst(BfTypeCode_Int32, 0);
auto deinitBlock = bfModule->mBfIRBuilder->CreateBlock("doDeinit", false);
deinitSkipBlock = bfModule->mBfIRBuilder->CreateBlock("skipDeinit", false);
auto cmpResult = bfModule->mBfIRBuilder->CreateCmpEQ(bfModule->mBfIRBuilder->GetArgument(1), bfModule->mBfIRBuilder->CreateConst(BfTypeCode_Int32, 0));
bfModule->mBfIRBuilder->CreateCondBr(cmpResult, deinitBlock, deinitSkipBlock);
bfModule->mBfIRBuilder->AddBlock(deinitBlock);
bfModule->mBfIRBuilder->SetInsertPoint(deinitBlock);
}
bfModule->mBfIRBuilder->CreateCall(dtorFunc, SizedArray<BfIRValue, 0>());
@ -1801,6 +1858,13 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule)
bfModule->mBfIRBuilder->CreateCall(shutdownMethod.mFunc, SizedArray<BfIRValue, 0>());
}
if (deinitSkipBlock)
{
bfModule->mBfIRBuilder->CreateBr(deinitSkipBlock);
bfModule->mBfIRBuilder->AddBlock(deinitSkipBlock);
bfModule->mBfIRBuilder->SetInsertPoint(deinitSkipBlock);
}
if (retValue)
bfModule->mBfIRBuilder->CreateRet(retValue);
else
@ -5784,6 +5848,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
}
if ((bfProject->mTargetType != BfTargetType_BeefConsoleApplication) && (bfProject->mTargetType != BfTargetType_BeefWindowsApplication) &&
(bfProject->mTargetType != BfTargetType_BeefDynLib) &&
(bfProject->mTargetType != BfTargetType_C_ConsoleApplication) && (bfProject->mTargetType != BfTargetType_C_WindowsApplication) &&
(bfProject->mTargetType != BfTargetType_BeefTest))
continue;
@ -7866,6 +7931,11 @@ BF_EXPORT const char* BF_CALLTYPE BfCompiler_GetUsedOutputFileNames(BfCompiler*
{
if (!bfProject->ContainsReference(project))
canReference = false;
if (bfProject != project)
{
if (project->mTargetType == BfTargetType_BeefDynLib)
canReference = false;
}
}
if (!canReference)
continue;