diff --git a/BeefySysLib/util/String.h b/BeefySysLib/util/String.h index 11064aec..dce187f2 100644 --- a/BeefySysLib/util/String.h +++ b/BeefySysLib/util/String.h @@ -1210,3 +1210,4 @@ namespace std } }; } + diff --git a/IDE/src/IDEApp.bf b/IDE/src/IDEApp.bf index 98ba757c..2b6d7d7d 100644 --- a/IDE/src/IDEApp.bf +++ b/IDE/src/IDEApp.bf @@ -1816,6 +1816,9 @@ namespace IDE bool SaveWorkspace() { + if (mWorkspace.mNeedsCreate) + mWorkspace.mNeedsCreate = false; + if (!mWorkspace.IsSingleFileWorkspace) { #if !CLI @@ -9376,6 +9379,11 @@ namespace IDE public void AutoGenerateStartupCode(Project project) { + // We have to save this to ensure any new project is actually created. Maybe overkill, + // but best to stay conservative since this path won't be heavily tested + if (!SaveAll()) + return; + String namespaceName = scope .(); String className = scope .(); String startupStr = project.mBeefGlobalOptions.mStartupObject; @@ -9411,6 +9419,8 @@ namespace IDE String srcPath = scope .(); project.mRootFolder.GetFullImportPath(srcPath); + Directory.CreateDirectory(srcPath).IgnoreError(); + srcPath.Append(Path.DirectorySeparatorChar); srcPath.Append("Program.bf"); diff --git a/IDEHelper/Backend/BeMCContext.cpp b/IDEHelper/Backend/BeMCContext.cpp index ab816027..b0af9b76 100644 --- a/IDEHelper/Backend/BeMCContext.cpp +++ b/IDEHelper/Backend/BeMCContext.cpp @@ -14742,6 +14742,7 @@ void BeMCContext::Generate(BeFunction* function) //mDbgPreferredRegs[8] = X64Reg_RAX; mDebugging = function->mName == //"?TestPrimitives@Nullable@Tests@bf@@SAXXZ" + "?Hey@Blurg@bf@@SAHXZ"; //"?Main@Program@bf@@CAHPEAV?$Array1@PEAVString@System@bf@@@System@2@@Z"; diff --git a/IDEHelper/COFF.cpp b/IDEHelper/COFF.cpp index 334f1473..ae2c4799 100644 --- a/IDEHelper/COFF.cpp +++ b/IDEHelper/COFF.cpp @@ -6113,9 +6113,19 @@ addr_target COFF::EvaluateLocation(DbgSubprogram* dwSubprogram, const uint8* loc else result = stackFrame->mRegisters.mIntRegsArray[X64Reg_RBP] + defRangeFPRel.offFramePointer; #else - if (dwSubprogram->mLocalBaseReg == DbgSubprogram::LocalBaseRegKind_ESP) - //result = stackFrame->mRegisters.mIntRegsArray[X86Reg_ESP] + BF_ALIGN(dwSubprogram->mFrameBaseLen, 16) + defRangeFPRel.offFramePointer; - result = stackFrame->mRegisters.mIntRegsArray[X86Reg_ESP] + dwSubprogram->mFrameBaseLen + defRangeFPRel.offFramePointer; + if (dwSubprogram->mLocalBaseReg == DbgSubprogram::LocalBaseRegKind_VFRAME) + { + if (defRangeFPRel.offFramePointer > 0) + { + // Note that a positive offFramePointer always refers to params, and param fp reg is always EBP-relative. + // If this is not true in some cases then we need to actually pass in knowledge of whether is loc data is + // from a param or not, and we have to store the param fp reg just like the local fp reg (mLocalBaseReg) + result = stackFrame->mRegisters.mIntRegsArray[X86Reg_EBP] + defRangeFPRel.offFramePointer; + } + else + //result = stackFrame->mRegisters.mIntRegsArray[X86Reg_EBP] + defRangeFPRel.offFramePointer - 4; + result = ((stackFrame->mRegisters.mIntRegsArray[X86Reg_ESP] + dwSubprogram->mFrameBaseLen) & ~7) + defRangeFPRel.offFramePointer; + } else if (dwSubprogram->mLocalBaseReg == DbgSubprogram::LocalBaseRegKind_EBX) result = stackFrame->mRegisters.mIntRegsArray[X86Reg_EBX] + defRangeFPRel.offFramePointer; else diff --git a/IDEHelper/Compiler/BfContext.cpp b/IDEHelper/Compiler/BfContext.cpp index f3aa060d..e34a8fee 100644 --- a/IDEHelper/Compiler/BfContext.cpp +++ b/IDEHelper/Compiler/BfContext.cpp @@ -780,7 +780,7 @@ void BfContext::ValidateDependencies() while (itr != mResolvedTypes.end()) { auto type = itr.mCurEntry->mValue; - if (type->IsGenericTypeInstance()) + if ((type->IsGenericTypeInstance()) && (type->mDefineState > BfTypeDefineState_Undefined)) { // We can't contain deleted generic arguments without being deleted ourselves BfGenericTypeInstance* genericType = (BfGenericTypeInstance*)type; diff --git a/IDEHelper/Compiler/BfExprEvaluator.cpp b/IDEHelper/Compiler/BfExprEvaluator.cpp index 0a9ed68f..2e51943c 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.cpp +++ b/IDEHelper/Compiler/BfExprEvaluator.cpp @@ -18197,4 +18197,3 @@ void BfExprEvaluator::Visit(BfBinaryOperatorExpression* binOpExpr) PerformBinaryOperation(binOpExpr->mLeft, binOpExpr->mRight, binOpExpr->mOp, binOpExpr->mOpToken, BfBinOpFlag_None); } -// \ No newline at end of file diff --git a/IDEHelper/Compiler/BfIRBuilder.cpp b/IDEHelper/Compiler/BfIRBuilder.cpp index 2fadbe40..4738e082 100644 --- a/IDEHelper/Compiler/BfIRBuilder.cpp +++ b/IDEHelper/Compiler/BfIRBuilder.cpp @@ -995,6 +995,7 @@ BfIRBuilder::BfIRBuilder(BfModule* module) : BfIRConstHolder(module) mActiveFunctionHasBody = false; mHasStarted = false; mCmdCount = 0; + mIsBeefBackend = false; } bool BfIRBuilder::HasExports() @@ -1374,7 +1375,9 @@ void BfIRBuilder::Start(const StringImpl& moduleName, int ptrSize, bool isOptimi } void BfIRBuilder::SetBackend(bool isBeefBackend) -{ +{ + mIsBeefBackend = isBeefBackend; + BF_ASSERT(mIRCodeGen == NULL); if (mDbgVerifyCodeGen) { @@ -1881,13 +1884,14 @@ public: void BfIRBuilder::CreateTypeDeclaration(BfType* type, bool forceDefine) { bool wantDIData = DbgHasInfo() && (!type->IsUnspecializedType()); - - // Types that don't have a proper 'defining module' need to be defined in every module they are used - bool isDefiningModule = (type->GetModule() == mModule) || (type->IsFunction()); - bool wantsForwardDecl = !isDefiningModule && !forceDefine; - + + // Types that don't have a proper 'defining module' need to be defined in every module they are used + bool wantsDIForwardDecl = (type->GetModule() != mModule) && (!type->IsFunction()); + // Forward declarations of valuetypes doesn't work in LLVM backend for Win32..... +// if ((!mIsBeefBackend) && (type->IsValueType())) +// wantsDIForwardDecl = false; if (mModule->mExtensionCount != 0) - wantsForwardDecl = true; + wantsDIForwardDecl = true; bool isPrimEnum = (type->IsEnum()) && (type->IsTypedPrimitive()); @@ -2144,7 +2148,7 @@ void BfIRBuilder::CreateTypeDeclaration(BfType* type, bool forceDefine) else curDIScope = CreateNamespaceScope(checkType, fileDIScope); String typeName = GetDebugTypeName(typeInstance, false); - if (wantsForwardDecl) + if (wantsDIForwardDecl) { if (type->IsInterface()) { @@ -2169,10 +2173,14 @@ void BfIRBuilder::CreateTypeDeclaration(BfType* type, bool forceDefine) int flags = 0; diForwardDecl = DbgCreateReplaceableCompositeType(llvm::dwarf::DW_TAG_structure_type, typeName, curDIScope, fileDIScope, 0, (int64)BF_ALIGN(typeInstance->mInstSize, typeInstance->mInstAlign) * 8, (int64)typeInstance->mInstAlign * 8, flags); + + mDITemporaryTypes.push_back(typeInstance); - - - mDITemporaryTypes.push_back(typeInstance); + if (!type->IsUnspecializedType()) + { + BF_ASSERT(!mDeferredDbgTypeDefs.Contains(type)); + mDeferredDbgTypeDefs.Add(type); + } } DbgSetInstType(type, diForwardDecl); @@ -2257,8 +2265,10 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type) bool isGlobalContainer = typeDef->IsGlobalsContainer(); - bool isDefiningModule = true; + bool isDefiningModule = ((type->GetModule() == mModule) || (type->IsFunction())); auto diForwardDecl = DbgGetTypeInst(typeInstance); + + //BF_ASSERT(WantsDbgDefinition(type)); llvm::SmallVector diFieldTypes; @@ -2330,7 +2340,7 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type) { if (fieldDef->mIsConst) { - if (wantDIData) + if (isDefiningModule) { if ((isPayloadEnum) && (fieldDef->IsEnumCaseEntry())) { @@ -2464,7 +2474,7 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type) } else if (fieldDef->mIsStatic) { - if (wantDIData) + if (isDefiningModule) { int flags = 0; auto memberType = DbgCreateStaticMemberType(diForwardDecl, fieldDef->mName, fileDIScope, 0, @@ -2523,8 +2533,11 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type) if (type->IsBoxed()) wantsMethods = false; + if (!isDefiningModule) + wantsMethods = false; + if (wantsMethods) - { + { for (int methodIdx = 0; methodIdx < (int)typeInstance->mMethodInstanceGroups.size(); methodIdx++) { auto& methodGroup = typeInstance->mMethodInstanceGroups[methodIdx]; @@ -2747,6 +2760,18 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type) } } +bool BfIRBuilder::WantsDbgDefinition(BfType* type) +{ + if ((type->GetModule() == mModule) || (type->IsFunction())) + return true; + + // Forward declarations of valuetypes doesn't work in LLVM backend +// if ((!mIsBeefBackend) && (type->IsValueType())) +// return true; + + return false; +} + void BfIRBuilder::CreateTypeDefinition(BfType* type, bool forceDefine) { // This PopulateType is generally NOT needed, but here is a scenario in which it is: @@ -2757,10 +2782,10 @@ void BfIRBuilder::CreateTypeDefinition(BfType* type, bool forceDefine) if (type->IsDataIncomplete()) mModule->PopulateType(type, BfPopulateType_Data); - bool isDefiningModule = (type->GetModule() == mModule) || (type->IsFunction()); + bool isDefiningModule = ((type->GetModule() == mModule) || (type->IsFunction())); if (mModule->mExtensionCount != 0) isDefiningModule = false; - + // if (mModule->mModuleName == "vdata") // isDefiningModule = true; @@ -2771,8 +2796,7 @@ void BfIRBuilder::CreateTypeDefinition(BfType* type, bool forceDefine) { DbgSetTypeSize(DbgGetType(type), BF_ALIGN(type->mSize, type->mAlign) * 8, type->mAlign * 8); } - - bool wantsForwardDecl = !isDefiningModule && !forceDefine; + bool isPrimEnum = (type->IsEnum()) && (type->IsTypedPrimitive()); auto typeInstance = type->ToTypeInstance(); @@ -2780,13 +2804,7 @@ void BfIRBuilder::CreateTypeDefinition(BfType* type, bool forceDefine) return; auto typeDef = typeInstance->mTypeDef; - if (DbgHasInfo() && (!type->IsUnspecializedType()) && (!wantsForwardDecl)) - { - BF_ASSERT(!mDeferredDbgTypeDefs.Contains(type)); - mDeferredDbgTypeDefs.Add(type); - } - - + #ifdef BFIR_RENTRY_CHECK ReEntryCheck reEntryCheck(&mDefReentrySet, type); #endif @@ -3007,12 +3025,17 @@ void BfIRBuilder::CreateTypeDefinition(BfType* type, bool forceDefine) void BfIRBuilder::ReplaceDITemporaryTypes() { - for (auto typeInstance : mDITemporaryTypes) + //for (auto typeInstance : mDITemporaryTypes) + for (int i = 0; i < (int)mDITemporaryTypes.size(); i++) { - if (mTypeMap[typeInstance] == BfIRPopulateType_Full) + auto typeInstance = mDITemporaryTypes[i]; + auto populateType = mTypeMap[typeInstance]; + if (populateType == BfIRPopulateType_Full) continue; + mTypeMap[typeInstance] = BfIRPopulateType_Eventually_Full; CreateTypeDefinition(typeInstance, false); + mTypeMap[typeInstance] = BfIRPopulateType_Full; } mDITemporaryTypes.Clear(); } @@ -4510,8 +4533,9 @@ void BfIRBuilder::DbgFinalize() { while ((!mDeferredDbgTypeDefs.IsEmpty()) || (!mDITemporaryTypes.IsEmpty())) { - for (auto deferredType : mDeferredDbgTypeDefs) - CreateDbgTypeDefinition(deferredType); + //for (auto deferredType : mDeferredDbgTypeDefs) + for (int i = 0; i < (int)mDeferredDbgTypeDefs.size(); i++) + CreateDbgTypeDefinition(mDeferredDbgTypeDefs[i]); mDeferredDbgTypeDefs.Clear(); ReplaceDITemporaryTypes(); diff --git a/IDEHelper/Compiler/BfIRBuilder.h b/IDEHelper/Compiler/BfIRBuilder.h index ef63d58c..02da4ca0 100644 --- a/IDEHelper/Compiler/BfIRBuilder.h +++ b/IDEHelper/Compiler/BfIRBuilder.h @@ -849,6 +849,7 @@ public: bool mDbgVerifyCodeGen; int mCurFakeId; bool mHasGlobalDefs; + bool mIsBeefBackend; int mNumFunctionsWithBodies; int mBlockCount; bool mHasStarted; @@ -938,6 +939,7 @@ public: BfIRMDNode CreateNamespaceScope(BfType* type, BfIRMDNode fileDIScope); String GetDebugTypeName(BfTypeInstance* typeInstance, bool includeOuterTypeName); void CreateDbgTypeDefinition(BfType* type); + bool WantsDbgDefinition(BfType * type); void CreateTypeDeclaration(BfType* type, bool forceDefine); void CreateTypeDefinition(BfType* type, bool forceDefine); void ReplaceDITemporaryTypes(); diff --git a/IDEHelper/DbgModule.cpp b/IDEHelper/DbgModule.cpp index c0214263..5b3cba53 100644 --- a/IDEHelper/DbgModule.cpp +++ b/IDEHelper/DbgModule.cpp @@ -7265,4 +7265,4 @@ DbgType* DbgModule::GetSizedArrayType(DbgType * elementType, int count) *sizedArrayTypePtr = sizedArrayType; } return *sizedArrayTypePtr; -} \ No newline at end of file +} diff --git a/IDEHelper/DbgModule.h b/IDEHelper/DbgModule.h index 837ce40d..930a1e02 100644 --- a/IDEHelper/DbgModule.h +++ b/IDEHelper/DbgModule.h @@ -351,7 +351,7 @@ public: enum LocalBaseRegKind : uint8 { LocalBaseRegKind_None, - LocalBaseRegKind_ESP, + LocalBaseRegKind_VFRAME, LocalBaseRegKind_EBP, LocalBaseRegKind_EBX }; diff --git a/IDEHelper/DebugTarget.cpp b/IDEHelper/DebugTarget.cpp index c450c08f..15f0d31d 100644 --- a/IDEHelper/DebugTarget.cpp +++ b/IDEHelper/DebugTarget.cpp @@ -2150,8 +2150,8 @@ int DebugTarget::GetFrameBaseRegister(DbgSubprogram* dwSubprogram) } #ifdef BF_DBG_32 - if (dwSubprogram->mLocalBaseReg == DbgSubprogram::LocalBaseRegKind_ESP) - return X86Reg_ESP; + if (dwSubprogram->mLocalBaseReg == DbgSubprogram::LocalBaseRegKind_VFRAME) + return X86Reg_EBP; else if (dwSubprogram->mLocalBaseReg == DbgSubprogram::LocalBaseRegKind_EBX) return X86Reg_EBX; return X86Reg_EBP;