diff --git a/IDE/Tests/Test1/scripts/Mixins.txt b/IDE/Tests/Test1/scripts/Mixins.txt index b9d97849..34b07812 100644 --- a/IDE/Tests/Test1/scripts/Mixins.txt +++ b/IDE/Tests/Test1/scripts/Mixins.txt @@ -25,4 +25,14 @@ StepOver() AssertLineContains("a + 20000") StepOver() -AssertLineContains("a + 30000") \ No newline at end of file +AssertLineContains("a + 30000") + +StepOut() +StepOver() +StepInto() +AssertEvalEquals("mStr.mLength", "6") +AssertLineContains("a + mStr.Length") +StepOut() +StepOver() +StepInto() +AssertLineContains("a + b + mStr.Length") \ No newline at end of file diff --git a/IDE/Tests/Test1/src/Mixins.bf b/IDE/Tests/Test1/src/Mixins.bf index dc16ca25..64660457 100644 --- a/IDE/Tests/Test1/src/Mixins.bf +++ b/IDE/Tests/Test1/src/Mixins.bf @@ -8,7 +8,17 @@ namespace IDETest { class ClassA { - public String mStr; + public String mStr ~ delete _; + + public mixin Zorf(int a) + { + a + mStr.Length + } + + public mixin Zorf(int a, int b) + { + a + b + mStr.Length + } } public static mixin MixA(int a) @@ -40,6 +50,10 @@ namespace IDETest DeleteAndNullify!(ca.mStr); int a = 123; MixC!(1); + + ca.mStr = new String("Zorpie"); + int val = ca.Zorf!(100); + val = ca.Zorf!(200, 300); } } } diff --git a/IDEHelper/COFF.cpp b/IDEHelper/COFF.cpp index 58dcb23d..652061e5 100644 --- a/IDEHelper/COFF.cpp +++ b/IDEHelper/COFF.cpp @@ -4325,6 +4325,27 @@ void COFF::FixupInlinee(DbgSubprogram* dbgSubprogram, uint32 ipiTag) lfMFuncId* funcData = (lfMFuncId*)dataStart; CvParseMethod(NULL, NULL, funcData->type, false, dbgSubprogram); dbgSubprogram->mName = (const char*)funcData->name; + + if (dbgSubprogram->mName != NULL) + { + for (const char* cPtr = dbgSubprogram->mName + 1; true; cPtr++) + { + char c = *cPtr; + if (c == 0) + break; + // For removing the mangled name from the mixins + if (c == '?') + { + int nameLen = cPtr - dbgSubprogram->mName; + char* dupStr = (char*)mAlloc.AllocBytes(nameLen + 1); + memcpy(dupStr, dbgSubprogram->mName, nameLen); + dupStr[nameLen] = 0; + dbgSubprogram->mName = dupStr; + break; + } + } + } + FixSubprogramName(dbgSubprogram); dbgSubprogram->mParentType = CvGetType(funcData->parentType); diff --git a/IDEHelper/Compiler/BfExprEvaluator.cpp b/IDEHelper/Compiler/BfExprEvaluator.cpp index f41aba32..b47c11ac 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.cpp +++ b/IDEHelper/Compiler/BfExprEvaluator.cpp @@ -13513,7 +13513,7 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo if (wantsDIData) { - BfIRMDNode diFuncType = mModule->mBfIRBuilder->DbgCreateSubroutineType(SizedArray()); + BfIRMDNode diFuncType = mModule->mBfIRBuilder->DbgCreateSubroutineType(methodInstance); //int defLine = mModule->mCurFilePosition.mCurLine; @@ -13527,7 +13527,10 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo auto diParentType = mModule->mBfIRBuilder->DbgGetTypeInst(methodInstance->GetOwner()); if (!mModule->mBfIRBuilder->mIgnoreWrites) { - curMethodState->mCurScope->mDIScope = mModule->mBfIRBuilder->DbgCreateFunction(diParentType, methodDef->mName + "!", "", mModule->mCurFilePosition.mFileInstance->mDIFile, + String methodName = methodDef->mName; + methodName += "!"; + BfMangler::Mangle(methodName, mModule->mCompiler->GetMangleKind(), methodInstance); + curMethodState->mCurScope->mDIScope = mModule->mBfIRBuilder->DbgCreateFunction(diParentType, methodName, "", mModule->mCurFilePosition.mFileInstance->mDIFile, defLine + 1, diFuncType, false, true, mModule->mCurFilePosition.mCurLine + 1, flags, false, BfIRValue()); scopeData.mAltDIFile = mModule->mCurFilePosition.mFileInstance->mDIFile; } @@ -13710,66 +13713,89 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo newLocalVar->mParamIdx = -3; }; - + argExprEvaluatorItr = argExprEvaluators.begin(); - for (int argIdx = 0; argIdx < (int)explicitParamCount; argIdx++) + for (int argIdx = methodDef->mIsStatic ? 0 : -1; argIdx < (int)explicitParamCount; argIdx++) { int paramIdx = argIdx; - auto exprEvaluator = *argExprEvaluatorItr; - auto paramDef = methodDef->mParams[paramIdx]; - auto arg = &args[argIdx]; + auto exprEvaluator = *argExprEvaluatorItr; - if (!arg->mTypedValue) - { - auto wantType = methodInstance->GetParamType(paramIdx); - if (wantType->IsVar()) - wantType = mModule->mContext->mBfObjectType; - arg->mTypedValue = mModule->GetDefaultTypedValue(wantType); - } + BfTypedValue argValue; BfLocalVariable* localVar = new BfLocalVariable(); - localVar->mName = paramDef->mName; - localVar->mResolvedType = arg->mTypedValue.mType; - if (arg->mTypedValue.mType->IsRef()) + + if (argIdx == -1) { - auto refType = (BfRefType*)localVar->mResolvedType; - localVar->mAddr = mModule->LoadValue(arg->mTypedValue).mValue; - localVar->mResolvedType = arg->mTypedValue.mType->GetUnderlyingType(); - localVar->mIsAssigned = refType->mRefKind != BfRefType::RefKind_Out; + argValue = target; + localVar->mName = "this"; + localVar->mIsThis = true; + localVar->mIsAssigned = true; } - else if (arg->mTypedValue.IsAddr()) - localVar->mAddr = arg->mTypedValue.mValue; else { - if (!arg->mTypedValue.mValue) + auto arg = &args[argIdx]; + auto paramDef = methodDef->mParams[paramIdx]; + + localVar->mName = paramDef->mName; + + if (!arg->mTypedValue) + { + auto wantType = methodInstance->GetParamType(paramIdx); + if (wantType->IsVar()) + wantType = mModule->mContext->mBfObjectType; + arg->mTypedValue = mModule->GetDefaultTypedValue(wantType); + } + argValue = arg->mTypedValue; + } + + localVar->mResolvedType = argValue.mType; + if (argValue.mType->IsRef()) + { + auto refType = (BfRefType*)localVar->mResolvedType; + localVar->mAddr = mModule->LoadValue(argValue).mValue; + localVar->mResolvedType = argValue.mType->GetUnderlyingType(); + localVar->mIsAssigned = refType->mRefKind != BfRefType::RefKind_Out; + } + else if (argValue.IsAddr()) + localVar->mAddr = argValue.mValue; + else + { + if (!argValue.mValue) { // Untyped value } - else if (arg->mTypedValue.mValue.IsConst()) + else if (argValue.mValue.IsConst()) { - localVar->mConstValue = arg->mTypedValue.mValue; + localVar->mConstValue = argValue.mValue; } - else if (arg->mTypedValue.IsSplat()) + else if (argValue.IsSplat()) { - localVar->mValue = arg->mTypedValue.mValue; + localVar->mValue = argValue.mValue; localVar->mIsSplat = true; } else { - if (arg->mTypedValue.IsAddr()) - localVar->mAddr = arg->mTypedValue.mValue; + if (argValue.IsAddr()) + localVar->mAddr = argValue.mValue; else - localVar->mValue = arg->mTypedValue.mValue; + localVar->mValue = argValue.mValue; } - localVar->mIsReadOnly = arg->mTypedValue.IsReadOnly(); + localVar->mIsReadOnly = argValue.IsReadOnly(); } - _AddLocalVariable(localVar, exprEvaluator); - - endLocalIdx++; - ++argExprEvaluatorItr; + if (argIdx == -1) + { + _AddLocalVariable(localVar, NULL); + } + else + { + _AddLocalVariable(localVar, exprEvaluator); + + endLocalIdx++; + ++argExprEvaluatorItr; + } } if (auto blockBody = BfNodeDynCast(methodDef->mBody)) diff --git a/IDEHelper/Compiler/BfIRBuilder.cpp b/IDEHelper/Compiler/BfIRBuilder.cpp index 9c329e19..93acd878 100644 --- a/IDEHelper/Compiler/BfIRBuilder.cpp +++ b/IDEHelper/Compiler/BfIRBuilder.cpp @@ -2693,38 +2693,7 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type) if (methodDef->mIsOverride) continue; - llvm::SmallVector diParams; - diParams.push_back(DbgGetType(methodInstance->mReturnType)); - - BfType* thisType = NULL; - if (!methodDef->mIsStatic) - { - BfType* thisType; - thisType = typeInstance; - if (!thisType->IsValuelessType()) - { - BfType* thisPtrType = thisType; - auto diType = DbgGetType(thisPtrType); - if ((thisType->IsComposite()) && (!methodInstance->GetParamIsSplat(-1))) - { - diType = DbgCreatePointerType(diType); - diType = DbgCreateArtificialType(diType); - } - diParams.push_back(diType); - } - } - - for (int paramIdx = 0; paramIdx < methodInstance->GetParamCount(); paramIdx++) - { - bool isParamSkipped = methodInstance->IsParamSkipped(paramIdx); - if (!isParamSkipped) - { - auto resolvedType = methodInstance->GetParamType(paramIdx); - diParams.push_back(DbgGetType(resolvedType)); - } - } - - BfIRMDNode diFuncType = DbgCreateSubroutineType(diParams); + BfIRMDNode diFuncType = DbgCreateSubroutineType(methodInstance); int defLine = 0; @@ -5004,6 +4973,45 @@ BfIRMDNode BfIRBuilder::DbgCreateParameterVariable(BfIRMDNode scope, const Strin return retVal; } +BfIRMDNode BfIRBuilder::DbgCreateSubroutineType(BfMethodInstance* methodInstance) +{ + auto methodDef = methodInstance->mMethodDef; + auto typeInstance = methodInstance->GetOwner(); + + llvm::SmallVector diParams; + diParams.push_back(DbgGetType(methodInstance->mReturnType)); + + BfType* thisType = NULL; + if (!methodDef->mIsStatic) + { + BfType* thisType; + thisType = typeInstance; + if (!thisType->IsValuelessType()) + { + BfType* thisPtrType = thisType; + auto diType = DbgGetType(thisPtrType); + if ((thisType->IsComposite()) && (!methodInstance->GetParamIsSplat(-1))) + { + diType = DbgCreatePointerType(diType); + diType = DbgCreateArtificialType(diType); + } + diParams.push_back(diType); + } + } + + for (int paramIdx = 0; paramIdx < methodInstance->GetParamCount(); paramIdx++) + { + bool isParamSkipped = methodInstance->IsParamSkipped(paramIdx); + if (!isParamSkipped) + { + auto resolvedType = methodInstance->GetParamType(paramIdx); + diParams.push_back(DbgGetType(resolvedType)); + } + } + + return DbgCreateSubroutineType(diParams); +} + BfIRMDNode BfIRBuilder::DbgCreateSubroutineType(const BfSizedArray& elements) { BfIRMDNode retVal = WriteCmd(BfIRCmd_DbgCreateSubroutineType, elements); diff --git a/IDEHelper/Compiler/BfIRBuilder.h b/IDEHelper/Compiler/BfIRBuilder.h index e513f669..e76ddf60 100644 --- a/IDEHelper/Compiler/BfIRBuilder.h +++ b/IDEHelper/Compiler/BfIRBuilder.h @@ -1252,6 +1252,7 @@ public: bool isLocalToUnit, bool isDefinition, int scopeLine, int flags, bool isOptimized, BfIRValue fn); BfIRMDNode DbgCreateParameterVariable(BfIRMDNode scope, const StringImpl& name, int argNo, BfIRMDNode file, int lineNum, BfIRMDNode type, bool AlwaysPreserve = false, int flags = 0); + BfIRMDNode DbgCreateSubroutineType(BfMethodInstance* methodInstance); BfIRMDNode DbgCreateSubroutineType(const BfSizedArray& elements); BfIRMDNode DbgCreateAutoVariable(BfIRMDNode scope, const StringImpl& name, BfIRMDNode file, int lineNo, BfIRMDNode type, BfIRInitType initType = BfIRInitType_NotSet); BfIRValue DbgInsertValueIntrinsic(BfIRValue val, BfIRMDNode varInfo); diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index ddb9e9ee..1220654b 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -12618,27 +12618,18 @@ void BfModule::DoAddLocalVariable(BfLocalVariable* localVar) } } -BfLocalVariable* BfModule::AddLocalVariableDef(BfLocalVariable* localVarDef, bool addDebugInfo, bool doAliasValue, BfIRValue declareBefore, BfIRInitType initType) -{ - if ((localVarDef->mValue) && (!localVarDef->mAddr) && (IsTargetingBeefBackend())) - { - if ((!localVarDef->mValue.IsConst()) && (!localVarDef->mValue.IsArg()) && (!localVarDef->mValue.IsFake())) - { - mBfIRBuilder->CreateValueScopeRetain(localVarDef->mValue); - mCurMethodState->mCurScope->mHadScopeValueRetain = true; - } - } - - if ((addDebugInfo) && (mBfIRBuilder->DbgHasInfo()) && - ((mCurMethodInstance == NULL) || (!mCurMethodInstance->mIsUnspecialized)) && - (mHasFullDebugInfo) && +void BfModule::DoLocalVariableDebugInfo(BfLocalVariable* localVarDef, bool doAliasValue, BfIRValue declareBefore, BfIRInitType initType) +{ + if ((mBfIRBuilder->DbgHasInfo()) && + ((mCurMethodInstance == NULL) || (!mCurMethodInstance->mIsUnspecialized)) && + (mHasFullDebugInfo) && ((mCurMethodState->mClosureState == NULL) || (!mCurMethodState->mClosureState->mCapturing))) { auto varType = localVarDef->mResolvedType; if (localVarDef->mResolvedType->IsValuelessType()) { - + } else { @@ -12651,7 +12642,7 @@ BfLocalVariable* BfModule::AddLocalVariableDef(BfLocalVariable* localVarDef, boo diValue = localVarDef->mAddr; isByAddr = true; } - + auto diType = mBfIRBuilder->DbgGetType(localVarDef->mResolvedType); bool didConstToMem = false; @@ -12662,7 +12653,7 @@ BfLocalVariable* BfModule::AddLocalVariableDef(BfLocalVariable* localVarDef, boo else if (localVarDef->mConstValue) { auto constant = mBfIRBuilder->GetConstant(localVarDef->mConstValue); - isConstant = + isConstant = (constant->mConstType < BfConstType_GlobalVar) || (constant->mConstType == BfConstType_AggZero) || (constant->mConstType == BfConstType_Array); @@ -12672,9 +12663,9 @@ BfLocalVariable* BfModule::AddLocalVariableDef(BfLocalVariable* localVarDef, boo { mBfIRBuilder->PopulateType(localVarDef->mResolvedType); auto constMem = mBfIRBuilder->ConstToMemory(localVarDef->mConstValue); - + if (IsTargetingBeefBackend()) - { + { diValue = mBfIRBuilder->CreateAliasValue(constMem); didConstToMem = true; @@ -12698,14 +12689,14 @@ BfLocalVariable* BfModule::AddLocalVariableDef(BfLocalVariable* localVarDef, boo mBfIRBuilder->SetInsertPoint(prevBlock); mBfIRBuilder->RestoreDebugLocation(); - } + } } if (mCompiler->mOptions.IsCodeView()) diType = mBfIRBuilder->DbgCreateConstType(diType); - } + } } - + if (!mBfIRBuilder->mIgnoreWrites) { auto diVariable = mBfIRBuilder->DbgCreateAutoVariable(mCurMethodState->mCurScope->mDIScope, @@ -12737,9 +12728,24 @@ BfLocalVariable* BfModule::AddLocalVariableDef(BfLocalVariable* localVarDef, boo } } } - } + } + } +} + +BfLocalVariable* BfModule::AddLocalVariableDef(BfLocalVariable* localVarDef, bool addDebugInfo, bool doAliasValue, BfIRValue declareBefore, BfIRInitType initType) +{ + if ((localVarDef->mValue) && (!localVarDef->mAddr) && (IsTargetingBeefBackend())) + { + if ((!localVarDef->mValue.IsConst()) && (!localVarDef->mValue.IsArg()) && (!localVarDef->mValue.IsFake())) + { + mBfIRBuilder->CreateValueScopeRetain(localVarDef->mValue); + mCurMethodState->mCurScope->mHadScopeValueRetain = true; + } } + if (addDebugInfo) + DoLocalVariableDebugInfo(localVarDef, doAliasValue, declareBefore, initType); + localVarDef->mDeclBlock = mBfIRBuilder->GetInsertBlock(); DoAddLocalVariable(localVarDef); diff --git a/IDEHelper/Compiler/BfModule.h b/IDEHelper/Compiler/BfModule.h index 6ecb4059..b2655aa3 100644 --- a/IDEHelper/Compiler/BfModule.h +++ b/IDEHelper/Compiler/BfModule.h @@ -1647,6 +1647,7 @@ public: bool CheckGenericConstraints(const BfGenericParamSource& genericParamSource, BfType* checkArgType, BfAstNode* checkArgTypeRef, BfGenericParamInstance* genericParamInst, BfTypeVector* methodGenericArgs = NULL, BfError** errorOut = NULL); BfIRValue AllocLocalVariable(BfType* type, const StringImpl& name, bool doLifetimeEnd = true); void DoAddLocalVariable(BfLocalVariable* localVar); + void DoLocalVariableDebugInfo(BfLocalVariable* localVar, bool doAliasValue = false, BfIRValue declareBefore = BfIRValue(), BfIRInitType initType = BfIRInitType_NotSet); BfLocalVariable* AddLocalVariableDef(BfLocalVariable* localVarDef, bool addDebugInfo = false, bool doAliasValue = false, BfIRValue declareBefore = BfIRValue(), BfIRInitType initType = BfIRInitType_NotSet); bool TryLocalVariableInit(BfLocalVariable* localVar); void LocalVariableDone(BfLocalVariable* localVar, bool isMethodExit);