mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-09 20:12:21 +02:00
Allow '...' varargs in delegate and function types
This commit is contained in:
parent
7e139f5d7c
commit
b916273a97
5 changed files with 95 additions and 19 deletions
|
@ -1214,6 +1214,11 @@ bool BfMSMangler::FindOrCreateNameSub(MangleContext& mangleContext, StringImpl&
|
||||||
{
|
{
|
||||||
name += "_";
|
name += "_";
|
||||||
name += methodDef->mParams[paramIdx]->mName;
|
name += methodDef->mParams[paramIdx]->mName;
|
||||||
|
if (methodDef->mParams[paramIdx]->mParamKind == BfParamKind_VarArgs)
|
||||||
|
{
|
||||||
|
name += "__varargs";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
typeVec.push_back(BfNodeDynCast<BfDirectTypeReference>(methodDef->mParams[paramIdx]->mTypeRef)->mType);
|
typeVec.push_back(BfNodeDynCast<BfDirectTypeReference>(methodDef->mParams[paramIdx]->mTypeRef)->mType);
|
||||||
}
|
}
|
||||||
name += '@';
|
name += '@';
|
||||||
|
|
|
@ -7628,7 +7628,8 @@ BfType* BfModule::ResolveGenericType(BfType* unspecializedType, BfTypeVector* ty
|
||||||
directTypeRef->Init(returnType);
|
directTypeRef->Init(returnType);
|
||||||
methodDef->mReturnTypeRef = directTypeRef;
|
methodDef->mReturnTypeRef = directTypeRef;
|
||||||
delegateInfo->mReturnType = returnType;
|
delegateInfo->mReturnType = returnType;
|
||||||
delegateInfo->mHasExplicitThis = unspecializedDelegateInfo->mHasExplicitThis;
|
delegateInfo->mHasExplicitThis = unspecializedDelegateInfo->mHasExplicitThis;
|
||||||
|
delegateInfo->mHasVarArgs = unspecializedDelegateInfo->mHasVarArgs;
|
||||||
|
|
||||||
int paramIdx = 0;
|
int paramIdx = 0;
|
||||||
for (int paramIdx = 0; paramIdx < (int)paramTypes.size(); paramIdx++)
|
for (int paramIdx = 0; paramIdx < (int)paramTypes.size(); paramIdx++)
|
||||||
|
@ -10197,13 +10198,28 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
|
||||||
bool hasMutSpecifier = false;
|
bool hasMutSpecifier = false;
|
||||||
bool isFirst = true;
|
bool isFirst = true;
|
||||||
bool isDelegate = delegateTypeRef->mTypeToken->GetToken() == BfToken_Delegate;
|
bool isDelegate = delegateTypeRef->mTypeToken->GetToken() == BfToken_Delegate;
|
||||||
|
bool hasVarArgs = false;
|
||||||
|
|
||||||
Array<BfType*> paramTypes;
|
Array<BfType*> paramTypes;
|
||||||
for (auto param : delegateTypeRef->mParams)
|
for (int paramIdx = 0; paramIdx < delegateTypeRef->mParams.size(); paramIdx++)
|
||||||
{
|
{
|
||||||
|
auto param = delegateTypeRef->mParams[paramIdx];
|
||||||
BfResolveTypeRefFlags resolveTypeFlags = BfResolveTypeRefFlag_AllowRef;
|
BfResolveTypeRefFlags resolveTypeFlags = BfResolveTypeRefFlag_AllowRef;
|
||||||
if ((param->mNameNode != NULL) && (param->mNameNode->Equals("this")))
|
if ((param->mNameNode != NULL) && (param->mNameNode->Equals("this")))
|
||||||
resolveTypeFlags = (BfResolveTypeRefFlags)(resolveTypeFlags | BfResolveTypeRefFlag_NoWarnOnMut);
|
resolveTypeFlags = (BfResolveTypeRefFlags)(resolveTypeFlags | BfResolveTypeRefFlag_NoWarnOnMut);
|
||||||
|
|
||||||
|
if (paramIdx == delegateTypeRef->mParams.size() - 1)
|
||||||
|
{
|
||||||
|
if (auto dotTypeRef = BfNodeDynCast<BfDotTypeReference>(param->mTypeRef))
|
||||||
|
{
|
||||||
|
if (dotTypeRef->mDotToken->mToken == BfToken_DotDotDot)
|
||||||
|
{
|
||||||
|
hasVarArgs = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
auto paramType = ResolveTypeRef(param->mTypeRef, BfPopulateType_Declaration, resolveTypeFlags);
|
auto paramType = ResolveTypeRef(param->mTypeRef, BfPopulateType_Declaration, resolveTypeFlags);
|
||||||
if (paramType == NULL)
|
if (paramType == NULL)
|
||||||
{
|
{
|
||||||
|
@ -10319,7 +10335,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
|
||||||
}
|
}
|
||||||
|
|
||||||
auto directTypeRef = BfAstNode::ZeroedAlloc<BfDirectTypeReference>();
|
auto directTypeRef = BfAstNode::ZeroedAlloc<BfDirectTypeReference>();
|
||||||
delegateInfo->mDirectAllocNodes.push_back(directTypeRef);
|
delegateInfo->mDirectAllocNodes.push_back(directTypeRef);
|
||||||
if (typeDef->mIsDelegate)
|
if (typeDef->mIsDelegate)
|
||||||
directTypeRef->Init(delegateType);
|
directTypeRef->Init(delegateType);
|
||||||
else
|
else
|
||||||
|
@ -10332,6 +10348,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
|
||||||
methodDef->mReturnTypeRef = directTypeRef;
|
methodDef->mReturnTypeRef = directTypeRef;
|
||||||
delegateInfo->mReturnType = returnType;
|
delegateInfo->mReturnType = returnType;
|
||||||
delegateInfo->mHasExplicitThis = functionThisType != NULL;
|
delegateInfo->mHasExplicitThis = functionThisType != NULL;
|
||||||
|
delegateInfo->mHasVarArgs = hasVarArgs;
|
||||||
|
|
||||||
auto hashVal = mContext->mResolvedTypes.Hash(typeRef, &lookupCtx);
|
auto hashVal = mContext->mResolvedTypes.Hash(typeRef, &lookupCtx);
|
||||||
|
|
||||||
|
@ -10361,11 +10378,18 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
|
||||||
paramDef->mName = paramName;
|
paramDef->mName = paramName;
|
||||||
if ((paramIdx == 0) && (functionThisType != NULL))
|
if ((paramIdx == 0) && (functionThisType != NULL))
|
||||||
paramDef->mParamKind = BfParamKind_ExplicitThis;
|
paramDef->mParamKind = BfParamKind_ExplicitThis;
|
||||||
methodDef->mParams.push_back(paramDef);
|
methodDef->mParams.push_back(paramDef);
|
||||||
|
|
||||||
delegateInfo->mParams.Add(paramType);
|
delegateInfo->mParams.Add(paramType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (delegateInfo->mHasVarArgs)
|
||||||
|
{
|
||||||
|
BfParameterDef* paramDef = new BfParameterDef();
|
||||||
|
paramDef->mParamKind = BfParamKind_VarArgs;
|
||||||
|
methodDef->mParams.push_back(paramDef);
|
||||||
|
}
|
||||||
|
|
||||||
typeDef->mMethods.push_back(methodDef);
|
typeDef->mMethods.push_back(methodDef);
|
||||||
|
|
||||||
if (failed)
|
if (failed)
|
||||||
|
@ -13073,6 +13097,12 @@ void BfModule::DoTypeToString(StringImpl& str, BfType* resolvedType, BfTypeNameF
|
||||||
auto paramDef = methodDef->mParams[paramIdx];
|
auto paramDef = methodDef->mParams[paramIdx];
|
||||||
BfTypeNameFlags innerFlags = (BfTypeNameFlags)(typeNameFlags & ~(BfTypeNameFlag_OmitNamespace | BfTypeNameFlag_OmitOuterType | BfTypeNameFlag_ExtendedInfo));
|
BfTypeNameFlags innerFlags = (BfTypeNameFlags)(typeNameFlags & ~(BfTypeNameFlag_OmitNamespace | BfTypeNameFlag_OmitOuterType | BfTypeNameFlag_ExtendedInfo));
|
||||||
|
|
||||||
|
if (paramDef->mParamKind == BfParamKind_VarArgs)
|
||||||
|
{
|
||||||
|
str += "...";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
auto paramType = delegateInfo->mParams[paramIdx];
|
auto paramType = delegateInfo->mParams[paramIdx];
|
||||||
if ((paramIdx == 0) && (delegateInfo->mHasExplicitThis))
|
if ((paramIdx == 0) && (delegateInfo->mHasExplicitThis))
|
||||||
{
|
{
|
||||||
|
|
|
@ -9262,12 +9262,22 @@ bool BfReducer::ParseMethod(BfMethodDeclaration* methodDeclaration, SizedArrayIm
|
||||||
methodDeclaration->mOpenParen = tokenNode;
|
methodDeclaration->mOpenParen = tokenNode;
|
||||||
MoveNode(methodDeclaration->mOpenParen, methodDeclaration);
|
MoveNode(methodDeclaration->mOpenParen, methodDeclaration);
|
||||||
|
|
||||||
if (auto nextToken = BfNodeDynCast<BfTokenNode>(mVisitorPos.GetNext()))
|
bool isFunction = false;
|
||||||
|
bool isDelegate = false;
|
||||||
|
if ((mCurTypeDecl->mTypeNode != NULL) && (mCurTypeDecl->mTypeNode->GetToken() == BfToken_Function))
|
||||||
|
isFunction = true;
|
||||||
|
else if ((mCurTypeDecl->mTypeNode != NULL) && (mCurTypeDecl->mTypeNode->GetToken() == BfToken_Delegate))
|
||||||
|
isDelegate = true;
|
||||||
|
|
||||||
|
if ((!isFunction) && (!isDelegate))
|
||||||
{
|
{
|
||||||
if (nextToken->mToken == BfToken_This)
|
if (auto nextToken = BfNodeDynCast<BfTokenNode>(mVisitorPos.GetNext()))
|
||||||
{
|
{
|
||||||
MEMBER_SET(methodDeclaration, mThisToken, nextToken);
|
if (nextToken->mToken == BfToken_This)
|
||||||
mVisitorPos.MoveNext();
|
{
|
||||||
|
MEMBER_SET(methodDeclaration, mThisToken, nextToken);
|
||||||
|
mVisitorPos.MoveNext();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2736,6 +2736,7 @@ BfResolvedTypeSet::~BfResolvedTypeSet()
|
||||||
#define HASH_DELEGATE 11
|
#define HASH_DELEGATE 11
|
||||||
#define HASH_CONSTEXPR 12
|
#define HASH_CONSTEXPR 12
|
||||||
#define HASH_GLOBAL 13
|
#define HASH_GLOBAL 13
|
||||||
|
#define HASH_DOTDOTDOT 14
|
||||||
|
|
||||||
BfVariant BfResolvedTypeSet::EvaluateToVariant(LookupContext* ctx, BfExpression* expr, BfType*& outType)
|
BfVariant BfResolvedTypeSet::EvaluateToVariant(LookupContext* ctx, BfExpression* expr, BfType*& outType)
|
||||||
{
|
{
|
||||||
|
@ -2808,16 +2809,24 @@ int BfResolvedTypeSet::Hash(BfType* type, LookupContext* ctx, bool allowRef)
|
||||||
|
|
||||||
auto methodDef = typeInst->mTypeDef->mMethods[0];
|
auto methodDef = typeInst->mTypeDef->mMethods[0];
|
||||||
BF_ASSERT(methodDef->mName == "Invoke");
|
BF_ASSERT(methodDef->mName == "Invoke");
|
||||||
BF_ASSERT(delegateInfo->mParams.size() == methodDef->mParams.size());
|
|
||||||
|
int infoParamCount = (int)delegateInfo->mParams.size();
|
||||||
|
if (delegateInfo->mHasVarArgs)
|
||||||
|
infoParamCount++;
|
||||||
|
|
||||||
|
BF_ASSERT(infoParamCount == methodDef->mParams.size());
|
||||||
|
|
||||||
for (int paramIdx = 0; paramIdx < delegateInfo->mParams.size(); paramIdx++)
|
for (int paramIdx = 0; paramIdx < delegateInfo->mParams.size(); paramIdx++)
|
||||||
{
|
{
|
||||||
// Parse attributes?
|
// Parse attributes?
|
||||||
hashVal = ((hashVal ^ (Hash(delegateInfo->mParams[paramIdx], ctx))) << 5) - hashVal;
|
hashVal = ((hashVal ^ (Hash(delegateInfo->mParams[paramIdx], ctx))) << 5) - hashVal;
|
||||||
String paramName = methodDef->mParams[paramIdx]->mName;
|
String paramName = methodDef->mParams[paramIdx]->mName;
|
||||||
int nameHash = (int)Hash64(paramName.c_str(), (int)paramName.length());
|
int nameHash = (int)Hash64(paramName.c_str(), (int)paramName.length());
|
||||||
hashVal = ((hashVal ^ (nameHash)) << 5) - hashVal;
|
hashVal = ((hashVal ^ (nameHash)) << 5) - hashVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (delegateInfo->mHasVarArgs)
|
||||||
|
hashVal = ((hashVal ^ HASH_DOTDOTDOT) << 5) - hashVal;
|
||||||
|
|
||||||
return hashVal;
|
return hashVal;
|
||||||
}
|
}
|
||||||
|
@ -3397,8 +3406,9 @@ int BfResolvedTypeSet::Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHash
|
||||||
|
|
||||||
bool isFirstParam = true;
|
bool isFirstParam = true;
|
||||||
|
|
||||||
for (auto param : delegateTypeRef->mParams)
|
for (int paramIdx = 0; paramIdx < delegateTypeRef->mParams.size(); paramIdx++)
|
||||||
{
|
{
|
||||||
|
auto param = delegateTypeRef->mParams[paramIdx];
|
||||||
// Parse attributes?
|
// Parse attributes?
|
||||||
BfTypeReference* fieldType = param->mTypeRef;
|
BfTypeReference* fieldType = param->mTypeRef;
|
||||||
|
|
||||||
|
@ -3410,8 +3420,20 @@ int BfResolvedTypeSet::Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHash
|
||||||
fieldType = refNode->mElementType;
|
fieldType = refNode->mElementType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (paramIdx == delegateTypeRef->mParams.size() - 1)
|
||||||
|
{
|
||||||
|
if (auto dotTypeRef = BfNodeDynCastExact<BfDotTypeReference>(fieldType))
|
||||||
|
{
|
||||||
|
if (dotTypeRef->mDotToken->mToken == BfToken_DotDotDot)
|
||||||
|
{
|
||||||
|
hashVal = ((hashVal ^ HASH_DOTDOTDOT) << 5) - hashVal;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
hashVal = ((hashVal ^ (Hash(fieldType, ctx, BfHashFlag_AllowRef))) << 5) - hashVal;
|
hashVal = ((hashVal ^ (Hash(fieldType, ctx, (BfHashFlags)(BfHashFlag_AllowRef)))) << 5) - hashVal;
|
||||||
hashVal = ((hashVal ^ (HashNode(param->mNameNode))) << 5) - hashVal;
|
hashVal = ((hashVal ^ (HashNode(param->mNameNode))) << 5) - hashVal;
|
||||||
isFirstParam = true;
|
isFirstParam = true;
|
||||||
}
|
}
|
||||||
|
@ -3511,8 +3533,8 @@ int BfResolvedTypeSet::Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHash
|
||||||
hashVal = ((hashVal ^ (Hash(resultType, ctx, BfHashFlag_AllowRef))) << 5) - hashVal;
|
hashVal = ((hashVal ^ (Hash(resultType, ctx, BfHashFlag_AllowRef))) << 5) - hashVal;
|
||||||
return hashVal;
|
return hashVal;
|
||||||
}
|
}
|
||||||
else if (auto dotTypeRef = BfNodeDynCastExact<BfDotTypeReference>(typeRef))
|
else if (auto dotTypeRef = BfNodeDynCastExact<BfDotTypeReference>(typeRef))
|
||||||
{
|
{
|
||||||
ctx->mModule->ResolveTypeRef(dotTypeRef, BfPopulateType_Identity, ctx->mResolveFlags);
|
ctx->mModule->ResolveTypeRef(dotTypeRef, BfPopulateType_Identity, ctx->mResolveFlags);
|
||||||
ctx->mFailed = true;
|
ctx->mFailed = true;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -4009,7 +4031,7 @@ bool BfResolvedTypeSet::Equals(BfType* lhs, BfTypeReference* rhs, LookupContext*
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
bool handled = false;
|
bool handled = false;
|
||||||
auto lhsThisType = lhsDelegateInfo->mParams[0];
|
auto lhsThisType = lhsDelegateInfo->mParams[0];
|
||||||
|
|
||||||
auto rhsThisType = ctx->mModule->ResolveTypeRef(param0->mTypeRef, BfPopulateType_Identity, (BfResolveTypeRefFlags)(BfResolveTypeRefFlag_NoWarnOnMut | BfResolveTypeRefFlag_AllowRef));
|
auto rhsThisType = ctx->mModule->ResolveTypeRef(param0->mTypeRef, BfPopulateType_Identity, (BfResolveTypeRefFlags)(BfResolveTypeRefFlag_NoWarnOnMut | BfResolveTypeRefFlag_AllowRef));
|
||||||
bool wantsMutating = false;
|
bool wantsMutating = false;
|
||||||
|
@ -4032,11 +4054,16 @@ bool BfResolvedTypeSet::Equals(BfType* lhs, BfTypeReference* rhs, LookupContext*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lhsDelegateInfo->mParams.size() != (int)rhsDelegateType->mParams.size())
|
int lhsParamsCount = (int)lhsDelegateInfo->mParams.size();
|
||||||
|
if (lhsDelegateInfo->mHasVarArgs)
|
||||||
|
lhsParamsCount++;
|
||||||
|
|
||||||
|
if (lhsParamsCount != (int)rhsDelegateType->mParams.size())
|
||||||
return false;
|
return false;
|
||||||
for (int paramIdx = paramRefOfs; paramIdx < lhsDelegateInfo->mParams.size(); paramIdx++)
|
for (int paramIdx = paramRefOfs; paramIdx < lhsDelegateInfo->mParams.size(); paramIdx++)
|
||||||
{
|
{
|
||||||
if (!Equals(lhsDelegateInfo->mParams[paramIdx], rhsDelegateType->mParams[paramIdx]->mTypeRef, ctx))
|
auto paramTypeRef = rhsDelegateType->mParams[paramIdx]->mTypeRef;
|
||||||
|
if (!Equals(lhsDelegateInfo->mParams[paramIdx], paramTypeRef, ctx))
|
||||||
return false;
|
return false;
|
||||||
StringView rhsParamName;
|
StringView rhsParamName;
|
||||||
if (rhsDelegateType->mParams[paramIdx]->mNameNode != NULL)
|
if (rhsDelegateType->mParams[paramIdx]->mNameNode != NULL)
|
||||||
|
|
|
@ -32,7 +32,8 @@ enum BfResolveTypeRefFlags
|
||||||
BfResolveTypeRefFlag_NoReify = 0x200,
|
BfResolveTypeRefFlag_NoReify = 0x200,
|
||||||
BfResolveTypeRefFlag_NoCreate = 0x400,
|
BfResolveTypeRefFlag_NoCreate = 0x400,
|
||||||
BfResolveTypeRefFlag_NoWarnOnMut = 0x800,
|
BfResolveTypeRefFlag_NoWarnOnMut = 0x800,
|
||||||
BfResolveTypeRefFlag_DisallowComptime = 0x1000
|
BfResolveTypeRefFlag_DisallowComptime = 0x1000,
|
||||||
|
BfResolveTypeRefFlag_AllowDotDotDot = 0x2000
|
||||||
};
|
};
|
||||||
|
|
||||||
enum BfTypeNameFlags : uint16
|
enum BfTypeNameFlags : uint16
|
||||||
|
@ -443,12 +444,14 @@ public:
|
||||||
BfType* mReturnType;
|
BfType* mReturnType;
|
||||||
Array<BfType*> mParams;
|
Array<BfType*> mParams;
|
||||||
bool mHasExplicitThis;
|
bool mHasExplicitThis;
|
||||||
|
bool mHasVarArgs;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BfDelegateInfo()
|
BfDelegateInfo()
|
||||||
{
|
{
|
||||||
mReturnType = NULL;
|
mReturnType = NULL;
|
||||||
mHasExplicitThis = false;
|
mHasExplicitThis = false;
|
||||||
|
mHasVarArgs = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
~BfDelegateInfo()
|
~BfDelegateInfo()
|
||||||
|
@ -2478,7 +2481,8 @@ public:
|
||||||
{
|
{
|
||||||
BfHashFlag_None = 0,
|
BfHashFlag_None = 0,
|
||||||
BfHashFlag_AllowRef = 1,
|
BfHashFlag_AllowRef = 1,
|
||||||
BfHashFlag_AllowGenericParamConstValue = 2
|
BfHashFlag_AllowGenericParamConstValue = 2,
|
||||||
|
BfHashFlag_AllowDotDotDot = 4,
|
||||||
};
|
};
|
||||||
|
|
||||||
class LookupContext
|
class LookupContext
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue