1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-10 04:22:20 +02:00

Allow '...' varargs in delegate and function types

This commit is contained in:
Brian Fiete 2021-02-02 07:08:55 -08:00
parent 7e139f5d7c
commit b916273a97
5 changed files with 95 additions and 19 deletions

View file

@ -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 += '@';

View file

@ -7629,6 +7629,7 @@ BfType* BfModule::ResolveGenericType(BfType* unspecializedType, BfTypeVector* ty
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)
{ {
@ -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);
@ -10366,6 +10383,13 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
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))
{ {

View file

@ -9262,6 +9262,15 @@ bool BfReducer::ParseMethod(BfMethodDeclaration* methodDeclaration, SizedArrayIm
methodDeclaration->mOpenParen = tokenNode; methodDeclaration->mOpenParen = tokenNode;
MoveNode(methodDeclaration->mOpenParen, methodDeclaration); MoveNode(methodDeclaration->mOpenParen, methodDeclaration);
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 (auto nextToken = BfNodeDynCast<BfTokenNode>(mVisitorPos.GetNext())) if (auto nextToken = BfNodeDynCast<BfTokenNode>(mVisitorPos.GetNext()))
{ {
if (nextToken->mToken == BfToken_This) if (nextToken->mToken == BfToken_This)
@ -9270,6 +9279,7 @@ bool BfReducer::ParseMethod(BfMethodDeclaration* methodDeclaration, SizedArrayIm
mVisitorPos.MoveNext(); mVisitorPos.MoveNext();
} }
} }
}
methodDeclaration->mCloseParen = ParseMethodParams(methodDeclaration, params, commas, BfToken_RParen, true); methodDeclaration->mCloseParen = ParseMethodParams(methodDeclaration, params, commas, BfToken_RParen, true);

View file

@ -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,7 +2809,12 @@ 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++)
{ {
@ -2819,6 +2825,9 @@ int BfResolvedTypeSet::Hash(BfType* type, LookupContext* ctx, bool allowRef)
hashVal = ((hashVal ^ (nameHash)) << 5) - hashVal; hashVal = ((hashVal ^ (nameHash)) << 5) - hashVal;
} }
if (delegateInfo->mHasVarArgs)
hashVal = ((hashVal ^ HASH_DOTDOTDOT) << 5) - hashVal;
return hashVal; return hashVal;
} }
else if (type->IsTypeInstance()) else if (type->IsTypeInstance())
@ -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;
@ -3411,7 +3421,19 @@ int BfResolvedTypeSet::Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHash
} }
} }
hashVal = ((hashVal ^ (Hash(fieldType, ctx, BfHashFlag_AllowRef))) << 5) - hashVal; 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, (BfHashFlags)(BfHashFlag_AllowRef)))) << 5) - hashVal;
hashVal = ((hashVal ^ (HashNode(param->mNameNode))) << 5) - hashVal; hashVal = ((hashVal ^ (HashNode(param->mNameNode))) << 5) - hashVal;
isFirstParam = true; isFirstParam = true;
} }
@ -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)

View file

@ -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