mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 03:28:20 +02:00
Interop fixes and tests, fixing xplat struct passing issues
This commit is contained in:
parent
4cf6af53bd
commit
5da74382d4
31 changed files with 1569 additions and 239 deletions
|
@ -512,10 +512,20 @@ namespace System
|
|||
UInt8,
|
||||
Int16,
|
||||
UInt16,
|
||||
Int24,
|
||||
UInt24,
|
||||
Int32,
|
||||
UInt32,
|
||||
Int40,
|
||||
UInt40,
|
||||
Int48,
|
||||
UInt48,
|
||||
Int56,
|
||||
UInt56,
|
||||
Int64,
|
||||
UInt64,
|
||||
Int128,
|
||||
UInt128,
|
||||
Int,
|
||||
UInt,
|
||||
IntUnknown,
|
||||
|
|
|
@ -479,10 +479,20 @@ namespace System
|
|||
UInt8,
|
||||
Int16,
|
||||
UInt16,
|
||||
Int24,
|
||||
UInt24,
|
||||
Int32,
|
||||
UInt32,
|
||||
Int40,
|
||||
UInt40,
|
||||
Int48,
|
||||
UInt48,
|
||||
Int56,
|
||||
UInt56,
|
||||
Int64,
|
||||
UInt64,
|
||||
Int128,
|
||||
UInt128,
|
||||
Int,
|
||||
UInt,
|
||||
IntUnknown,
|
||||
|
|
|
@ -71,6 +71,22 @@ BeStructType* BeContext::CreateStruct(const StringImpl& name)
|
|||
return structType;
|
||||
}
|
||||
|
||||
BeStructType* BeContext::CreateStruct(const SizedArrayImpl<BeType*>& types)
|
||||
{
|
||||
BeStructType** valuePtr = NULL;
|
||||
if (mAnonymousStructMap.TryGetValueWith(types, &valuePtr))
|
||||
return *valuePtr;
|
||||
|
||||
Array<BeType*> key;
|
||||
for (auto type : types)
|
||||
key.Add(type);
|
||||
|
||||
BeStructType* structType = CreateStruct("");
|
||||
SetStructBody(structType, types, false);
|
||||
mAnonymousStructMap.TryAdd(key, structType);
|
||||
return structType;
|
||||
}
|
||||
|
||||
BePointerType* BeContext::GetPointerTo(BeType* beType)
|
||||
{
|
||||
if (beType->mPointerType == NULL)
|
||||
|
|
|
@ -226,6 +226,7 @@ public:
|
|||
//BumpAllocator mAlloc;
|
||||
BeType* mPrimitiveTypes[BeTypeCode_COUNT];
|
||||
OwnedVector<BeType> mTypes;
|
||||
Dictionary<Array<BeType*>, BeStructType*> mAnonymousStructMap;
|
||||
|
||||
public:
|
||||
void NotImpl();
|
||||
|
@ -234,6 +235,7 @@ public:
|
|||
BeContext();
|
||||
BeType* GetPrimitiveType(BeTypeCode typeCode);
|
||||
BeStructType* CreateStruct(const StringImpl& name);
|
||||
BeStructType* CreateStruct(const SizedArrayImpl<BeType*>& types);
|
||||
BePointerType* GetPointerTo(BeType* beType);
|
||||
void SetStructBody(BeStructType* structType, const SizedArrayImpl<BeType*>& types, bool packed);
|
||||
BeSizedArrayType* CreateSizedArrayType(BeType* type, int length);
|
||||
|
|
|
@ -963,6 +963,13 @@ void BeIRCodeGen::HandleNextCmd()
|
|||
SetResult(curId, mBeContext->CreateStruct(typeName));
|
||||
}
|
||||
break;
|
||||
case BfIRCmd_CreateAnonymousStruct:
|
||||
{
|
||||
CMD_PARAM(CmdParamVec<BeType*>, members);
|
||||
BeStructType* structType = mBeContext->CreateStruct(members);
|
||||
SetResult(curId, structType);
|
||||
}
|
||||
break;
|
||||
case BfIRCmd_StructSetBody:
|
||||
{
|
||||
CMD_PARAM(BeType*, type);
|
||||
|
@ -2143,7 +2150,8 @@ void BeIRCodeGen::HandleNextCmd()
|
|||
{
|
||||
if (attribute == BfIRAttribute_StructRet)
|
||||
{
|
||||
BF_ASSERT(argIdx == 1);
|
||||
auto valType = callInst->mArgs[argIdx - 1].mValue->GetType();
|
||||
BF_ASSERT(valType->IsPointer());
|
||||
callInst->mArgs[argIdx - 1].mStructRet = true;
|
||||
}
|
||||
else if (attribute == BfIRAttribute_ZExt)
|
||||
|
@ -2152,6 +2160,9 @@ void BeIRCodeGen::HandleNextCmd()
|
|||
callInst->mArgs[argIdx - 1].mNoAlias = true;
|
||||
else if (attribute == BfIRAttribute_NoCapture)
|
||||
callInst->mArgs[argIdx - 1].mNoCapture = true;
|
||||
else if (attribute == BfIRAttribute_ByVal)
|
||||
{
|
||||
}
|
||||
else
|
||||
BF_FATAL("Unhandled");
|
||||
}
|
||||
|
@ -2177,7 +2188,21 @@ void BeIRCodeGen::HandleNextCmd()
|
|||
if (argIdx > 0)
|
||||
{
|
||||
if (attribute == BfIRAttribute_Dereferencable)
|
||||
{
|
||||
callInst->mArgs[argIdx - 1].mDereferenceableSize = arg;
|
||||
if (auto func = BeValueDynCast<BeFunction>(callInst->mFunc))
|
||||
{
|
||||
BF_ASSERT(func->mParams[argIdx - 1].mDereferenceableSize == arg);
|
||||
}
|
||||
}
|
||||
else if (attribute == BfIRAttribute_ByVal)
|
||||
{
|
||||
callInst->mArgs[argIdx - 1].mByRefSize = arg;
|
||||
if (auto func = BeValueDynCast<BeFunction>(callInst->mFunc))
|
||||
{
|
||||
BF_ASSERT(func->mParams[argIdx - 1].mByValSize == arg);
|
||||
}
|
||||
}
|
||||
else
|
||||
BF_FATAL("Unhandled");
|
||||
}
|
||||
|
@ -2242,6 +2267,8 @@ void BeIRCodeGen::HandleNextCmd()
|
|||
{
|
||||
if (attribute == BfIRAttribute_Dereferencable)
|
||||
func->mParams[argIdx - 1].mDereferenceableSize = arg;
|
||||
else if (attribute == BfIRAttribute_ByVal)
|
||||
func->mParams[argIdx - 1].mByValSize = arg;
|
||||
else
|
||||
BF_FATAL("Unhandled");
|
||||
}
|
||||
|
|
|
@ -532,6 +532,7 @@ void BeFunction::HashContent(BeHashContext& hashCtx)
|
|||
hashCtx.Mixin(param.mStructRet);
|
||||
hashCtx.Mixin(param.mZExt);
|
||||
hashCtx.Mixin(param.mDereferenceableSize);
|
||||
hashCtx.Mixin(param.mByValSize);
|
||||
}
|
||||
if (mDbgFunction != NULL)
|
||||
mDbgFunction->HashReference(hashCtx);
|
||||
|
|
|
@ -410,6 +410,7 @@ public:
|
|||
bool mNoCapture;
|
||||
bool mZExt;
|
||||
int mDereferenceableSize;
|
||||
int mByValSize;
|
||||
|
||||
BeFunctionParam()
|
||||
{
|
||||
|
@ -418,6 +419,7 @@ public:
|
|||
mNoCapture = false;
|
||||
mZExt = false;
|
||||
mDereferenceableSize = -1;
|
||||
mByValSize = -1;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1207,6 +1209,7 @@ public:
|
|||
{
|
||||
BeValue* mValue;
|
||||
int mDereferenceableSize;
|
||||
int mByRefSize;
|
||||
bool mStructRet;
|
||||
bool mZExt;
|
||||
bool mNoAlias;
|
||||
|
@ -1219,6 +1222,7 @@ public:
|
|||
mNoAlias = false;
|
||||
mNoCapture = false;
|
||||
mDereferenceableSize = -1;
|
||||
mByRefSize = -1;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1254,6 +1258,8 @@ public:
|
|||
arg.mValue->HashReference(hashCtx);
|
||||
hashCtx.Mixin(arg.mStructRet);
|
||||
hashCtx.Mixin(arg.mZExt);
|
||||
hashCtx.Mixin(arg.mDereferenceableSize);
|
||||
hashCtx.Mixin(arg.mByRefSize);
|
||||
}
|
||||
hashCtx.Mixin(mCallingConv);
|
||||
hashCtx.Mixin(mNoReturn);
|
||||
|
|
|
@ -3470,6 +3470,8 @@ void BfCompiler::VisitSourceExteriorNodes()
|
|||
if (parser->mAwaitingDelete)
|
||||
return;
|
||||
|
||||
if (parser->mParserData == NULL)
|
||||
return;
|
||||
if (parser->mParserData->mExteriorNodesCheckIdx == mSystem->mTypeMapVersion)
|
||||
return;
|
||||
|
||||
|
|
|
@ -2496,6 +2496,8 @@ void MsDemangleScanner::Process(const StringImpl& mangledName)
|
|||
|
||||
String BfDemangler::Demangle(const StringImpl& mangledName, DbgLanguage language, Flags flags)
|
||||
{
|
||||
if (mangledName.IsEmpty())
|
||||
return "";
|
||||
if (mangledName[0] == '?')
|
||||
{
|
||||
MsDemangler demangler;
|
||||
|
|
|
@ -4484,7 +4484,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfMethodInstance* methodInstance, BfIRV
|
|||
}
|
||||
else
|
||||
{
|
||||
auto val = mModule->GetDefaultTypedValue(returnType, true, methodInstance->HasStructRet() ? BfDefaultValueKind_Addr : BfDefaultValueKind_Value);
|
||||
auto val = mModule->GetDefaultTypedValue(returnType, true, (methodInstance->GetStructRetIdx() != -1) ? BfDefaultValueKind_Addr : BfDefaultValueKind_Value);
|
||||
if (val.mKind == BfTypedValueKind_Addr)
|
||||
val.mKind = BfTypedValueKind_TempAddr;
|
||||
return val;
|
||||
|
@ -4492,7 +4492,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfMethodInstance* methodInstance, BfIRV
|
|||
};
|
||||
|
||||
mModule->PopulateType(origReturnType, BfPopulateType_Data);
|
||||
if (methodInstance->HasStructRet())
|
||||
if (methodInstance->GetStructRetIdx() != -1)
|
||||
{
|
||||
// We need to ensure that mReceivingValue has the correct type, otherwise it's possible that a conversion operator needs to be applied
|
||||
// This happens for returning Result<T>'s with a 'T' value
|
||||
|
@ -4756,13 +4756,23 @@ BfTypedValue BfExprEvaluator::CreateCall(BfMethodInstance* methodInstance, BfIRV
|
|||
mModule->mBfIRBuilder->PopulateType(returnType);
|
||||
|
||||
BfIRValue callInst;
|
||||
int callIRArgCount = (int)irArgs.size();
|
||||
if (sret != NULL)
|
||||
{
|
||||
SizedArray<BfIRValue, 8> sretIRArgs;
|
||||
sretIRArgs.push_back(sret->mValue);
|
||||
if (!irArgs.IsEmpty())
|
||||
sretIRArgs.Insert(sretIRArgs.size(), &irArgs[0], irArgs.size());
|
||||
int sretIdx = methodInstance->GetStructRetIdx();
|
||||
int inIdx = 0;
|
||||
for (int outIdx = 0; outIdx < irArgs.size() + 1; outIdx++)
|
||||
{
|
||||
if (outIdx == sretIdx)
|
||||
{
|
||||
sretIRArgs.Add(sret->mValue);
|
||||
continue;
|
||||
}
|
||||
sretIRArgs.Add(irArgs[inIdx++]);
|
||||
}
|
||||
callInst = mModule->mBfIRBuilder->CreateCall(funcCallInst, sretIRArgs);
|
||||
callIRArgCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -4780,18 +4790,23 @@ BfTypedValue BfExprEvaluator::CreateCall(BfMethodInstance* methodInstance, BfIRV
|
|||
int paramIdx = 0;
|
||||
bool doingThis = !methodDef->mIsStatic;
|
||||
int argIdx = 0;
|
||||
if (sret != NULL)
|
||||
|
||||
|
||||
if (methodInstance->mIdHash == 1140)
|
||||
{
|
||||
mModule->mBfIRBuilder->Call_AddAttribute(callInst, argIdx + 1, BfIRAttribute_StructRet);
|
||||
argIdx++;
|
||||
NOP;
|
||||
}
|
||||
|
||||
int paramCount = methodInstance->GetParamCount();
|
||||
|
||||
for ( ; argIdx < (int)irArgs.size(); /*argIdx++*/)
|
||||
for ( ; argIdx < callIRArgCount ; )
|
||||
{
|
||||
if (argIdx >= paramCount)
|
||||
break;
|
||||
if (argIdx == methodInstance->GetStructRetIdx())
|
||||
{
|
||||
mModule->mBfIRBuilder->Call_AddAttribute(callInst, argIdx + 1, BfIRAttribute_StructRet);
|
||||
argIdx++;
|
||||
continue;
|
||||
}
|
||||
|
||||
auto _HandleParamType = [&] (BfType* paramType)
|
||||
{
|
||||
|
@ -4799,10 +4814,13 @@ BfTypedValue BfExprEvaluator::CreateCall(BfMethodInstance* methodInstance, BfIRV
|
|||
{
|
||||
if ((!doingThis) || (!methodDef->mIsMutating && methodInstance->AllowsSplatting()))
|
||||
{
|
||||
auto loweredTypeCode = paramType->GetLoweredType();
|
||||
if (loweredTypeCode != BfTypeCode_None)
|
||||
BfTypeCode loweredTypeCode = BfTypeCode_None;
|
||||
BfTypeCode loweredTypeCode2 = BfTypeCode_None;
|
||||
if (paramType->GetLoweredType(BfTypeUsage_Parameter, &loweredTypeCode, &loweredTypeCode2))
|
||||
{
|
||||
argIdx++;
|
||||
if (loweredTypeCode2 != BfTypeCode_None)
|
||||
argIdx++;
|
||||
return; // Lowering never requires attributes
|
||||
}
|
||||
}
|
||||
|
@ -4818,6 +4836,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfMethodInstance* methodInstance, BfIRV
|
|||
if ((addDeref <= 0) && (!elementType->IsValuelessType()))
|
||||
mModule->AssertErrorState();
|
||||
}
|
||||
|
||||
if ((paramType->IsComposite()) && (!paramType->IsTypedPrimitive()))
|
||||
{
|
||||
if (mModule->mCompiler->mOptions.mAllowStructByVal)
|
||||
|
@ -4834,10 +4853,17 @@ BfTypedValue BfExprEvaluator::CreateCall(BfMethodInstance* methodInstance, BfIRV
|
|||
// We're splatting
|
||||
}
|
||||
else
|
||||
{
|
||||
if (doingThis)
|
||||
{
|
||||
mModule->mBfIRBuilder->Call_AddAttribute(callInst, argIdx + 1, BfIRAttribute_NoCapture);
|
||||
addDeref = paramType->mSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
mModule->mBfIRBuilder->Call_AddAttribute(callInst, argIdx + 1, BfIRAttribute_ByVal, mModule->mSystem->mPtrSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (paramType->IsPrimitiveType())
|
||||
|
@ -4876,13 +4902,28 @@ BfTypedValue BfExprEvaluator::CreateCall(BfMethodInstance* methodInstance, BfIRV
|
|||
}
|
||||
else
|
||||
{
|
||||
if (paramIdx >= methodInstance->GetParamCount())
|
||||
break;
|
||||
|
||||
paramType = methodInstance->GetParamType(paramIdx);
|
||||
|
||||
BfTypeCode loweredTypeCode = BfTypeCode_None;
|
||||
BfTypeCode loweredTypeCode2 = BfTypeCode_None;
|
||||
if (paramType->GetLoweredType(BfTypeUsage_Parameter, &loweredTypeCode, &loweredTypeCode2))
|
||||
{
|
||||
argIdx++;
|
||||
paramIdx++;
|
||||
if (loweredTypeCode2 != BfTypeCode_None)
|
||||
argIdx++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((paramType->IsValuelessType()) && (!paramType->IsMethodRef()))
|
||||
{
|
||||
paramIdx++;
|
||||
continue;
|
||||
}
|
||||
//if (resolvedTypeRef->IsSplattable())
|
||||
|
||||
if (methodInstance->GetParamIsSplat(paramIdx))
|
||||
{
|
||||
BfTypeUtils::SplatIterate(_HandleParamType, paramType);
|
||||
|
@ -4893,8 +4934,6 @@ BfTypedValue BfExprEvaluator::CreateCall(BfMethodInstance* methodInstance, BfIRV
|
|||
_HandleParamType(methodInstance->GetParamType(paramIdx));
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (doingThis)
|
||||
doingThis = false;
|
||||
else
|
||||
|
@ -4936,13 +4975,14 @@ BfTypedValue BfExprEvaluator::CreateCall(BfMethodInstance* methodInstance, BfIRV
|
|||
result = *sret;
|
||||
else if (hasResult)
|
||||
{
|
||||
if (methodInstance->mReturnType->GetLoweredType() != BfTypeCode_None)
|
||||
BfTypeCode loweredRetType = BfTypeCode_None;
|
||||
BfTypeCode loweredRetType2 = BfTypeCode_None;
|
||||
if (methodInstance->GetLoweredReturnType(&loweredRetType, &loweredRetType2))
|
||||
{
|
||||
auto loweredType = mModule->GetPrimitiveType(methodInstance->mReturnType->GetLoweredType());
|
||||
auto loweredPtrType = mModule->CreatePointerType(loweredType);
|
||||
|
||||
auto retVal = mModule->CreateAlloca(methodInstance->mReturnType);
|
||||
auto castedRetVal = mModule->mBfIRBuilder->CreateBitCast(retVal, mModule->mBfIRBuilder->MapType(loweredPtrType));
|
||||
BfIRType loweredIRType = mModule->GetIRLoweredType(loweredRetType, loweredRetType2);
|
||||
loweredIRType = mModule->mBfIRBuilder->GetPointerTo(loweredIRType);
|
||||
auto castedRetVal = mModule->mBfIRBuilder->CreateBitCast(retVal, loweredIRType);
|
||||
mModule->mBfIRBuilder->CreateStore(callInst, castedRetVal);
|
||||
result = BfTypedValue(retVal, methodInstance->mReturnType, BfTypedValueKind_TempAddr);
|
||||
}
|
||||
|
@ -5116,14 +5156,40 @@ void BfExprEvaluator::PushArg(BfTypedValue argVal, SizedArrayImpl<BfIRValue>& ir
|
|||
|
||||
if (!disableLowering)
|
||||
{
|
||||
auto loweredTypeCode = argVal.mType->GetLoweredType();
|
||||
if (loweredTypeCode != BfTypeCode_None)
|
||||
BfTypeCode loweredTypeCode = BfTypeCode_None;
|
||||
BfTypeCode loweredTypeCode2 = BfTypeCode_None;
|
||||
if (argVal.mType->GetLoweredType(BfTypeUsage_Parameter, &loweredTypeCode, &loweredTypeCode2))
|
||||
{
|
||||
auto primType = mModule->GetPrimitiveType(loweredTypeCode);
|
||||
auto ptrType = mModule->CreatePointerType(primType);
|
||||
BfIRValue primPtrVal = mModule->mBfIRBuilder->CreateBitCast(argVal.mValue, mModule->mBfIRBuilder->MapType(ptrType));
|
||||
// auto primType = mModule->GetPrimitiveType(loweredTypeCode);
|
||||
// auto ptrType = mModule->CreatePointerType(primType);
|
||||
// BfIRValue primPtrVal = mModule->mBfIRBuilder->CreateBitCast(argVal.mValue, mModule->mBfIRBuilder->MapType(ptrType));
|
||||
// auto primVal = mModule->mBfIRBuilder->CreateLoad(primPtrVal);
|
||||
// irArgs.push_back(primVal);
|
||||
//
|
||||
// if (loweredTypeCode2 != BfTypeCode_None)
|
||||
// {
|
||||
// auto primType2 = mModule->GetPrimitiveType(loweredTypeCode2);
|
||||
// auto ptrType2 = mModule->CreatePointerType(primType2);
|
||||
// BfIRValue primPtrVal2 = mModule->mBfIRBuilder->CreateBitCast(mModule->mBfIRBuilder->CreateInBoundsGEP(primPtrVal, 1), mModule->mBfIRBuilder->MapType(ptrType2));
|
||||
// auto primVal2 = mModule->mBfIRBuilder->CreateLoad(primPtrVal2);
|
||||
// irArgs.push_back(primVal2);
|
||||
// }
|
||||
|
||||
auto primType = mModule->mBfIRBuilder->GetPrimitiveType(loweredTypeCode);
|
||||
auto ptrType = mModule->mBfIRBuilder->GetPointerTo(primType);
|
||||
BfIRValue primPtrVal = mModule->mBfIRBuilder->CreateBitCast(argVal.mValue, ptrType);
|
||||
auto primVal = mModule->mBfIRBuilder->CreateLoad(primPtrVal);
|
||||
irArgs.push_back(primVal);
|
||||
|
||||
if (loweredTypeCode2 != BfTypeCode_None)
|
||||
{
|
||||
auto primType2 = mModule->mBfIRBuilder->GetPrimitiveType(loweredTypeCode2);
|
||||
auto ptrType2 = mModule->mBfIRBuilder->GetPointerTo(primType2);
|
||||
BfIRValue primPtrVal2 = mModule->mBfIRBuilder->CreateBitCast(mModule->mBfIRBuilder->CreateInBoundsGEP(primPtrVal, 1), ptrType2);
|
||||
auto primVal2 = mModule->mBfIRBuilder->CreateLoad(primPtrVal2);
|
||||
irArgs.push_back(primVal2);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -5244,7 +5310,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu
|
|||
if (!mModule->mCompiler->mIsResolveOnly)
|
||||
sCallIdx++;
|
||||
int callIdx = sCallIdx;
|
||||
if (callIdx == 4348)
|
||||
if (callIdx == 1177)
|
||||
{
|
||||
NOP;
|
||||
}
|
||||
|
@ -5439,6 +5505,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu
|
|||
wantsSplat = methodInstance->GetParamIsSplat(paramIdx);
|
||||
if (methodInstance->IsImplicitCapture(paramIdx))
|
||||
{
|
||||
auto paramType = methodInstance->GetParamType(paramIdx);
|
||||
if (mModule->mCurMethodInstance->IsMixin())
|
||||
{
|
||||
// Don't bother, also- can fail on captures
|
||||
|
@ -5461,10 +5528,12 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu
|
|||
{
|
||||
SplatArgs(lookupVal, irArgs);
|
||||
}
|
||||
else
|
||||
else if (paramType->IsRef())
|
||||
{
|
||||
irArgs.push_back(lookupVal.mValue);
|
||||
}
|
||||
else
|
||||
PushArg(lookupVal, irArgs, true);
|
||||
}
|
||||
}
|
||||
paramIdx++;
|
||||
|
@ -5549,7 +5618,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu
|
|||
bool hadMissingArg = false;
|
||||
|
||||
int argExprIdx = argIdx;
|
||||
if ((methodDef->mMethodType == BfMethodType_Extension))
|
||||
if (methodDef->mMethodType == BfMethodType_Extension)
|
||||
{
|
||||
argExprIdx--;
|
||||
if (argExprIdx == -1)
|
||||
|
@ -5718,10 +5787,6 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu
|
|||
{
|
||||
if (methodRefType->WantsDataPassedAsSplat(dataIdx))
|
||||
SplatArgs(lookupVal, irArgs);
|
||||
else if (lookupVal.mType->IsComposite())
|
||||
{
|
||||
irArgs.push_back(lookupVal.mValue);
|
||||
}
|
||||
else
|
||||
irArgs.push_back(lookupVal.mValue);
|
||||
}
|
||||
|
@ -6814,11 +6879,6 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp
|
|||
methodMatcher.CheckType(lookupTypeInst, target, true);
|
||||
}
|
||||
|
||||
if ((methodMatcher.mBestMethodDef != NULL) && (methodMatcher.mBestMethodDef->mName == "Zorf"))
|
||||
{
|
||||
NOP;
|
||||
}
|
||||
|
||||
BfTypedValue staticResult;
|
||||
methodMatcher.TryDevirtualizeCall(target, &origTarget, &staticResult);
|
||||
if (staticResult)
|
||||
|
@ -9910,7 +9970,9 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr)
|
|||
{
|
||||
hasThis = true;
|
||||
methodInstance->GetIRFunctionInfo(mModule, irReturnType, irParamTypes);
|
||||
int thisIdx = methodInstance->HasStructRet() ? 1 : 0;
|
||||
int thisIdx = 0;
|
||||
if (methodInstance->GetStructRetIdx() == 0)
|
||||
thisIdx = 1;
|
||||
irParamTypes[thisIdx] = mModule->mBfIRBuilder->MapType(useTypeInstance);
|
||||
}
|
||||
else
|
||||
|
@ -9927,10 +9989,10 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr)
|
|||
auto funcType = mModule->mBfIRBuilder->CreateFunctionType(irReturnType, irParamTypes);
|
||||
funcValue = mModule->mBfIRBuilder->CreateFunction(funcType, BfIRLinkageType_External, methodName);
|
||||
|
||||
if (methodInstance->HasStructRet())
|
||||
if (methodInstance->GetStructRetIdx() != -1)
|
||||
{
|
||||
mModule->mBfIRBuilder->Func_AddAttribute(funcValue, 1, BfIRAttribute_NoAlias);
|
||||
mModule->mBfIRBuilder->Func_AddAttribute(funcValue, 1, BfIRAttribute_StructRet);
|
||||
mModule->mBfIRBuilder->Func_AddAttribute(funcValue, methodInstance->GetStructRetIdx() + 1, BfIRAttribute_NoAlias);
|
||||
mModule->mBfIRBuilder->Func_AddAttribute(funcValue, methodInstance->GetStructRetIdx() + 1, BfIRAttribute_StructRet);
|
||||
}
|
||||
|
||||
auto srcCallingConv = mModule->GetIRCallingConvention(methodInstance);
|
||||
|
@ -9947,9 +10009,17 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr)
|
|||
fieldIdx = 0;
|
||||
SizedArray<BfIRValue, 8> irArgs;
|
||||
|
||||
if (methodInstance->mIdHash == 775)
|
||||
{
|
||||
NOP;
|
||||
}
|
||||
|
||||
int argIdx = 0;
|
||||
if (methodInstance->HasStructRet())
|
||||
irArgs.push_back(mModule->mBfIRBuilder->GetArgument(argIdx++));
|
||||
if (bindMethodInstance->GetStructRetIdx() == 0)
|
||||
{
|
||||
irArgs.push_back(mModule->mBfIRBuilder->GetArgument(methodInstance->GetStructRetIdx()));
|
||||
argIdx++;
|
||||
}
|
||||
|
||||
for (int implicitParamIdx = bindMethodInstance->HasThis() ? -1 : 0; implicitParamIdx < implicitParamCount; implicitParamIdx++)
|
||||
{
|
||||
|
@ -9965,7 +10035,10 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr)
|
|||
disableSplat = true;
|
||||
}
|
||||
}
|
||||
int thisIdx = methodInstance->HasStructRet() ? 1 : 0;
|
||||
|
||||
int thisIdx = 0;
|
||||
if (methodInstance->GetStructRetIdx() == 0)
|
||||
thisIdx = 1;
|
||||
auto fieldPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(mModule->mBfIRBuilder->GetArgument(thisIdx), 0, gepIdx);
|
||||
BfTypedValue typedVal(fieldPtr, fieldType, true);
|
||||
PushArg(typedVal, irArgs, disableSplat);
|
||||
|
@ -9975,6 +10048,12 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr)
|
|||
if (hasThis)
|
||||
argIdx++;
|
||||
|
||||
if (bindMethodInstance->GetStructRetIdx() == 1)
|
||||
{
|
||||
irArgs.push_back(mModule->mBfIRBuilder->GetArgument(methodInstance->GetStructRetIdx()));
|
||||
argIdx++;
|
||||
}
|
||||
|
||||
for (int paramIdx = 0; paramIdx < methodInstance->GetParamCount(); paramIdx++)
|
||||
{
|
||||
auto paramType = methodInstance->GetParamType(paramIdx);
|
||||
|
@ -9992,12 +10071,12 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr)
|
|||
if (mModule->mCompiler->mOptions.mAllowHotSwapping)
|
||||
bindFuncVal = mModule->mBfIRBuilder->RemapBindFunction(bindFuncVal);
|
||||
auto callInst = mModule->mBfIRBuilder->CreateCall(bindFuncVal, irArgs);
|
||||
if (methodInstance->HasStructRet())
|
||||
mModule->mBfIRBuilder->Call_AddAttribute(callInst, 1, BfIRAttribute_StructRet);
|
||||
if (bindMethodInstance->GetStructRetIdx() != -1)
|
||||
mModule->mBfIRBuilder->Call_AddAttribute(callInst, bindMethodInstance->GetStructRetIdx() + 1, BfIRAttribute_StructRet);
|
||||
auto destCallingConv = mModule->GetIRCallingConvention(bindMethodInstance);
|
||||
if (destCallingConv != BfIRCallingConv_CDecl)
|
||||
mModule->mBfIRBuilder->SetCallCallingConv(callInst, destCallingConv);
|
||||
if ((methodInstance->mReturnType->IsValuelessType()) || (methodInstance->HasStructRet()))
|
||||
if ((methodInstance->mReturnType->IsValuelessType()) || (methodInstance->GetStructRetIdx() != -1))
|
||||
{
|
||||
mModule->mBfIRBuilder->CreateRetVoid();
|
||||
}
|
||||
|
@ -10784,13 +10863,16 @@ BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lam
|
|||
}
|
||||
|
||||
SizedArray<BfIRType, 3> newTypes;
|
||||
if ((invokeMethodInstance != NULL) && (invokeMethodInstance->HasStructRet()))
|
||||
|
||||
if ((invokeMethodInstance != NULL) && (invokeMethodInstance->GetStructRetIdx() == 0))
|
||||
newTypes.push_back(origParamTypes[0]);
|
||||
if (!methodDef->mIsStatic)
|
||||
newTypes.push_back(mModule->mBfIRBuilder->MapType(useTypeInstance));
|
||||
if ((invokeMethodInstance != NULL) && (invokeMethodInstance->GetStructRetIdx() == 1))
|
||||
newTypes.push_back(origParamTypes[1]);
|
||||
|
||||
int paramStartIdx = 0;
|
||||
if ((invokeMethodInstance != NULL) && (invokeMethodInstance->HasStructRet()))
|
||||
if ((invokeMethodInstance != NULL) && (invokeMethodInstance->GetStructRetIdx() != -1))
|
||||
paramStartIdx++;
|
||||
if (!methodDef->mIsStatic)
|
||||
paramStartIdx++;
|
||||
|
@ -14585,6 +14667,11 @@ BfTypedValue BfExprEvaluator::GetResult(bool clearResult, bool resolveGenericTyp
|
|||
return mResult;
|
||||
}
|
||||
|
||||
if (matchedMethod->mName == "get__CultureName")
|
||||
{
|
||||
NOP;
|
||||
}
|
||||
|
||||
auto methodInstance = GetPropertyMethodInstance(matchedMethod);
|
||||
if (methodInstance.mMethodInstance == NULL)
|
||||
return mResult;
|
||||
|
@ -14662,7 +14749,7 @@ BfTypedValue BfExprEvaluator::GetResult(bool clearResult, bool resolveGenericTyp
|
|||
}
|
||||
else
|
||||
{
|
||||
auto val = mModule->GetDefaultTypedValue(returnType, true, methodInstance.mMethodInstance->HasStructRet() ? BfDefaultValueKind_Addr : BfDefaultValueKind_Value);
|
||||
auto val = mModule->GetDefaultTypedValue(returnType, true, (methodInstance.mMethodInstance->GetStructRetIdx() != -1) ? BfDefaultValueKind_Addr : BfDefaultValueKind_Value);
|
||||
if (val.mKind == BfTypedValueKind_Addr)
|
||||
val.mKind = BfTypedValueKind_TempAddr;
|
||||
return val;
|
||||
|
|
|
@ -3305,6 +3305,13 @@ BfIRType BfIRBuilder::CreateStructType(const StringImpl& name)
|
|||
return retType;
|
||||
}
|
||||
|
||||
BfIRType BfIRBuilder::CreateStructType(const BfSizedArray<BfIRType>& memberTypes)
|
||||
{
|
||||
BfIRType retType = WriteCmd(BfIRCmd_CreateAnonymousStruct, memberTypes);
|
||||
NEW_CMD_INSERTED_IRTYPE;
|
||||
return retType;
|
||||
}
|
||||
|
||||
void BfIRBuilder::StructSetBody(BfIRType type, const BfSizedArray<BfIRType>& memberTypes, bool isPacked)
|
||||
{
|
||||
WriteCmd(BfIRCmd_StructSetBody, type, memberTypes, isPacked);
|
||||
|
@ -4421,6 +4428,11 @@ BfIRFunction BfIRBuilder::CreateFunction(BfIRFunctionType funcType, BfIRLinkageT
|
|||
NEW_CMD_INSERTED_IRVALUE;
|
||||
mFunctionMap[name] = retVal;
|
||||
|
||||
if (name == "?TestStructRetCapture$Rt@Lambdas@Tests@bf@@QEAA?AUStructA@123@XZ")
|
||||
{
|
||||
NOP;
|
||||
}
|
||||
|
||||
//BfLogSys(mModule->mSystem, "BfIRBuilder::CreateFunction: %d %s Module:%p\n", retVal.mId, name.c_str(), mModule);
|
||||
|
||||
return retVal;
|
||||
|
|
|
@ -94,10 +94,20 @@ enum BfTypeCode : uint8
|
|||
BfTypeCode_UInt8,
|
||||
BfTypeCode_Int16,
|
||||
BfTypeCode_UInt16,
|
||||
BfTypeCode_Int24,
|
||||
BfTypeCode_UInt24,
|
||||
BfTypeCode_Int32,
|
||||
BfTypeCode_UInt32,
|
||||
BfTypeCode_Int40,
|
||||
BfTypeCode_UInt40,
|
||||
BfTypeCode_Int48,
|
||||
BfTypeCode_UInt48,
|
||||
BfTypeCode_Int56,
|
||||
BfTypeCode_UInt56,
|
||||
BfTypeCode_Int64,
|
||||
BfTypeCode_UInt64,
|
||||
BfTypeCode_Int128,
|
||||
BfTypeCode_UInt128,
|
||||
BfTypeCode_IntPtr,
|
||||
BfTypeCode_UIntPtr,
|
||||
BfTypeCode_IntUnknown,
|
||||
|
@ -152,6 +162,7 @@ enum BfIRCmd : uint8
|
|||
BfIRCmd_SetType,
|
||||
BfIRCmd_SetInstType,
|
||||
BfIRCmd_PrimitiveType,
|
||||
BfIRCmd_CreateAnonymousStruct,
|
||||
BfIRCmd_CreateStruct,
|
||||
BfIRCmd_StructSetBody,
|
||||
BfIRCmd_Type,
|
||||
|
@ -1050,6 +1061,7 @@ public:
|
|||
|
||||
BfIRType GetPrimitiveType(BfTypeCode typeCode);
|
||||
BfIRType CreateStructType(const StringImpl& name);
|
||||
BfIRType CreateStructType(const BfSizedArray<BfIRType>& memberTypes);
|
||||
void StructSetBody(BfIRType type, const BfSizedArray<BfIRType>& memberTypes, bool isPacked);
|
||||
BfIRType MapType(BfType* type, BfIRPopulateType populateType = BfIRPopulateType_Declaration);
|
||||
BfIRType MapTypeInst(BfTypeInstance* typeInst, BfIRPopulateType populateType = BfIRPopulateType_Declaration);
|
||||
|
|
|
@ -434,17 +434,42 @@ llvm::Type* BfIRCodeGen::GetLLVMType(BfTypeCode typeCode, bool& isSigned)
|
|||
case BfTypeCode_UInt16:
|
||||
case BfTypeCode_Char16:
|
||||
return llvm::Type::getInt16Ty(*mLLVMContext);
|
||||
case BfTypeCode_Int24:
|
||||
isSigned = true;
|
||||
return llvm::Type::getIntNTy(*mLLVMContext, 24);
|
||||
case BfTypeCode_UInt24:
|
||||
return llvm::Type::getIntNTy(*mLLVMContext, 24);
|
||||
case BfTypeCode_Int32:
|
||||
isSigned = true;
|
||||
return llvm::Type::getInt32Ty(*mLLVMContext);
|
||||
case BfTypeCode_UInt32:
|
||||
case BfTypeCode_Char32:
|
||||
return llvm::Type::getInt32Ty(*mLLVMContext);
|
||||
case BfTypeCode_Int40:
|
||||
isSigned = true;
|
||||
return llvm::Type::getIntNTy(*mLLVMContext, 40);
|
||||
case BfTypeCode_UInt40:
|
||||
return llvm::Type::getIntNTy(*mLLVMContext, 40);
|
||||
case BfTypeCode_Int48:
|
||||
isSigned = true;
|
||||
return llvm::Type::getIntNTy(*mLLVMContext, 48);
|
||||
case BfTypeCode_UInt48:
|
||||
return llvm::Type::getIntNTy(*mLLVMContext, 48);
|
||||
case BfTypeCode_Int56:
|
||||
isSigned = true;
|
||||
return llvm::Type::getIntNTy(*mLLVMContext, 56);
|
||||
case BfTypeCode_UInt56:
|
||||
return llvm::Type::getIntNTy(*mLLVMContext, 56);
|
||||
case BfTypeCode_Int64:
|
||||
isSigned = true;
|
||||
return llvm::Type::getInt64Ty(*mLLVMContext);
|
||||
case BfTypeCode_UInt64:
|
||||
return llvm::Type::getInt64Ty(*mLLVMContext);
|
||||
case BfTypeCode_Int128:
|
||||
isSigned = true;
|
||||
return llvm::Type::getInt128Ty(*mLLVMContext);
|
||||
case BfTypeCode_UInt128:
|
||||
return llvm::Type::getInt128Ty(*mLLVMContext);
|
||||
case BfTypeCode_IntPtr:
|
||||
BF_FATAL("Illegal");
|
||||
/*isSigned = true;
|
||||
|
@ -1116,6 +1141,13 @@ void BfIRCodeGen::HandleNextCmd()
|
|||
SetResult(curId, GetLLVMType(typeCode, isSigned));
|
||||
}
|
||||
break;
|
||||
case BfIRCmd_CreateAnonymousStruct:
|
||||
{
|
||||
CMD_PARAM(CmdParamVec<llvm::Type*>, members);
|
||||
llvm::StructType* structType = llvm::StructType::get(*mLLVMContext, members);
|
||||
SetResult(curId, structType);
|
||||
}
|
||||
break;
|
||||
case BfIRCmd_CreateStruct:
|
||||
{
|
||||
CMD_PARAM(String, typeName);
|
||||
|
@ -2621,6 +2653,15 @@ void BfIRCodeGen::HandleNextCmd()
|
|||
{
|
||||
((llvm::CallInst*)callInst)->addDereferenceableAttr(argIdx, arg);
|
||||
}
|
||||
else if (attribute == BfIRAttribute_ByVal)
|
||||
{
|
||||
llvm::AttrBuilder B;
|
||||
B.addAttribute(llvm::Attribute::ByVal);
|
||||
B.addAlignmentAttr(arg);
|
||||
auto attrList = ((llvm::CallInst*)callInst)->getAttributes();
|
||||
attrList = attrList.addAttributes(*mLLVMContext, argIdx, B);
|
||||
((llvm::CallInst*)callInst)->setAttributes(attrList);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -2655,6 +2696,15 @@ void BfIRCodeGen::HandleNextCmd()
|
|||
{
|
||||
((llvm::Function*)func)->addDereferenceableAttr(argIdx, arg);
|
||||
}
|
||||
else if (attribute == BfIRAttribute_ByVal)
|
||||
{
|
||||
llvm::AttrBuilder B;
|
||||
B.addAttribute(llvm::Attribute::ByVal);
|
||||
B.addAlignmentAttr(arg);
|
||||
auto attrList = ((llvm::Function*)func)->getAttributes();
|
||||
attrList = attrList.addAttributes(*mLLVMContext, argIdx, B);
|
||||
((llvm::Function*)func)->setAttributes(attrList);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case BfIRCmd_Func_SetParamName:
|
||||
|
|
|
@ -1577,7 +1577,7 @@ void BfMSMangler::Mangle(MangleContext& mangleContext, StringImpl& name, BfType*
|
|||
name += "E";
|
||||
name += "A";
|
||||
}
|
||||
else if (((type->IsGenericTypeInstance()) || (type->IsTuple()) || (type->IsEnum())) && (mangleContext.mInRet))
|
||||
else if (((type->IsGenericTypeInstance()) || (type->IsComposite()) || (type->IsEnum())) && (mangleContext.mInRet))
|
||||
name += "?A";
|
||||
|
||||
Mangle(mangleContext, name, typeInstance, false);
|
||||
|
|
|
@ -1098,9 +1098,8 @@ void BfModule::EnsureIRBuilder(bool dbgVerifyCodeGen)
|
|||
//mBfIRBuilder->mDbgVerifyCodeGen = true;
|
||||
if (
|
||||
(mModuleName == "-")
|
||||
//|| (mModuleName == "Blurg")
|
||||
//|| (mModuleName == "System_Int32")
|
||||
//|| (mModuleName == "Hey_Dude_Bro_TestClass")
|
||||
//|| (mModuleName == "Tests_FuncRefs_Class")
|
||||
//|| (mModuleName == "Tests_FuncRefs")
|
||||
)
|
||||
mBfIRBuilder->mDbgVerifyCodeGen = true;
|
||||
|
||||
|
@ -3993,7 +3992,7 @@ void BfModule::CreateFakeCallerMethod(const String& funcName)
|
|||
SizedArray<BfIRValue, 8> args;
|
||||
BfExprEvaluator exprEvaluator(this);
|
||||
|
||||
if (mCurMethodInstance->HasStructRet())
|
||||
if (mCurMethodInstance->GetStructRetIdx() != -1)
|
||||
{
|
||||
auto retPtrType = CreatePointerType(mCurMethodInstance->mReturnType);
|
||||
exprEvaluator.PushArg(GetDefaultTypedValue(retPtrType, true, BfDefaultValueKind_Const), args);
|
||||
|
@ -4001,7 +4000,7 @@ void BfModule::CreateFakeCallerMethod(const String& funcName)
|
|||
|
||||
if (mCurMethodInstance->HasThis())
|
||||
{
|
||||
auto thisValue = GetDefaultTypedValue(mCurMethodInstance->GetOwner(), true);
|
||||
auto thisValue = GetDefaultTypedValue(mCurMethodInstance->GetOwner(), true, mCurTypeInstance->IsComposite() ? BfDefaultValueKind_Addr : BfDefaultValueKind_Const);
|
||||
exprEvaluator.PushThis(NULL, thisValue, mCurMethodInstance, args);
|
||||
}
|
||||
|
||||
|
@ -12705,7 +12704,7 @@ void BfModule::CreateDIRetVal()
|
|||
{
|
||||
BfType* dbgType = mCurMethodInstance->mReturnType;
|
||||
BfIRValue dbgValue = mCurMethodState->mRetVal.mValue;
|
||||
if (mCurMethodInstance->HasStructRet())
|
||||
if (mCurMethodInstance->GetStructRetIdx() != -1)
|
||||
{
|
||||
BF_ASSERT(mCurMethodState->mRetValAddr);
|
||||
dbgType = CreatePointerType(dbgType);
|
||||
|
@ -13207,11 +13206,11 @@ void BfModule::MarkScopeLeft(BfScopeData* scopeData)
|
|||
|
||||
void BfModule::CreateReturn(BfIRValue val)
|
||||
{
|
||||
if (mCurMethodInstance->HasStructRet())
|
||||
if (mCurMethodInstance->GetStructRetIdx() != -1)
|
||||
{
|
||||
// Store to sret
|
||||
BF_ASSERT(val);
|
||||
mBfIRBuilder->CreateStore(val, mBfIRBuilder->GetArgument(0));
|
||||
mBfIRBuilder->CreateStore(val, mBfIRBuilder->GetArgument(mCurMethodInstance->GetStructRetIdx()));
|
||||
mBfIRBuilder->CreateRetVoid();
|
||||
}
|
||||
else
|
||||
|
@ -13222,14 +13221,18 @@ void BfModule::CreateReturn(BfIRValue val)
|
|||
}
|
||||
else if (mCurMethodInstance->mReturnType->IsStruct())
|
||||
{
|
||||
auto loweredType = GetPrimitiveType(mCurMethodInstance->mReturnType->GetLoweredType());
|
||||
auto ptrReturnType = CreatePointerType(mCurMethodInstance->mReturnType);
|
||||
auto ptrLoweredValue = CreateAlloca(loweredType);
|
||||
auto ptrReturnValue = mBfIRBuilder->CreateBitCast(ptrLoweredValue, mBfIRBuilder->MapType(ptrReturnType));
|
||||
mBfIRBuilder->CreateStore(val, ptrReturnValue);
|
||||
BfTypeCode loweredReturnType = BfTypeCode_None;
|
||||
BfTypeCode loweredReturnType2 = BfTypeCode_None;
|
||||
mCurMethodInstance->GetLoweredReturnType(&loweredReturnType, &loweredReturnType2);
|
||||
|
||||
auto loadedLoweredValue = mBfIRBuilder->CreateLoad(ptrLoweredValue);
|
||||
mBfIRBuilder->CreateRet(loadedLoweredValue);
|
||||
auto retVal = CreateAlloca(mCurMethodInstance->mReturnType);
|
||||
mBfIRBuilder->CreateStore(val, retVal);
|
||||
|
||||
auto irRetType = GetIRLoweredType(loweredReturnType, loweredReturnType2);
|
||||
irRetType = mBfIRBuilder->GetPointerTo(irRetType);
|
||||
auto ptrReturnValue = mBfIRBuilder->CreateBitCast(retVal, irRetType);
|
||||
auto loadedReturnValue = mBfIRBuilder->CreateLoad(ptrReturnValue);
|
||||
mBfIRBuilder->CreateRet(loadedReturnValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -13286,7 +13289,7 @@ void BfModule::EmitDefaultReturn()
|
|||
{
|
||||
if (mCurMethodInstance->mReturnType->IsVoid())
|
||||
mBfIRBuilder->CreateRetVoid();
|
||||
else if (!mCurMethodInstance->HasStructRet())
|
||||
else if (mCurMethodInstance->GetStructRetIdx() == -1)
|
||||
mBfIRBuilder->CreateRet(GetDefaultValue(mCurMethodInstance->mReturnType));
|
||||
}
|
||||
|
||||
|
@ -13395,14 +13398,18 @@ void BfModule::CreateDelegateInvokeMethod()
|
|||
if (mCurMethodInstance->mReturnType->IsValueType())
|
||||
mBfIRBuilder->PopulateType(mCurMethodInstance->mReturnType, BfIRPopulateType_Full);
|
||||
|
||||
if (mCurMethodInstance->GetStructRetIdx() != 0)
|
||||
memberFuncArgs.push_back(BfIRValue()); // Push 'target'
|
||||
|
||||
int thisIdx = 0;
|
||||
if (mCurMethodInstance->HasStructRet())
|
||||
if (mCurMethodInstance->GetStructRetIdx() != -1)
|
||||
{
|
||||
thisIdx = 1;
|
||||
staticFuncArgs.push_back(mBfIRBuilder->GetArgument(0));
|
||||
memberFuncArgs.push_back(mBfIRBuilder->GetArgument(0));
|
||||
thisIdx = mCurMethodInstance->GetStructRetIdx() ^ 1;
|
||||
staticFuncArgs.push_back(mBfIRBuilder->GetArgument(mCurMethodInstance->GetStructRetIdx()));
|
||||
memberFuncArgs.push_back(mBfIRBuilder->GetArgument(mCurMethodInstance->GetStructRetIdx()));
|
||||
}
|
||||
|
||||
if (mCurMethodInstance->GetStructRetIdx() == 0)
|
||||
memberFuncArgs.push_back(BfIRValue()); // Push 'target'
|
||||
|
||||
mCurMethodInstance->GetIRFunctionInfo(this, origReturnType, staticParamTypes, true);
|
||||
|
@ -13441,8 +13448,8 @@ void BfModule::CreateDelegateInvokeMethod()
|
|||
auto funcPtrPtr = mBfIRBuilder->CreateBitCast(fieldPtr, memberFuncPtrPtr);
|
||||
auto funcPtr = mBfIRBuilder->CreateLoad(funcPtrPtr);
|
||||
nonStaticResult = mBfIRBuilder->CreateCall(funcPtr, memberFuncArgs);
|
||||
if (mCurMethodInstance->HasStructRet())
|
||||
mBfIRBuilder->Call_AddAttribute(nonStaticResult, 1, BfIRAttribute_StructRet);
|
||||
if (mCurMethodInstance->GetStructRetIdx() != -1)
|
||||
mBfIRBuilder->Call_AddAttribute(nonStaticResult, mCurMethodInstance->GetStructRetIdx() + 1, BfIRAttribute_StructRet);
|
||||
if (callingConv != BfIRCallingConv_CDecl)
|
||||
mBfIRBuilder->SetCallCallingConv(nonStaticResult, callingConv);
|
||||
mCurMethodState->SetHadReturn(false);
|
||||
|
@ -13459,8 +13466,11 @@ void BfModule::CreateDelegateInvokeMethod()
|
|||
auto funcPtrPtr = mBfIRBuilder->CreateBitCast(fieldPtr, staticFuncPtrPtr);
|
||||
auto funcPtr = mBfIRBuilder->CreateLoad(funcPtrPtr);
|
||||
staticResult = mBfIRBuilder->CreateCall(funcPtr, staticFuncArgs);
|
||||
if (mCurMethodInstance->HasStructRet())
|
||||
mBfIRBuilder->Call_AddAttribute(staticResult, 1, BfIRAttribute_StructRet);
|
||||
if (mCurMethodInstance->GetStructRetIdx() != -1)
|
||||
{
|
||||
// Note: since this is a forced static invocation, we know the sret will be the first parameter
|
||||
mBfIRBuilder->Call_AddAttribute(staticResult, 0 + 1, BfIRAttribute_StructRet);
|
||||
}
|
||||
if (callingConv == BfIRCallingConv_ThisCall)
|
||||
callingConv = BfIRCallingConv_CDecl;
|
||||
if (callingConv != BfIRCallingConv_CDecl)
|
||||
|
@ -13473,16 +13483,20 @@ void BfModule::CreateDelegateInvokeMethod()
|
|||
|
||||
mBfIRBuilder->AddBlock(doneBB);
|
||||
mBfIRBuilder->SetInsertPoint(doneBB);
|
||||
if ((mCurMethodInstance->mReturnType->IsValuelessType()) || (mCurMethodInstance->HasStructRet()))
|
||||
if ((mCurMethodInstance->mReturnType->IsValuelessType()) || (mCurMethodInstance->GetStructRetIdx() != -1))
|
||||
{
|
||||
mBfIRBuilder->CreateRetVoid();
|
||||
}
|
||||
else
|
||||
{
|
||||
auto loweredReturnType = mCurMethodInstance->mReturnType;
|
||||
if (loweredReturnType->GetLoweredType() != BfTypeCode_None)
|
||||
loweredReturnType = GetPrimitiveType(loweredReturnType->GetLoweredType());
|
||||
auto phi = mBfIRBuilder->CreatePhi(mBfIRBuilder->MapType(loweredReturnType), 2);
|
||||
BfIRType loweredIRReturnType;
|
||||
BfTypeCode loweredTypeCode = BfTypeCode_None;
|
||||
BfTypeCode loweredTypeCode2 = BfTypeCode_None;
|
||||
if (mCurMethodInstance->GetLoweredReturnType(&loweredTypeCode, &loweredTypeCode2))
|
||||
loweredIRReturnType = GetIRLoweredType(loweredTypeCode, loweredTypeCode2);
|
||||
else
|
||||
loweredIRReturnType = mBfIRBuilder->MapType(mCurMethodInstance->mReturnType);
|
||||
auto phi = mBfIRBuilder->CreatePhi(loweredIRReturnType, 2);
|
||||
mBfIRBuilder->AddPhiIncoming(phi, nonStaticResult, trueBB);
|
||||
mBfIRBuilder->AddPhiIncoming(phi, staticResult, falseBB);
|
||||
mBfIRBuilder->CreateRet(phi);
|
||||
|
@ -14365,21 +14379,24 @@ void BfModule::SetupIRMethod(BfMethodInstance* methodInstance, BfIRFunction func
|
|||
|
||||
int argCount = methodInstance->GetIRFunctionParamCount(this);
|
||||
|
||||
if (methodInstance->HasStructRet())
|
||||
while (argIdx < argCount)
|
||||
{
|
||||
if (argIdx == methodInstance->GetStructRetIdx())
|
||||
{
|
||||
mBfIRBuilder->Func_AddAttribute(func, argIdx + 1, BfIRAttribute_NoAlias);
|
||||
mBfIRBuilder->Func_AddAttribute(func, argIdx + 1, BfIRAttribute_StructRet);
|
||||
argIdx++;
|
||||
continue;
|
||||
}
|
||||
|
||||
while (argIdx < argCount)
|
||||
{
|
||||
while ((paramIdx != -1) && (methodInstance->IsParamSkipped(paramIdx)))
|
||||
paramIdx++;
|
||||
|
||||
BfType* resolvedTypeRef = NULL;
|
||||
BfType* resolvedTypeRef2 = NULL;
|
||||
String paramName;
|
||||
bool isSplattable = false;
|
||||
bool tryLowering = true;
|
||||
bool isThis = paramIdx == -1;
|
||||
if (isThis)
|
||||
{
|
||||
|
@ -14389,6 +14406,7 @@ void BfModule::SetupIRMethod(BfMethodInstance* methodInstance, BfIRFunction func
|
|||
else
|
||||
resolvedTypeRef = methodInstance->GetOwner();
|
||||
isSplattable = (resolvedTypeRef->IsSplattable()) && (methodInstance->AllowsThisSplatting());
|
||||
tryLowering = methodInstance->AllowsThisSplatting();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -14409,11 +14427,24 @@ void BfModule::SetupIRMethod(BfMethodInstance* methodInstance, BfIRFunction func
|
|||
}
|
||||
}
|
||||
|
||||
//
|
||||
if (tryLowering)
|
||||
{
|
||||
auto loweredTypeCode = resolvedTypeRef->GetLoweredType();
|
||||
if (loweredTypeCode != BfTypeCode_None)
|
||||
resolvedTypeRef = GetPrimitiveType(loweredTypeCode);
|
||||
BfTypeCode loweredTypeCode = BfTypeCode_None;
|
||||
BfTypeCode loweredTypeCode2 = BfTypeCode_None;
|
||||
if (resolvedTypeRef->GetLoweredType(BfTypeUsage_Parameter, &loweredTypeCode, &loweredTypeCode2))
|
||||
{
|
||||
mBfIRBuilder->Func_SetParamName(func, argIdx + 1, paramName + "__1");
|
||||
argIdx++;
|
||||
|
||||
if (loweredTypeCode2 != BfTypeCode_None)
|
||||
{
|
||||
mBfIRBuilder->Func_SetParamName(func, argIdx + 1, paramName + "__2");
|
||||
argIdx++;
|
||||
}
|
||||
|
||||
paramIdx++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
auto _SetupParam = [&](const StringImpl& paramName, BfType* resolvedTypeRef)
|
||||
|
@ -14432,16 +14463,17 @@ void BfModule::SetupIRMethod(BfMethodInstance* methodInstance, BfIRFunction func
|
|||
}
|
||||
if ((resolvedTypeRef->IsComposite()) && (!resolvedTypeRef->IsTypedPrimitive()))
|
||||
{
|
||||
if (mCompiler->mOptions.mAllowStructByVal)
|
||||
{
|
||||
mBfIRBuilder->Func_AddAttribute(func, argIdx + 1, BfIRAttribute_ByVal);
|
||||
}
|
||||
else
|
||||
if (paramIdx == -1)
|
||||
{
|
||||
mBfIRBuilder->Func_AddAttribute(func, argIdx + 1, BfIRAttribute_NoCapture);
|
||||
PopulateType(resolvedTypeRef, BfPopulateType_Data);
|
||||
addDeref = resolvedTypeRef->mSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
mBfIRBuilder->PopulateType(resolvedTypeRef);
|
||||
mBfIRBuilder->Func_AddAttribute(func, argIdx + 1, BfIRAttribute_ByVal, mSystem->mPtrSize);
|
||||
}
|
||||
}
|
||||
else if (resolvedTypeRef->IsPrimitiveType())
|
||||
{
|
||||
|
@ -14521,8 +14553,9 @@ void BfModule::SetupIRMethod(BfMethodInstance* methodInstance, BfIRFunction func
|
|||
}
|
||||
|
||||
_SetupParam(paramName, resolvedTypeRef);
|
||||
if (resolvedTypeRef2 != NULL)
|
||||
_SetupParam(paramName, resolvedTypeRef2);
|
||||
|
||||
//argIdx++;
|
||||
paramIdx++;
|
||||
}
|
||||
}
|
||||
|
@ -15412,11 +15445,15 @@ void BfModule::ProcessMethod_SetupParams(BfMethodInstance* methodInstance, BfTyp
|
|||
isThisStruct = thisType->IsStruct() && !thisType->IsTypedPrimitive();
|
||||
|
||||
int argIdx = 0;
|
||||
if (methodInstance->HasStructRet())
|
||||
|
||||
if (argIdx == methodInstance->GetStructRetIdx())
|
||||
argIdx++;
|
||||
|
||||
if (!methodDef->mIsStatic)
|
||||
{
|
||||
BfTypeCode loweredTypeCode = BfTypeCode_None;
|
||||
BfTypeCode loweredTypeCode2 = BfTypeCode_None;
|
||||
|
||||
BfLocalVariable* paramVar = new BfLocalVariable();
|
||||
paramVar->mResolvedType = thisType;
|
||||
paramVar->mName = "this";
|
||||
|
@ -15431,7 +15468,7 @@ void BfModule::ProcessMethod_SetupParams(BfMethodInstance* methodInstance, BfTyp
|
|||
paramVar->mIsSplat = true;
|
||||
}
|
||||
else if ((!methodDef->mIsMutating) && (methodInstance->mCallingConvention == BfCallingConvention_Unspecified))
|
||||
paramVar->mIsLowered = thisType->GetLoweredType() != BfTypeCode_None;
|
||||
paramVar->mIsLowered = thisType->GetLoweredType(BfTypeUsage_Parameter, &loweredTypeCode, &loweredTypeCode2) != BfTypeCode_None;
|
||||
|
||||
auto thisTypeInst = thisType->ToTypeInstance();
|
||||
paramVar->mIsStruct = isThisStruct;
|
||||
|
@ -15472,8 +15509,14 @@ void BfModule::ProcessMethod_SetupParams(BfMethodInstance* methodInstance, BfTyp
|
|||
argIdx++;
|
||||
}
|
||||
}
|
||||
|
||||
if (loweredTypeCode2 != BfTypeCode_None)
|
||||
argIdx++;
|
||||
}
|
||||
|
||||
if (argIdx == methodInstance->GetStructRetIdx())
|
||||
argIdx++;
|
||||
|
||||
bool hadParams = false;
|
||||
bool hasDefault = false;
|
||||
|
||||
|
@ -15485,6 +15528,9 @@ void BfModule::ProcessMethod_SetupParams(BfMethodInstance* methodInstance, BfTyp
|
|||
SetAndRestoreValue<bool> prevIgnoreErrors(mIgnoreErrors, true);
|
||||
BfLocalVariable* paramVar = new BfLocalVariable();
|
||||
|
||||
BfTypeCode loweredTypeCode = BfTypeCode_None;
|
||||
BfTypeCode loweredTypeCode2 = BfTypeCode_None;
|
||||
|
||||
bool isParamSkipped = methodInstance->IsParamSkipped(paramIdx);
|
||||
|
||||
BfType* unresolvedType = methodInstance->GetParamType(paramIdx, false);
|
||||
|
@ -15529,7 +15575,7 @@ void BfModule::ProcessMethod_SetupParams(BfMethodInstance* methodInstance, BfTyp
|
|||
paramVar->mIsSplat = true; // Treat skipped (valueless) as a splat
|
||||
paramVar->mValue = mBfIRBuilder->GetFakeVal();
|
||||
}
|
||||
paramVar->mIsLowered = resolvedType->GetLoweredType() != BfTypeCode_None;
|
||||
paramVar->mIsLowered = resolvedType->GetLoweredType(BfTypeUsage_Parameter, &loweredTypeCode, &loweredTypeCode2) != BfTypeCode_None;
|
||||
paramVar->mIsStruct = resolvedType->IsComposite() && !resolvedType->IsTypedPrimitive();
|
||||
paramVar->mParamIdx = paramIdx;
|
||||
paramVar->mIsImplicitParam = methodInstance->IsImplicitCapture(paramIdx);
|
||||
|
@ -15639,6 +15685,9 @@ void BfModule::ProcessMethod_SetupParams(BfMethodInstance* methodInstance, BfTyp
|
|||
{
|
||||
argIdx++;
|
||||
}
|
||||
|
||||
if (loweredTypeCode2 != BfTypeCode_None)
|
||||
argIdx++;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16755,9 +16804,6 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
|
|||
int localIdx = 0;
|
||||
int argIdx = 0;
|
||||
|
||||
if (methodInstance->HasStructRet())
|
||||
argIdx++;
|
||||
|
||||
Array<BfIRValue> splatAddrValues;
|
||||
|
||||
for ( ; argIdx < irParamCount; localIdx++)
|
||||
|
@ -16766,6 +16812,13 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
|
|||
if ((isThis) && (thisType->IsValuelessType()))
|
||||
isThis = false;
|
||||
|
||||
if (methodInstance->GetStructRetIdx() == argIdx)
|
||||
{
|
||||
argIdx++;
|
||||
if (argIdx == irParamCount)
|
||||
break;
|
||||
}
|
||||
|
||||
BfLocalVariable* paramVar = NULL;
|
||||
while (true)
|
||||
{
|
||||
|
@ -16782,7 +16835,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
|
|||
paramVar->mIsReadOnly = true;
|
||||
}
|
||||
|
||||
bool wantsAddr = (wantsDIVariables) || (!paramVar->mIsReadOnly) || (paramVar->mResolvedType->GetLoweredType() != BfTypeCode_None);
|
||||
bool wantsAddr = (wantsDIVariables) || (!paramVar->mIsReadOnly) || (paramVar->mResolvedType->GetLoweredType(BfTypeUsage_Parameter));
|
||||
|
||||
if (paramVar->mResolvedType->IsMethodRef())
|
||||
wantsAddr = false;
|
||||
|
@ -16895,6 +16948,15 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
|
|||
{
|
||||
BfTypeUtils::SplatIterate([&](BfType* checkType) { argIdx++; }, paramVar->mResolvedType);
|
||||
}
|
||||
else if (paramVar->mIsLowered)
|
||||
{
|
||||
BfTypeCode loweredTypeCode = BfTypeCode_None;
|
||||
BfTypeCode loweredTypeCode2 = BfTypeCode_None;
|
||||
paramVar->mResolvedType->GetLoweredType(BfTypeUsage_Parameter, &loweredTypeCode, &loweredTypeCode2);
|
||||
argIdx++;
|
||||
if (loweredTypeCode2 != BfTypeCode_None)
|
||||
argIdx++;
|
||||
}
|
||||
else
|
||||
{
|
||||
argIdx++;
|
||||
|
@ -16909,12 +16971,13 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
|
|||
int declArgIdx = 0;
|
||||
localIdx = 0;
|
||||
argIdx = 0;
|
||||
if (methodInstance->HasStructRet())
|
||||
argIdx++;
|
||||
|
||||
int splatAddrIdx = 0;
|
||||
while (localIdx < (int)methodState.mLocals.size())
|
||||
{
|
||||
if (argIdx == methodInstance->GetStructRetIdx())
|
||||
argIdx++;
|
||||
|
||||
int curLocalIdx = localIdx++;
|
||||
BfLocalVariable* paramVar = methodState.mLocals[curLocalIdx];
|
||||
if (!paramVar->IsParam())
|
||||
|
@ -17010,19 +17073,34 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
|
|||
bool handled = false;
|
||||
if (paramVar->mIsLowered)
|
||||
{
|
||||
auto loweredTypeCode = paramVar->mResolvedType->GetLoweredType();
|
||||
BF_ASSERT(loweredTypeCode != BfTypeCode_None);
|
||||
if (loweredTypeCode != BfTypeCode_None)
|
||||
BfTypeCode loweredTypeCode = BfTypeCode_None;
|
||||
BfTypeCode loweredTypeCode2 = BfTypeCode_None;
|
||||
if (paramVar->mResolvedType->GetLoweredType(BfTypeUsage_Parameter, &loweredTypeCode, &loweredTypeCode2))
|
||||
{
|
||||
// We have a lowered type coming in, so we have to cast the .addr before storing
|
||||
auto primType = GetPrimitiveType(loweredTypeCode);
|
||||
auto primPtrType = CreatePointerType(primType);
|
||||
auto primPtrVal = mBfIRBuilder->CreateBitCast(paramVar->mAddr, mBfIRBuilder->MapType(primPtrType));
|
||||
mBfIRBuilder->CreateAlignedStore(paramVar->mValue, primPtrVal, paramVar->mResolvedType->mSize);
|
||||
auto primType = mBfIRBuilder->GetPrimitiveType(loweredTypeCode);
|
||||
auto primPtrType = mBfIRBuilder->GetPointerTo(primType);
|
||||
auto primPtrVal = mBfIRBuilder->CreateBitCast(paramVar->mAddr, primPtrType);
|
||||
mBfIRBuilder->CreateStore(paramVar->mValue, primPtrVal);
|
||||
|
||||
if (loweredTypeCode2 != BfTypeCode_None)
|
||||
{
|
||||
declArgIdx++;
|
||||
|
||||
auto primType2 = mBfIRBuilder->GetPrimitiveType(loweredTypeCode2);
|
||||
auto primPtrType2 = mBfIRBuilder->GetPointerTo(primType2);
|
||||
auto primPtrVal2 = mBfIRBuilder->CreateBitCast(mBfIRBuilder->CreateInBoundsGEP(primPtrVal, 1), primPtrType2);
|
||||
mBfIRBuilder->CreateStore(mBfIRBuilder->GetArgument(argIdx + 1), primPtrVal2);
|
||||
}
|
||||
|
||||
// We don't want to allow directly using value
|
||||
paramVar->mValue = BfIRValue();
|
||||
handled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
BF_ASSERT("Expected lowered");
|
||||
}
|
||||
}
|
||||
|
||||
if (!handled)
|
||||
|
@ -17190,6 +17268,15 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
|
|||
{
|
||||
BfTypeUtils::SplatIterate([&](BfType* checkType) { argIdx++; }, paramVar->mResolvedType);
|
||||
}
|
||||
else if (paramVar->mIsLowered)
|
||||
{
|
||||
argIdx++;
|
||||
BfTypeCode loweredTypeCode = BfTypeCode_None;
|
||||
BfTypeCode loweredTypeCode2 = BfTypeCode_None;
|
||||
paramVar->mResolvedType->GetLoweredType(BfTypeUsage_Parameter, &loweredTypeCode, &loweredTypeCode2);
|
||||
if (loweredTypeCode != BfTypeCode_None)
|
||||
argIdx++;
|
||||
}
|
||||
else if (!paramVar->mResolvedType->IsValuelessType())
|
||||
{
|
||||
argIdx++;
|
||||
|
@ -17322,10 +17409,10 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
|
|||
{
|
||||
BF_ASSERT(innerType->IsUnspecializedType());
|
||||
}
|
||||
else if (methodInstance->HasStructRet())
|
||||
else if (methodInstance->GetStructRetIdx() != -1)
|
||||
{
|
||||
mBfIRBuilder->PopulateType(methodInstance->mReturnType);
|
||||
auto returnType = BfTypedValue(mBfIRBuilder->GetArgument(0), methodInstance->mReturnType, true);
|
||||
auto returnType = BfTypedValue(mBfIRBuilder->GetArgument(methodInstance->GetStructRetIdx()), methodInstance->mReturnType, true);
|
||||
exprEvaluator.mReceivingValue = &returnType;
|
||||
auto retVal = exprEvaluator.CreateCall(innerMethodInstance.mMethodInstance, innerMethodInstance.mFunc, true, innerParams, NULL, true);
|
||||
BF_ASSERT(exprEvaluator.mReceivingValue == NULL); // Ensure it was actually used
|
||||
|
@ -17692,11 +17779,11 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
|
|||
{
|
||||
mBfIRBuilder->PopulateType(mCurMethodInstance->mReturnType);
|
||||
|
||||
if (mCurMethodInstance->HasStructRet())
|
||||
if (mCurMethodInstance->GetStructRetIdx() != -1)
|
||||
{
|
||||
auto ptrType = CreatePointerType(mCurMethodInstance->mReturnType);
|
||||
auto allocaInst = AllocLocalVariable(ptrType, "__return.addr", false);
|
||||
auto storeInst = mBfIRBuilder->CreateStore(mBfIRBuilder->GetArgument(0), allocaInst);
|
||||
auto storeInst = mBfIRBuilder->CreateStore(mBfIRBuilder->GetArgument(mCurMethodInstance->GetStructRetIdx()), allocaInst);
|
||||
mBfIRBuilder->ClearDebugLocation(storeInst);
|
||||
mCurMethodState->mRetValAddr = allocaInst;
|
||||
}
|
||||
|
@ -17886,7 +17973,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
|
|||
|
||||
if (mCurMethodState->mIRExitBlock)
|
||||
{
|
||||
if ((mCurMethodState->mRetVal) && (!mCurMethodInstance->HasStructRet()))
|
||||
if ((mCurMethodState->mRetVal) && (mCurMethodInstance->GetStructRetIdx() == -1))
|
||||
{
|
||||
auto loadedVal = mBfIRBuilder->CreateLoad(mCurMethodState->mRetVal.mValue);
|
||||
|
||||
|
@ -19914,8 +20001,6 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool
|
|||
|
||||
int argIdx = 0;
|
||||
PopulateType(methodInstance->mReturnType, BfPopulateType_Data);
|
||||
if (methodInstance->HasStructRet())
|
||||
argIdx++;
|
||||
if (!methodDef->mIsStatic)
|
||||
{
|
||||
if (methodInstance->GetParamIsSplat(-1))
|
||||
|
@ -19923,6 +20008,10 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool
|
|||
else if (!methodInstance->GetOwner()->IsValuelessType())
|
||||
argIdx++;
|
||||
}
|
||||
|
||||
if (methodInstance->GetStructRetIdx() != -1)
|
||||
argIdx++;
|
||||
|
||||
for (auto& methodParam : mCurMethodInstance->mParams)
|
||||
{
|
||||
if (methodParam.mResolvedType->IsMethodRef())
|
||||
|
|
|
@ -1631,6 +1631,7 @@ public:
|
|||
BfTypeInstance* GetWrappedStructType(BfType* type, bool allowSpecialized = true);
|
||||
BfTypeInstance* GetPrimitiveStructType(BfTypeCode typeCode);
|
||||
BfPrimitiveType* GetPrimitiveType(BfTypeCode typeCode);
|
||||
BfIRType GetIRLoweredType(BfTypeCode loweredTypeCode, BfTypeCode loweredTypeCode2);
|
||||
BfMethodRefType* CreateMethodRefType(BfMethodInstance* methodInstance, bool mustAlreadyExist = false);
|
||||
BfType* FixIntUnknown(BfType* type);
|
||||
void FixIntUnknown(BfTypedValue& typedVal, BfType* matchType = NULL);
|
||||
|
|
|
@ -3136,37 +3136,6 @@ bool BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
|||
if (isCRepr)
|
||||
{
|
||||
typeInstance->mIsSplattable = false;
|
||||
|
||||
if ((mCompiler->mOptions.mPlatformType == BfPlatformType_Windows) && (mCompiler->mSystem->mPtrSize == 4))
|
||||
{
|
||||
// Win32 splat rules
|
||||
if ((typeInstance->mBaseType->mInstSize == 0) && (typeInstance->mInstSize <= 16))
|
||||
{
|
||||
typeInstance->mIsSplattable = true;
|
||||
|
||||
for (int fieldIdx = 0; fieldIdx < (int)typeInstance->mFieldInstances.size(); fieldIdx++)
|
||||
{
|
||||
auto fieldInstance = (BfFieldInstance*)&typeInstance->mFieldInstances[fieldIdx];
|
||||
if (fieldInstance->mDataIdx >= 0)
|
||||
{
|
||||
if (!fieldInstance->mResolvedType->IsPrimitiveType())
|
||||
typeInstance->mIsSplattable = false;
|
||||
else
|
||||
{
|
||||
auto primType = (BfPrimitiveType*)fieldInstance->mResolvedType;
|
||||
if ((primType->mTypeDef->mTypeCode != BfTypeCode_Int32) &&
|
||||
(primType->mTypeDef->mTypeCode != BfTypeCode_UInt32) &&
|
||||
(primType->mTypeDef->mTypeCode != BfTypeCode_IntPtr) &&
|
||||
(primType->mTypeDef->mTypeCode != BfTypeCode_UIntPtr) &&
|
||||
(primType->mTypeDef->mTypeCode != BfTypeCode_Pointer) &&
|
||||
(primType->mTypeDef->mTypeCode != BfTypeCode_Single) &&
|
||||
(primType->mTypeDef->mTypeCode != BfTypeCode_Double))
|
||||
typeInstance->mIsSplattable = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
typeInstance->mIsSplattable = (dataCount <= 3) && (!hadNonSplattable);
|
||||
|
@ -4736,6 +4705,18 @@ BfPrimitiveType* BfModule::GetPrimitiveType(BfTypeCode typeCode)
|
|||
return primType;
|
||||
}
|
||||
|
||||
BfIRType BfModule::GetIRLoweredType(BfTypeCode loweredTypeCode, BfTypeCode loweredTypeCode2)
|
||||
{
|
||||
BF_ASSERT(loweredTypeCode != BfTypeCode_None);
|
||||
if (loweredTypeCode2 == BfTypeCode_None)
|
||||
return mBfIRBuilder->GetPrimitiveType(loweredTypeCode);
|
||||
|
||||
SizedArray<BfIRType, 2> types;
|
||||
types.push_back(mBfIRBuilder->GetPrimitiveType(loweredTypeCode));
|
||||
types.push_back(mBfIRBuilder->GetPrimitiveType(loweredTypeCode2));
|
||||
return mBfIRBuilder->CreateStructType(types);
|
||||
}
|
||||
|
||||
BfMethodRefType* BfModule::CreateMethodRefType(BfMethodInstance* methodInstance, bool mustAlreadyExist)
|
||||
{
|
||||
auto methodRefType = new BfMethodRefType();
|
||||
|
@ -7803,6 +7784,10 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
|
|||
genericTypeInst = new BfTypeInstance();
|
||||
genericTypeInst->mGenericTypeInfo = new BfGenericTypeInfo();
|
||||
genericTypeInst->mTypeDef = typeDef;
|
||||
|
||||
if (parentGenericTypeInstance->mGenericTypeInfo->mGenericParams.IsEmpty())
|
||||
PopulateType(parentGenericTypeInstance, BfPopulateType_Declaration);
|
||||
|
||||
for (int i = 0; i < numParentGenericParams; i++)
|
||||
{
|
||||
genericTypeInst->mGenericTypeInfo->mGenericParams.push_back(parentGenericTypeInstance->mGenericTypeInfo->mGenericParams[i]->AddRef());
|
||||
|
|
|
@ -7370,6 +7370,7 @@ BfObjectCreateExpression* BfReducer::CreateObjectCreateExpression(BfAstNode* all
|
|||
SetAndRestoreValue<BfVisitorPos> prevVisitorPos(mVisitorPos, BfVisitorPos(block));
|
||||
ReadArguments(objectCreateExpr, objectCreateExpr, &arguments, &commas, BfToken_None, true);
|
||||
}
|
||||
if (block->mCloseBrace != NULL)
|
||||
MEMBER_SET(objectCreateExpr, mCloseToken, block->mCloseBrace);
|
||||
return objectCreateExpr;
|
||||
}
|
||||
|
|
|
@ -611,9 +611,24 @@ bool BfMethodInstance::HasParamsArray()
|
|||
return GetParamKind((int)mParams.size() - 1) == BfParamKind_Params;
|
||||
}
|
||||
|
||||
bool BfMethodInstance::HasStructRet()
|
||||
int BfMethodInstance::GetStructRetIdx()
|
||||
{
|
||||
return (mReturnType->IsComposite()) && (!mReturnType->IsValuelessType()) && (mReturnType->GetLoweredType() == BfTypeCode_None);
|
||||
if ((mReturnType->IsComposite()) && (!mReturnType->IsValuelessType()) && (!GetLoweredReturnType()))
|
||||
{
|
||||
auto owner = mMethodInstanceGroup->mOwner;
|
||||
if (owner->mModule->mCompiler->mOptions.mPlatformType != BfPlatformType_Windows)
|
||||
return 0;
|
||||
|
||||
if (!HasThis())
|
||||
return 0;
|
||||
if (!owner->IsValueType())
|
||||
return 1;
|
||||
if ((mMethodDef->mIsMutating) || ((!AllowsSplatting()) && (!owner->GetLoweredType(BfTypeUsage_Parameter))))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool BfMethodInstance::HasSelf()
|
||||
|
@ -626,6 +641,11 @@ bool BfMethodInstance::HasSelf()
|
|||
return false;
|
||||
}
|
||||
|
||||
bool BfMethodInstance::GetLoweredReturnType(BfTypeCode* loweredTypeCode, BfTypeCode* loweredTypeCode2)
|
||||
{
|
||||
return mReturnType->GetLoweredType(mMethodDef->mIsStatic ? BfTypeUsage_Return_Static : BfTypeUsage_Return_NonStatic, loweredTypeCode, loweredTypeCode2);
|
||||
}
|
||||
|
||||
bool BfMethodInstance::IsSkipCall(bool bypassVirtual)
|
||||
{
|
||||
if ((mMethodDef->mIsSkipCall) &&
|
||||
|
@ -743,7 +763,7 @@ BfType* BfMethodInstance::GetParamType(int paramIdx, bool useResolvedType)
|
|||
return mMethodInfoEx->mClosureInstanceInfo->mThisOverride;
|
||||
BF_ASSERT(!mMethodDef->mIsStatic);
|
||||
auto owner = mMethodInstanceGroup->mOwner;
|
||||
if ((owner->IsValueType()) && ((mMethodDef->mIsMutating) || (!AllowsSplatting())) && (owner->GetLoweredType() == BfTypeCode_None))
|
||||
if ((owner->IsValueType()) && ((mMethodDef->mIsMutating) || (!AllowsSplatting())) && (!owner->GetLoweredType(BfTypeUsage_Parameter)))
|
||||
return owner->mModule->CreatePointerType(owner);
|
||||
return owner;
|
||||
}
|
||||
|
@ -849,8 +869,6 @@ BfIdentifierNode* BfMethodInstance::GetParamNameNode(int paramIdx)
|
|||
BfParameterDef* paramDef = mMethodDef->mParams[methodParam->mParamDefIdx];
|
||||
if (paramDef->mParamDeclaration != NULL)
|
||||
return BfNodeDynCast<BfIdentifierNode>(paramDef->mParamDeclaration->mNameNode);
|
||||
// else if ((mClosureInstanceInfo != NULL) && (paramIdx < (int)mClosureInstanceInfo->mCaptureNodes.size()))
|
||||
// return mClosureInstanceInfo->mCaptureNodes[paramIdx];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -897,34 +915,36 @@ void BfMethodInstance::GetIRFunctionInfo(BfModule* module, BfIRType& returnType,
|
|||
{
|
||||
module->PopulateType(mReturnType);
|
||||
|
||||
BfType* loweredReturnType = mReturnType;
|
||||
auto loweredReturnTypeCode = mReturnType->GetLoweredType();
|
||||
if (loweredReturnTypeCode != BfTypeCode_None)
|
||||
loweredReturnType = module->GetPrimitiveType(loweredReturnTypeCode);
|
||||
|
||||
if (loweredReturnType->IsValuelessType())
|
||||
BfTypeCode loweredReturnTypeCode = BfTypeCode_None;
|
||||
BfTypeCode loweredReturnTypeCode2 = BfTypeCode_None;
|
||||
if (GetLoweredReturnType(&loweredReturnTypeCode, &loweredReturnTypeCode2))
|
||||
{
|
||||
auto irReturnType = module->GetIRLoweredType(loweredReturnTypeCode, loweredReturnTypeCode2);
|
||||
returnType = irReturnType;
|
||||
}
|
||||
else if (mReturnType->IsValuelessType())
|
||||
{
|
||||
auto voidType = module->GetPrimitiveType(BfTypeCode_None);
|
||||
returnType = module->mBfIRBuilder->MapType(voidType);
|
||||
}
|
||||
else if (loweredReturnType->IsComposite())
|
||||
else if (mReturnType->IsComposite())
|
||||
{
|
||||
auto voidType = module->GetPrimitiveType(BfTypeCode_None);
|
||||
returnType = module->mBfIRBuilder->MapType(voidType);
|
||||
auto typeInst = loweredReturnType->ToTypeInstance();
|
||||
auto typeInst = mReturnType->ToTypeInstance();
|
||||
if (typeInst != NULL)
|
||||
{
|
||||
paramTypes.push_back(module->mBfIRBuilder->MapTypeInstPtr(typeInst));
|
||||
}
|
||||
else
|
||||
{
|
||||
auto ptrType = module->CreatePointerType(loweredReturnType);
|
||||
auto ptrType = module->CreatePointerType(mReturnType);
|
||||
paramTypes.push_back(module->mBfIRBuilder->MapType(ptrType));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
returnType = module->mBfIRBuilder->MapType(loweredReturnType);
|
||||
returnType = module->mBfIRBuilder->MapType(mReturnType);
|
||||
}
|
||||
|
||||
for (int paramIdx = -1; paramIdx < GetParamCount(); paramIdx++)
|
||||
|
@ -972,11 +992,18 @@ void BfMethodInstance::GetIRFunctionInfo(BfModule* module, BfIRType& returnType,
|
|||
checkLowered = true;
|
||||
}
|
||||
|
||||
BfType* checkType2 = NULL;
|
||||
if (checkLowered)
|
||||
{
|
||||
auto loweredTypeCode = checkType->GetLoweredType();
|
||||
if (loweredTypeCode != BfTypeCode_None)
|
||||
checkType = module->GetPrimitiveType(loweredTypeCode);
|
||||
BfTypeCode loweredTypeCode = BfTypeCode_None;
|
||||
BfTypeCode loweredTypeCode2 = BfTypeCode_None;
|
||||
if (checkType->GetLoweredType(BfTypeUsage_Parameter, &loweredTypeCode, &loweredTypeCode2))
|
||||
{
|
||||
paramTypes.push_back(module->mBfIRBuilder->GetPrimitiveType(loweredTypeCode));
|
||||
if (loweredTypeCode2 != BfTypeCode_None)
|
||||
paramTypes.push_back(module->mBfIRBuilder->GetPrimitiveType(loweredTypeCode2));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if ((paramIdx == 0) && (GetParamName(0) == "this") && (checkType->IsPointer()))
|
||||
|
@ -1034,6 +1061,13 @@ void BfMethodInstance::GetIRFunctionInfo(BfModule* module, BfIRType& returnType,
|
|||
else
|
||||
_AddType(checkType);
|
||||
|
||||
if (checkType2 != NULL)
|
||||
_AddType(checkType2);
|
||||
}
|
||||
|
||||
if ((GetStructRetIdx() == 1) && (!forceStatic))
|
||||
{
|
||||
BF_SWAP(paramTypes[0], paramTypes[1]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1414,19 +1448,100 @@ BfPrimitiveType* BfTypeInstance::GetDiscriminatorType(int* outDataIdx)
|
|||
return (BfPrimitiveType*)fieldInstance.mResolvedType;
|
||||
}
|
||||
|
||||
BfTypeCode BfTypeInstance::GetLoweredType()
|
||||
bool BfTypeInstance::GetLoweredType(BfTypeUsage typeUsage, BfTypeCode* outTypeCode, BfTypeCode* outTypeCode2)
|
||||
{
|
||||
if ((mTypeDef->mTypeCode != BfTypeCode_Struct) || (mIsSplattable))
|
||||
return BfTypeCode_None;
|
||||
if ((mTypeDef->mTypeCode != BfTypeCode_Struct) || (IsBoxed()) || (mIsSplattable))
|
||||
return false;
|
||||
|
||||
if (mModule->mCompiler->mOptions.mPlatformType == BfPlatformType_Windows)
|
||||
{
|
||||
// Odd Windows rule: composite returns for non-static methods are always sret
|
||||
if (typeUsage == BfTypeUsage_Return_NonStatic)
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BfTypeCode typeCode = BfTypeCode_None;
|
||||
BfTypeCode pow2TypeCode = BfTypeCode_None;
|
||||
|
||||
switch (mInstSize)
|
||||
{
|
||||
case 1: return BfTypeCode_Int8;
|
||||
case 2: return BfTypeCode_Int16;
|
||||
case 4: return BfTypeCode_Int32;
|
||||
case 8: if (mModule->mSystem->mPtrSize == 8) return BfTypeCode_Int64;
|
||||
case 1:
|
||||
pow2TypeCode = BfTypeCode_Int8;
|
||||
break;
|
||||
case 2:
|
||||
pow2TypeCode = BfTypeCode_Int16;
|
||||
break;
|
||||
case 3:
|
||||
typeCode = BfTypeCode_Int24;
|
||||
break;
|
||||
case 4:
|
||||
pow2TypeCode = BfTypeCode_Int32;
|
||||
break;
|
||||
case 5:
|
||||
typeCode = BfTypeCode_Int40;
|
||||
break;
|
||||
case 6:
|
||||
typeCode = BfTypeCode_Int48;
|
||||
break;
|
||||
case 7:
|
||||
typeCode = BfTypeCode_Int56;
|
||||
break;
|
||||
case 8:
|
||||
if (mModule->mSystem->mPtrSize == 8)
|
||||
{
|
||||
pow2TypeCode = BfTypeCode_Int64;
|
||||
break;
|
||||
}
|
||||
return BfTypeCode_None;
|
||||
if (typeUsage == BfTypeUsage_Return_Static)
|
||||
{
|
||||
pow2TypeCode = BfTypeCode_Int64;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (pow2TypeCode != BfTypeCode_None)
|
||||
{
|
||||
if (outTypeCode != NULL)
|
||||
*outTypeCode = pow2TypeCode;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (mModule->mCompiler->mOptions.mPlatformType != BfPlatformType_Windows)
|
||||
{
|
||||
if (typeCode != BfTypeCode_None)
|
||||
{
|
||||
if (outTypeCode != NULL)
|
||||
*outTypeCode = typeCode;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool BfTypeInstance::HasEquivalentLayout(BfTypeInstance* compareTo)
|
||||
|
|
|
@ -428,6 +428,14 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
enum BfTypeUsage
|
||||
{
|
||||
BfTypeUsage_Unspecified,
|
||||
BfTypeUsage_Return_Static,
|
||||
BfTypeUsage_Return_NonStatic,
|
||||
BfTypeUsage_Parameter,
|
||||
};
|
||||
|
||||
class BfType
|
||||
{
|
||||
public:
|
||||
|
@ -539,7 +547,7 @@ public:
|
|||
virtual bool IsConstExprValue() { return false; }
|
||||
virtual bool IsDependentOnUnderlyingType() { return false; }
|
||||
virtual bool WantsGCMarking() { return false; }
|
||||
virtual BfTypeCode GetLoweredType() { return BfTypeCode_None; }
|
||||
virtual bool GetLoweredType(BfTypeUsage typeUsage, BfTypeCode* outTypeCode = NULL, BfTypeCode* outTypeCode2 = NULL) { return false; }
|
||||
virtual BfType* GetUnderlyingType() { return NULL; }
|
||||
virtual bool HasWrappedRepresentation() { return IsWrappableType(); }
|
||||
virtual bool IsTypeMemberIncluded(BfTypeDef* declaringTypeDef, BfTypeDef* activeTypeDef = NULL, BfModule* module = NULL) { return true; } // May be 'false' only for generic extensions with constraints
|
||||
|
@ -852,8 +860,9 @@ public:
|
|||
bool IsSpecializedByAutoCompleteMethod();
|
||||
bool HasThis();
|
||||
bool HasParamsArray();
|
||||
bool HasStructRet();
|
||||
int GetStructRetIdx();
|
||||
bool HasSelf();
|
||||
bool GetLoweredReturnType(BfTypeCode* loweredTypeCode = NULL, BfTypeCode* loweredTypeCode2 = NULL);
|
||||
bool IsAutocompleteMethod() { /*return mIdHash == -1;*/ return mIsAutocompleteMethod; }
|
||||
bool IsSkipCall(bool bypassVirtual = false);
|
||||
bool IsVarArgs();
|
||||
|
@ -1827,11 +1836,11 @@ public:
|
|||
virtual bool IsTypeMemberAccessible(BfTypeDef* declaringTypeDef, BfTypeDef* activeTypeDef) override;
|
||||
virtual bool IsTypeMemberAccessible(BfTypeDef* declaringTypeDef, BfProject* curProject) override;
|
||||
virtual bool WantsGCMarking() override;
|
||||
virtual BfTypeCode GetLoweredType() override;
|
||||
virtual bool GetLoweredType(BfTypeUsage typeUsage, BfTypeCode* outTypeCode = NULL, BfTypeCode* outTypeCode2 = NULL) override;
|
||||
|
||||
BfGenericTypeInfo* GetGenericTypeInfo() { return mGenericTypeInfo; }
|
||||
|
||||
virtual BfTypeInstance* ToGenericTypeInstance() { return (mGenericTypeInfo != NULL) ? this : NULL; }
|
||||
virtual BfTypeInstance* ToGenericTypeInstance() override { return (mGenericTypeInfo != NULL) ? this : NULL; }
|
||||
virtual bool IsGenericTypeInstance() override { return mGenericTypeInfo != NULL; }
|
||||
virtual bool IsSpecializedType() override { return (mGenericTypeInfo != NULL) && (!mGenericTypeInfo->mIsUnspecialized); }
|
||||
virtual bool IsSpecializedByAutoCompleteMethod() override;
|
||||
|
@ -2020,7 +2029,7 @@ public:
|
|||
virtual bool IsUnspecializedType() override { return mIsUnspecializedType; }
|
||||
virtual bool IsUnspecializedTypeVariation() override { return mIsUnspecializedTypeVariation; }
|
||||
|
||||
virtual BfDelegateInfo* GetDelegateInfo() { return &mDelegateInfo; }
|
||||
virtual BfDelegateInfo* GetDelegateInfo() override { return &mDelegateInfo; }
|
||||
};
|
||||
|
||||
class BfTupleType : public BfTypeInstance
|
||||
|
|
|
@ -4885,12 +4885,12 @@ void BfModule::Visit(BfReturnStatement* returnStmt)
|
|||
BfType* origType;
|
||||
BfExprEvaluator exprEvaluator(this);
|
||||
bool alreadyWritten = false;
|
||||
if (mCurMethodInstance->HasStructRet())
|
||||
if (mCurMethodInstance->GetStructRetIdx() != -1)
|
||||
exprEvaluator.mReceivingValue = &mCurMethodState->mRetVal;
|
||||
if (mCurMethodInstance->mMethodDef->mIsReadOnly)
|
||||
exprEvaluator.mAllowReadOnlyReference = true;
|
||||
auto retValue = CreateValueFromExpression(exprEvaluator, returnStmt->mExpression, expectingReturnType, BfEvalExprFlags_AllowRefExpr, &origType);
|
||||
if (mCurMethodInstance->HasStructRet())
|
||||
if (mCurMethodInstance->GetStructRetIdx() != -1)
|
||||
alreadyWritten = exprEvaluator.mReceivingValue == NULL;
|
||||
MarkScopeLeft(&mCurMethodState->mHeadScope);
|
||||
|
||||
|
|
|
@ -6734,7 +6734,7 @@ DbgTypedValue DbgExprEvaluator::CreateCall(BfAstNode* targetSrc, DbgTypedValue t
|
|||
|
||||
if ((param != NULL) && (param->mType != NULL) && (param->mType->IsCompositeType()))
|
||||
{
|
||||
if (splatParams.Contains(param->mName))
|
||||
if ((param->mName != NULL) && (splatParams.Contains(param->mName)))
|
||||
{
|
||||
std::function<void(const DbgTypedValue& typedVal)> _SplatArgs = [&](const DbgTypedValue& typedVal)
|
||||
{
|
||||
|
@ -7267,7 +7267,7 @@ DbgTypedValue DbgExprEvaluator::MatchMethod(BfAstNode* targetSrc, DbgTypedValue
|
|||
}
|
||||
else if (methodName == "__demangleMethod")
|
||||
{
|
||||
if (argValues.size() == 1)
|
||||
if (argValues.size() == 2)
|
||||
{
|
||||
auto checkType = argValues[0].mType;
|
||||
if (checkType->IsPointer())
|
||||
|
@ -7293,6 +7293,27 @@ DbgTypedValue DbgExprEvaluator::MatchMethod(BfAstNode* targetSrc, DbgTypedValue
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (methodName == "__demangle")
|
||||
{
|
||||
if (argValues.size() == 1)
|
||||
{
|
||||
auto rawTextType = mDbgModule->GetPrimitiveType(DbgType_RawText, GetLanguage());
|
||||
|
||||
String mangledName = argValues[0].mCharPtr;
|
||||
|
||||
static String demangledName;
|
||||
demangledName = BfDemangler::Demangle(mangledName, DbgLanguage_Unknown);
|
||||
|
||||
if (demangledName.StartsWith("bf."))
|
||||
demangledName.Remove(0, 3);
|
||||
|
||||
DbgTypedValue result;
|
||||
result.mType = rawTextType;
|
||||
result.mCharPtr = demangledName.c_str();
|
||||
result.mIsLiteral = true;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
else if (methodName == "__demangleFakeMember")
|
||||
{
|
||||
if (argValues.size() == 1)
|
||||
|
|
|
@ -158,6 +158,18 @@ public:
|
|||
return mPtr;
|
||||
}
|
||||
|
||||
String GetString() const
|
||||
{
|
||||
if (!mType->IsPointer())
|
||||
return "";
|
||||
if ((mType->mTypeParam->mTypeCode != DbgType_SChar) && (mType->mTypeParam->mTypeCode != DbgType_UChar))
|
||||
return "";
|
||||
if (mIsLiteral)
|
||||
return mCharPtr;
|
||||
//return (const char*)mPtr;
|
||||
return "";
|
||||
}
|
||||
|
||||
operator bool() const
|
||||
{
|
||||
return (mType != NULL) && (!mHasNoValue);
|
||||
|
|
31
IDEHelper/Tests/CLib/CLib.sln
Normal file
31
IDEHelper/Tests/CLib/CLib.sln
Normal file
|
@ -0,0 +1,31 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.28307.645
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CLib", "CLib.vcxproj", "{D72A956A-5D9C-42F4-B35B-05F0B05B632C}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{D72A956A-5D9C-42F4-B35B-05F0B05B632C}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{D72A956A-5D9C-42F4-B35B-05F0B05B632C}.Debug|x64.Build.0 = Debug|x64
|
||||
{D72A956A-5D9C-42F4-B35B-05F0B05B632C}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{D72A956A-5D9C-42F4-B35B-05F0B05B632C}.Debug|x86.Build.0 = Debug|Win32
|
||||
{D72A956A-5D9C-42F4-B35B-05F0B05B632C}.Release|x64.ActiveCfg = Release|x64
|
||||
{D72A956A-5D9C-42F4-B35B-05F0B05B632C}.Release|x64.Build.0 = Release|x64
|
||||
{D72A956A-5D9C-42F4-B35B-05F0B05B632C}.Release|x86.ActiveCfg = Release|Win32
|
||||
{D72A956A-5D9C-42F4-B35B-05F0B05B632C}.Release|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {B4D3315D-D9A9-4A82-BEC4-B05271FC794E}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
162
IDEHelper/Tests/CLib/CLib.vcxproj
Normal file
162
IDEHelper/Tests/CLib/CLib.vcxproj
Normal file
|
@ -0,0 +1,162 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>15.0</VCProjectVersion>
|
||||
<ProjectGuid>{D72A956A-5D9C-42F4-B35B-05F0B05B632C}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>CLib</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0.18362.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="stdafx.h" />
|
||||
<ClInclude Include="targetver.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="main.cpp" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
30
IDEHelper/Tests/CLib/CLib.vcxproj.filters
Normal file
30
IDEHelper/Tests/CLib/CLib.vcxproj.filters
Normal file
|
@ -0,0 +1,30 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="stdafx.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="targetver.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="main.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
371
IDEHelper/Tests/CLib/main.cpp
Normal file
371
IDEHelper/Tests/CLib/main.cpp
Normal file
|
@ -0,0 +1,371 @@
|
|||
#include <inttypes.h>
|
||||
|
||||
namespace Tests
|
||||
{
|
||||
struct Interop
|
||||
{
|
||||
struct StructA
|
||||
{
|
||||
int mA;
|
||||
|
||||
int MethodA0(int arg0)
|
||||
{
|
||||
return arg0 + mA * 100;
|
||||
}
|
||||
|
||||
StructA MethodA1(StructA other, int arg0)
|
||||
{
|
||||
StructA ret;
|
||||
ret.mA = mA + other.mA + arg0;
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
struct StructB
|
||||
{
|
||||
int mA;
|
||||
char mB;
|
||||
|
||||
int MethodB0(int arg0)
|
||||
{
|
||||
return arg0 + mA * 100 + mB * 10000;
|
||||
}
|
||||
|
||||
StructB MethodB1(StructB other, int arg0)
|
||||
{
|
||||
StructB ret;
|
||||
ret.mA = mA + other.mA + arg0;
|
||||
ret.mB = mB + other.mB;
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
struct StructC
|
||||
{
|
||||
char mA;
|
||||
int mB;
|
||||
|
||||
int MethodC0(int arg0)
|
||||
{
|
||||
return arg0 + mA * 100 + mB * 10000;
|
||||
}
|
||||
|
||||
StructC MethodC1(StructC other, int arg0)
|
||||
{
|
||||
StructC ret;
|
||||
ret.mA = mA + other.mA + arg0;
|
||||
ret.mB = mB + other.mB;
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
struct StructD
|
||||
{
|
||||
int mA;
|
||||
int mB;
|
||||
|
||||
int MethodD0(int arg0)
|
||||
{
|
||||
return arg0 + mA * 100 + mB * 10000;
|
||||
}
|
||||
|
||||
StructD MethodD1(StructD other, int arg0)
|
||||
{
|
||||
StructD ret;
|
||||
ret.mA = mA + other.mA + arg0;
|
||||
ret.mB = mB + other.mB;
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
struct StructE
|
||||
{
|
||||
int mA;
|
||||
int mB;
|
||||
int mC;
|
||||
|
||||
int MethodE0(int arg0)
|
||||
{
|
||||
return arg0 + mA * 100 + mC * 10000;
|
||||
}
|
||||
|
||||
StructE MethodE1(StructE other, int arg0)
|
||||
{
|
||||
StructE ret;
|
||||
ret.mA = mA + other.mA + arg0;
|
||||
ret.mB = mB + other.mB;
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
struct StructF
|
||||
{
|
||||
char mA;
|
||||
char mB;
|
||||
char mC;
|
||||
|
||||
int MethodF0(int arg0)
|
||||
{
|
||||
return arg0 + mA * 100 + mC * 10000;
|
||||
}
|
||||
|
||||
StructF MethodF1(StructF other, int arg0)
|
||||
{
|
||||
StructF ret;
|
||||
ret.mA = mA + other.mA + arg0;
|
||||
ret.mB = mB + other.mB;
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
struct StructG
|
||||
{
|
||||
char mA;
|
||||
char mB;
|
||||
char mC;
|
||||
char mD;
|
||||
|
||||
int MethodG0(int arg0)
|
||||
{
|
||||
return arg0 + mA * 100 + mC * 10000;
|
||||
}
|
||||
|
||||
StructG MethodG1(StructG other, int arg0)
|
||||
{
|
||||
StructG ret;
|
||||
ret.mA = mA + other.mA + arg0;
|
||||
ret.mB = mB + other.mB;
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
struct StructH
|
||||
{
|
||||
int64_t mA;
|
||||
int64_t mB;
|
||||
int64_t mC;
|
||||
|
||||
int MethodH0(int arg0)
|
||||
{
|
||||
return arg0 + (int)mA * 100 + (int)mC * 10000;
|
||||
}
|
||||
|
||||
StructH MethodH1(StructH other, int arg0)
|
||||
{
|
||||
StructH ret;
|
||||
ret.mA = mA + other.mA + arg0;
|
||||
ret.mB = mB + other.mB;
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
struct StructI
|
||||
{
|
||||
char mA;
|
||||
char mB;
|
||||
char mC;
|
||||
char mD;
|
||||
char mE;
|
||||
|
||||
int MethodI0(int arg0)
|
||||
{
|
||||
return arg0 + (int)mA * 100 + (int)mC * 10000;
|
||||
}
|
||||
|
||||
StructI MethodI1(StructI other, int arg0)
|
||||
{
|
||||
StructI ret;
|
||||
ret.mA = mA + other.mA + arg0;
|
||||
ret.mB = mB + other.mB;
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
using namespace Tests;
|
||||
|
||||
extern "C" int Func0(int a, int b)
|
||||
{
|
||||
return a + b * 100;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern "C" int Func1A(Interop::StructA arg0, Interop::StructA arg1, int arg2)
|
||||
{
|
||||
return arg0.mA + arg1.mA * 100 + arg2 * 10000;
|
||||
}
|
||||
|
||||
extern "C" int Func1B(Interop::StructB arg0, Interop::StructB arg1, int arg2)
|
||||
{
|
||||
return arg0.mA + arg1.mA * 100 + arg2 * 10000;
|
||||
}
|
||||
|
||||
extern "C" int Func1C(Interop::StructC arg0, Interop::StructC arg1, int arg2)
|
||||
{
|
||||
return arg0.mA + arg1.mA * 100 + arg2 * 10000;
|
||||
}
|
||||
|
||||
extern "C" int Func1D(Interop::StructD arg0, Interop::StructD arg1, int arg2)
|
||||
{
|
||||
return arg0.mA + arg1.mA * 100 + arg2 * 10000;
|
||||
}
|
||||
|
||||
extern "C" int Func1E(Interop::StructE arg0, Interop::StructE arg1, int arg2)
|
||||
{
|
||||
return arg0.mA + arg1.mA * 100 + arg2 * 10000;
|
||||
}
|
||||
|
||||
extern "C" int Func1F(Interop::StructF arg0, Interop::StructF arg1, int arg2)
|
||||
{
|
||||
return arg0.mA + arg1.mA * 100 + arg2 * 10000;
|
||||
}
|
||||
|
||||
extern "C" int Func1G(Interop::StructG arg0, Interop::StructG arg1, int arg2)
|
||||
{
|
||||
return arg0.mA + arg1.mA * 100 + arg2 * 10000;
|
||||
}
|
||||
|
||||
extern "C" int Func1H(Interop::StructH arg0, Interop::StructH arg1, int arg2)
|
||||
{
|
||||
return (int)arg0.mA + (int)arg1.mA * 100 + arg2 * 10000;
|
||||
}
|
||||
|
||||
extern "C" int Func1I(Interop::StructI arg0, Interop::StructI arg1, int arg2)
|
||||
{
|
||||
return (int)arg0.mA + (int)arg1.mA * 100 + arg2 * 10000;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern "C" Interop::StructA Func2A(Interop::StructA arg0, int arg1)
|
||||
{
|
||||
Interop::StructA ret;
|
||||
ret.mA = arg0.mA + arg1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern "C" Interop::StructB Func2B(Interop::StructB arg0, int arg1)
|
||||
{
|
||||
Interop::StructB ret;
|
||||
ret.mA = arg0.mA + arg1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern "C" Interop::StructC Func2C(Interop::StructC arg0, int arg1)
|
||||
{
|
||||
Interop::StructC ret;
|
||||
ret.mA = arg0.mA + arg1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern "C" Interop::StructD Func2D(Interop::StructD arg0, int arg1)
|
||||
{
|
||||
Interop::StructD ret;
|
||||
ret.mA = arg0.mA + arg1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern "C" Interop::StructE Func2E(Interop::StructE arg0, int arg1)
|
||||
{
|
||||
Interop::StructE ret;
|
||||
ret.mA = arg0.mA + arg1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern "C" Interop::StructF Func2F(Interop::StructF arg0, int arg1)
|
||||
{
|
||||
Interop::StructF ret;
|
||||
ret.mA = arg0.mA + arg1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern "C" Interop::StructG Func2G(Interop::StructG arg0, int arg1)
|
||||
{
|
||||
Interop::StructG ret;
|
||||
ret.mA = arg0.mA + arg1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern "C" Interop::StructH Func2H(Interop::StructH arg0, int arg1)
|
||||
{
|
||||
Interop::StructH ret;
|
||||
ret.mA = arg0.mA + arg1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern "C" Interop::StructI Func2I(Interop::StructI arg0, int arg1)
|
||||
{
|
||||
Interop::StructI ret;
|
||||
ret.mA = arg0.mA + arg1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern "C" int Func3A(Interop::StructA* ptr)
|
||||
{
|
||||
return ptr[0].mA + ptr[1].mA * 100;
|
||||
}
|
||||
|
||||
extern "C" int Func3B(Interop::StructB* ptr)
|
||||
{
|
||||
return ptr[0].mA + ptr[1].mA * 100;
|
||||
}
|
||||
|
||||
extern "C" int Func3C(Interop::StructC* ptr)
|
||||
{
|
||||
return ptr[0].mA + ptr[1].mA * 100;
|
||||
}
|
||||
|
||||
extern "C" int Func3D(Interop::StructD* ptr)
|
||||
{
|
||||
return ptr[0].mA + ptr[1].mA * 100;
|
||||
}
|
||||
|
||||
extern "C" int Func3E(Interop::StructE* ptr)
|
||||
{
|
||||
return ptr[0].mA + ptr[1].mA * 100;
|
||||
}
|
||||
|
||||
extern "C" int Func3F(Interop::StructF* ptr)
|
||||
{
|
||||
return ptr[0].mA + ptr[1].mA * 100;
|
||||
}
|
||||
|
||||
extern "C" int Func3G(Interop::StructG* ptr)
|
||||
{
|
||||
return ptr[0].mA + ptr[1].mA * 100;
|
||||
}
|
||||
|
||||
void UseIt()
|
||||
{
|
||||
Interop::StructA sa;
|
||||
sa.MethodA0(0);
|
||||
sa.MethodA1(sa, 1);
|
||||
Interop::StructB sb;
|
||||
sb.MethodB0(0);
|
||||
sb.MethodB1(sb, 1);
|
||||
Interop::StructC sc;
|
||||
sc.MethodC0(0);
|
||||
sc.MethodC1(sc, 1);
|
||||
Interop::StructD sd;
|
||||
sd.MethodD0(0);
|
||||
sd.MethodD1(sd, 1);
|
||||
Interop::StructE se;
|
||||
se.MethodE0(0);
|
||||
se.MethodE1(se, 1);
|
||||
Interop::StructF sf;
|
||||
sf.MethodF0(0);
|
||||
sf.MethodF1(sf, 1);
|
||||
Interop::StructG sg;
|
||||
sg.MethodG0(0);
|
||||
sg.MethodG1(sg, 1);
|
||||
Interop::StructH sh;
|
||||
sh.MethodH0(0);
|
||||
sh.MethodH1(sh, 1);
|
||||
Interop::StructI si;
|
||||
si.MethodI0(0);
|
||||
si.MethodI1(si, 1);
|
||||
}
|
261
IDEHelper/Tests/src/Interop.bf
Normal file
261
IDEHelper/Tests/src/Interop.bf
Normal file
|
@ -0,0 +1,261 @@
|
|||
using System;
|
||||
|
||||
namespace Tests
|
||||
{
|
||||
class Interop
|
||||
{
|
||||
[CRepr]
|
||||
public struct StructA
|
||||
{
|
||||
public int32 mA;
|
||||
|
||||
[LinkName(.CPP)]
|
||||
public extern int32 MethodA0(int32 arg0) mut;
|
||||
[LinkName(.CPP)]
|
||||
public extern StructA MethodA1(StructA sa, int32 arg0) mut;
|
||||
}
|
||||
|
||||
[CRepr]
|
||||
public struct StructB
|
||||
{
|
||||
public int32 mA;
|
||||
public int8 mB;
|
||||
|
||||
[LinkName(.CPP)]
|
||||
public extern int32 MethodB0(int32 arg0) mut;
|
||||
[LinkName(.CPP)]
|
||||
public extern StructB MethodB1(StructB sa, int32 arg0) mut;
|
||||
}
|
||||
|
||||
[CRepr]
|
||||
public struct StructC
|
||||
{
|
||||
public int8 mA;
|
||||
public int32 mB;
|
||||
|
||||
[LinkName(.CPP)]
|
||||
public extern int32 MethodC0(int32 arg0) mut;
|
||||
[LinkName(.CPP)]
|
||||
public extern StructC MethodC1(StructC sa, int32 arg0) mut;
|
||||
}
|
||||
|
||||
[CRepr]
|
||||
public struct StructD
|
||||
{
|
||||
public int32 mA;
|
||||
public int32 mB;
|
||||
|
||||
[LinkName(.CPP)]
|
||||
public extern int32 MethodD0(int32 arg0) mut;
|
||||
[LinkName(.CPP)]
|
||||
public extern StructD MethodD1(StructD sa, int32 arg0) mut;
|
||||
}
|
||||
|
||||
[CRepr]
|
||||
public struct StructE
|
||||
{
|
||||
public int32 mA;
|
||||
public int32 mB;
|
||||
public int32 mC;
|
||||
|
||||
[LinkName(.CPP)]
|
||||
public extern int32 MethodE0(int32 arg0) mut;
|
||||
[LinkName(.CPP)]
|
||||
public extern StructE MethodE1(StructE sa, int32 arg0) mut;
|
||||
}
|
||||
|
||||
[CRepr]
|
||||
public struct StructF
|
||||
{
|
||||
public int8 mA;
|
||||
public int8 mB;
|
||||
public int8 mC;
|
||||
|
||||
[LinkName(.CPP)]
|
||||
public extern int32 MethodF0(int32 arg0) mut;
|
||||
[LinkName(.CPP)]
|
||||
public extern StructF MethodF1(StructF sa, int32 arg0) mut;
|
||||
}
|
||||
|
||||
[CRepr]
|
||||
public struct StructG
|
||||
{
|
||||
public int8 mA;
|
||||
public int8 mB;
|
||||
public int8 mC;
|
||||
public int8 mD;
|
||||
|
||||
[LinkName(.CPP)]
|
||||
public extern int32 MethodG0(int32 arg0) mut;
|
||||
[LinkName(.CPP)]
|
||||
public extern StructG MethodG1(StructG sa, int32 arg0) mut;
|
||||
}
|
||||
|
||||
[CRepr]
|
||||
public struct StructH
|
||||
{
|
||||
public int64 mA;
|
||||
public int64 mB;
|
||||
public int64 mC;
|
||||
|
||||
[LinkName(.CPP)]
|
||||
public extern int32 MethodH0(int32 arg0) mut;
|
||||
[LinkName(.CPP)]
|
||||
public extern StructH MethodH1(StructH sa, int32 arg0) mut;
|
||||
}
|
||||
|
||||
[CRepr]
|
||||
public struct StructI
|
||||
{
|
||||
public int8 mA;
|
||||
public int8 mB;
|
||||
public int8 mC;
|
||||
public int8 mD;
|
||||
public int8 mE;
|
||||
|
||||
[LinkName(.CPP)]
|
||||
public extern int32 MethodI0(int32 arg0) mut;
|
||||
[LinkName(.CPP)]
|
||||
public extern StructI MethodI1(StructI sa, int32 arg0) mut;
|
||||
}
|
||||
|
||||
[LinkName(.C)]
|
||||
public static extern int32 Func0(int32 a, int32 b);
|
||||
|
||||
[LinkName(.C)]
|
||||
public static extern int32 Func1A(StructA arg0, StructA arg1, int32 arg2);
|
||||
[LinkName(.C)]
|
||||
public static extern int32 Func1B(StructB arg0, StructB arg1, int32 arg2);
|
||||
[LinkName(.C)]
|
||||
public static extern int32 Func1C(StructC arg0, StructC arg1, int32 arg2);
|
||||
[LinkName(.C)]
|
||||
public static extern int32 Func1D(StructD arg0, StructD arg1, int32 arg2);
|
||||
[LinkName(.C)]
|
||||
public static extern int32 Func1E(StructE arg0, StructE arg1, int32 arg2);
|
||||
[LinkName(.C)]
|
||||
public static extern int32 Func1F(StructF arg0, StructF arg1, int32 arg2);
|
||||
[LinkName(.C)]
|
||||
public static extern int32 Func1G(StructG arg0, StructG arg1, int32 arg2);
|
||||
[LinkName(.C)]
|
||||
public static extern int32 Func1H(StructH arg0, StructH arg1, int32 arg2);
|
||||
[LinkName(.C)]
|
||||
public static extern int32 Func1I(StructI arg0, StructI arg1, int32 arg2);
|
||||
|
||||
[LinkName(.C)]
|
||||
public static extern StructA Func2A(StructA arg0, int32 arg2);
|
||||
[LinkName(.C)]
|
||||
public static extern StructB Func2B(StructB arg0, int32 arg2);
|
||||
[LinkName(.C)]
|
||||
public static extern StructC Func2C(StructC arg0, int32 arg2);
|
||||
[LinkName(.C)]
|
||||
public static extern StructD Func2D(StructD arg0, int32 arg2);
|
||||
[LinkName(.C)]
|
||||
public static extern StructE Func2E(StructE arg0, int32 arg2);
|
||||
[LinkName(.C)]
|
||||
public static extern StructF Func2F(StructF arg0, int32 arg2);
|
||||
[LinkName(.C)]
|
||||
public static extern StructG Func2G(StructG arg0, int32 arg2);
|
||||
[LinkName(.C)]
|
||||
public static extern StructH Func2H(StructH arg0, int32 arg2);
|
||||
[LinkName(.C)]
|
||||
public static extern StructI Func2I(StructI arg0, int32 arg2);
|
||||
|
||||
[Test]
|
||||
public static void TestBasics()
|
||||
{
|
||||
//return;
|
||||
|
||||
StructA sa0 = default;
|
||||
sa0.mA = 10;
|
||||
StructA sa1 = default;
|
||||
sa1.mA = 11;
|
||||
|
||||
StructB sb0 = default;
|
||||
sb0.mA = 20;
|
||||
StructB sb1 = default;
|
||||
sb1.mA = 21;
|
||||
|
||||
StructC sc0 = default;
|
||||
sc0.mA = 30;
|
||||
StructC sc1 = default;
|
||||
sc1.mA = 31;
|
||||
|
||||
StructD sd0 = default;
|
||||
sd0.mA = 40;
|
||||
StructD sd1 = default;
|
||||
sd1.mA = 41;
|
||||
|
||||
StructE se0 = default;
|
||||
se0.mA = 50;
|
||||
StructE se1 = default;
|
||||
se1.mA = 51;
|
||||
|
||||
StructF sf0 = default;
|
||||
sf0.mA = 60;
|
||||
StructF sf1 = default;
|
||||
sf1.mA = 61;
|
||||
|
||||
StructG sg0 = default;
|
||||
sg0.mA = 70;
|
||||
StructG sg1 = default;
|
||||
sg1.mA = 71;
|
||||
|
||||
StructH sh0 = default;
|
||||
sh0.mA = 80;
|
||||
StructH sh1 = default;
|
||||
sh1.mA = 81;
|
||||
|
||||
StructI si0 = default;
|
||||
si0.mA = 90;
|
||||
StructI si1 = default;
|
||||
si1.mA = 91;
|
||||
|
||||
Test.Assert(Func0(12, 34) == 3412);
|
||||
|
||||
Test.Assert(Func1A(sa0, sa1, 12) == 121110);
|
||||
Test.Assert(sa0.MethodA0(12) == 1012);
|
||||
Test.Assert(sa0.MethodA1(sa1, 12).mA == 33);
|
||||
Test.Assert(Func2A(sa0, 12).mA == 22);
|
||||
|
||||
Test.Assert(Func1B(sb0, sb1, 12) == 122120);
|
||||
Test.Assert(sb0.MethodB0(12) == 2012);
|
||||
Test.Assert(sb0.MethodB1(sb1, 12).mA == 53);
|
||||
Test.Assert(Func2B(sb0, 12).mA == 32);
|
||||
|
||||
Test.Assert(Func1C(sc0, sc1, 12) == 123130);
|
||||
Test.Assert(sc0.MethodC0(12) == 3012);
|
||||
Test.Assert(sc0.MethodC1(sc1, 12).mA == 73);
|
||||
Test.Assert(Func2C(sc0, 12).mA == 42);
|
||||
|
||||
Test.Assert(Func1D(sd0, sd1, 12) == 124140);
|
||||
Test.Assert(sd0.MethodD0(12) == 4012);
|
||||
Test.Assert(sd0.MethodD1(sd1, 12).mA == 93);
|
||||
Test.Assert(Func2D(sd0, 12).mA == 52);
|
||||
|
||||
Test.Assert(Func1E(se0, se1, 12) == 125150);
|
||||
Test.Assert(se0.MethodE0(12) == 5012);
|
||||
Test.Assert(se0.MethodE1(se1, 12).mA == 113);
|
||||
Test.Assert(Func2E(se0, 12).mA == 62);
|
||||
|
||||
Test.Assert(Func1F(sf0, sf1, 12) == 126160);
|
||||
Test.Assert(sf0.MethodF0(12) == 6012);
|
||||
Test.Assert(sf0.MethodF1(sf1, 12).mA == (int8)133);
|
||||
Test.Assert(Func2F(sf0, 12).mA == 72);
|
||||
|
||||
Test.Assert(Func1G(sg0, sg1, 12) == 127170);
|
||||
Test.Assert(sg0.MethodG0(12) == 7012);
|
||||
Test.Assert(sg0.MethodG1(sg1, 12).mA == (int8)153);
|
||||
Test.Assert(Func2G(sg0, 12).mA == 82);
|
||||
|
||||
Test.Assert(Func1H(sh0, sh1, 12) == 128180);
|
||||
Test.Assert(sh0.MethodH0(12) == 8012);
|
||||
Test.Assert(sh0.MethodH1(sh1, 12).mA == 173);
|
||||
Test.Assert(Func2H(sh0, 12).mA == 92);
|
||||
|
||||
Test.Assert(Func1I(si0, si1, 12) == 129190);
|
||||
Test.Assert(si0.MethodI0(12) == 9012);
|
||||
Test.Assert(si0.MethodI1(si1, 12).mA == (int8)193);
|
||||
Test.Assert(Func2I(si0, 12).mA == 102);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -9,11 +9,15 @@ md stats
|
|||
|
||||
@REM GOTO RANDO
|
||||
|
||||
|
||||
@ECHO Testing IDEHelper\Tests
|
||||
CALL bin/msbuild.bat IDEHelper\Tests\CLib\CLib.vcxproj /p:Configuration=Debug /p:Platform=x64 /p:SolutionDir=%cd%\ /v:m
|
||||
@IF %ERRORLEVEL% NEQ 0 GOTO HADERROR
|
||||
IDE\dist\BeefBuild_d -proddir=IDEHelper\Tests -test
|
||||
@IF %ERRORLEVEL% NEQ 0 GOTO HADERROR
|
||||
|
||||
@ECHO Testing IDEHelper\Tests (Win32)
|
||||
CALL bin/msbuild.bat IDEHelper\Tests\CLib\CLib.vcxproj /p:Configuration=Debug /p:Platform=x86 /p:SolutionDir=%cd%\ /v:m
|
||||
IDE\dist\BeefBuild_d -proddir=IDEHelper\Tests -test -platform=Win32
|
||||
@IF %ERRORLEVEL% NEQ 0 GOTO HADERROR
|
||||
|
||||
|
|
5
extern/llvm_build.sh
vendored
5
extern/llvm_build.sh
vendored
|
@ -3,12 +3,13 @@ set -e
|
|||
|
||||
if [ ! -d llvm-project_8_0_0 ]; then
|
||||
git clone https://github.com/llvm/llvm-project.git llvm-project_8_0_0
|
||||
fi
|
||||
|
||||
if [ -d llvm-project_8_0_0 ]; then
|
||||
if [ -d llvm-project_8_0_0 ]; then
|
||||
cd llvm-project_8_0_0
|
||||
git checkout llvmorg-8.0.0
|
||||
cd ..
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
if [ ! -d llvm_linux_8_0_0 ]; then
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue