mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-09 03:52:19 +02:00
Mixin name uniquing, 'this' for mixins
This commit is contained in:
parent
1a17780847
commit
4d53f185d8
8 changed files with 180 additions and 93 deletions
|
@ -26,3 +26,13 @@ StepOver()
|
|||
AssertLineContains("a + 20000")
|
||||
StepOver()
|
||||
AssertLineContains("a + 30000")
|
||||
|
||||
StepOut()
|
||||
StepOver()
|
||||
StepInto()
|
||||
AssertEvalEquals("mStr.mLength", "6")
|
||||
AssertLineContains("a + mStr.Length")
|
||||
StepOut()
|
||||
StepOver()
|
||||
StepInto()
|
||||
AssertLineContains("a + b + mStr.Length")
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -13513,7 +13513,7 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo
|
|||
|
||||
if (wantsDIData)
|
||||
{
|
||||
BfIRMDNode diFuncType = mModule->mBfIRBuilder->DbgCreateSubroutineType(SizedArray<BfIRMDNode, 0>());
|
||||
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;
|
||||
}
|
||||
|
@ -13712,13 +13715,29 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo
|
|||
};
|
||||
|
||||
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];
|
||||
|
||||
BfTypedValue argValue;
|
||||
|
||||
BfLocalVariable* localVar = new BfLocalVariable();
|
||||
|
||||
if (argIdx == -1)
|
||||
{
|
||||
argValue = target;
|
||||
localVar->mName = "this";
|
||||
localVar->mIsThis = true;
|
||||
localVar->mIsAssigned = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto arg = &args[argIdx];
|
||||
auto paramDef = methodDef->mParams[paramIdx];
|
||||
|
||||
localVar->mName = paramDef->mName;
|
||||
|
||||
if (!arg->mTypedValue)
|
||||
{
|
||||
|
@ -13727,50 +13746,57 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo
|
|||
wantType = mModule->mContext->mBfObjectType;
|
||||
arg->mTypedValue = mModule->GetDefaultTypedValue(wantType);
|
||||
}
|
||||
argValue = arg->mTypedValue;
|
||||
}
|
||||
|
||||
BfLocalVariable* localVar = new BfLocalVariable();
|
||||
localVar->mName = paramDef->mName;
|
||||
localVar->mResolvedType = arg->mTypedValue.mType;
|
||||
if (arg->mTypedValue.mType->IsRef())
|
||||
localVar->mResolvedType = argValue.mType;
|
||||
if (argValue.mType->IsRef())
|
||||
{
|
||||
auto refType = (BfRefType*)localVar->mResolvedType;
|
||||
localVar->mAddr = mModule->LoadValue(arg->mTypedValue).mValue;
|
||||
localVar->mResolvedType = arg->mTypedValue.mType->GetUnderlyingType();
|
||||
localVar->mAddr = mModule->LoadValue(argValue).mValue;
|
||||
localVar->mResolvedType = argValue.mType->GetUnderlyingType();
|
||||
localVar->mIsAssigned = refType->mRefKind != BfRefType::RefKind_Out;
|
||||
}
|
||||
else if (arg->mTypedValue.IsAddr())
|
||||
localVar->mAddr = arg->mTypedValue.mValue;
|
||||
else if (argValue.IsAddr())
|
||||
localVar->mAddr = argValue.mValue;
|
||||
else
|
||||
{
|
||||
if (!arg->mTypedValue.mValue)
|
||||
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();
|
||||
}
|
||||
|
||||
if (argIdx == -1)
|
||||
{
|
||||
_AddLocalVariable(localVar, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
_AddLocalVariable(localVar, exprEvaluator);
|
||||
|
||||
endLocalIdx++;
|
||||
++argExprEvaluatorItr;
|
||||
}
|
||||
}
|
||||
|
||||
if (auto blockBody = BfNodeDynCast<BfBlock>(methodDef->mBody))
|
||||
mModule->VisitCodeBlock(blockBody);
|
||||
|
|
|
@ -2693,38 +2693,7 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type)
|
|||
if (methodDef->mIsOverride)
|
||||
continue;
|
||||
|
||||
llvm::SmallVector<BfIRMDNode, 8> 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<BfIRMDNode, 8> 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<BfIRMDNode>& elements)
|
||||
{
|
||||
BfIRMDNode retVal = WriteCmd(BfIRCmd_DbgCreateSubroutineType, elements);
|
||||
|
|
|
@ -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<BfIRMDNode>& elements);
|
||||
BfIRMDNode DbgCreateAutoVariable(BfIRMDNode scope, const StringImpl& name, BfIRMDNode file, int lineNo, BfIRMDNode type, BfIRInitType initType = BfIRInitType_NotSet);
|
||||
BfIRValue DbgInsertValueIntrinsic(BfIRValue val, BfIRMDNode varInfo);
|
||||
|
|
|
@ -12618,18 +12618,9 @@ void BfModule::DoAddLocalVariable(BfLocalVariable* localVar)
|
|||
}
|
||||
}
|
||||
|
||||
BfLocalVariable* BfModule::AddLocalVariableDef(BfLocalVariable* localVarDef, bool addDebugInfo, bool doAliasValue, BfIRValue declareBefore, BfIRInitType initType)
|
||||
void BfModule::DoLocalVariableDebugInfo(BfLocalVariable* localVarDef, 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()) &&
|
||||
if ((mBfIRBuilder->DbgHasInfo()) &&
|
||||
((mCurMethodInstance == NULL) || (!mCurMethodInstance->mIsUnspecialized)) &&
|
||||
(mHasFullDebugInfo) &&
|
||||
((mCurMethodState->mClosureState == NULL) || (!mCurMethodState->mClosureState->mCapturing)))
|
||||
|
@ -12739,6 +12730,21 @@ 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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue