| 3557 | } |
| 3558 | |
| 3559 | void BfResolvedTypeSet::HashGenericArguments(BfTypeReference* typeRef, LookupContext* ctx, int& hashVal, int hashSeed) |
| 3560 | { |
| 3561 | if (auto genericTypeRef = BfNodeDynCast<BfGenericInstanceTypeRef>(typeRef)) |
| 3562 | { |
| 3563 | for (int genericIdx = 0; genericIdx < BF_MAX(genericTypeRef->mGenericArguments.mSize, genericTypeRef->mCommas.mSize + 1); genericIdx++) |
| 3564 | { |
| 3565 | bool allowUnboundGeneric = ((ctx->mResolveFlags & BfResolveTypeRefFlag_AllowUnboundGeneric) != 0) && (hashSeed == 0); |
| 3566 | |
| 3567 | BfAstNode* genericArgTypeRef = NULL; |
| 3568 | if (genericIdx < genericTypeRef->mGenericArguments.mSize) |
| 3569 | genericArgTypeRef = genericTypeRef->mGenericArguments[genericIdx]; |
| 3570 | |
| 3571 | if (allowUnboundGeneric) |
| 3572 | { |
| 3573 | if (BfNodeIsExact<BfWildcardTypeReference>(genericArgTypeRef)) |
| 3574 | genericArgTypeRef = NULL; |
| 3575 | } |
| 3576 | |
| 3577 | int argHashVal = 0; |
| 3578 | if (genericArgTypeRef != NULL) |
| 3579 | { |
| 3580 | argHashVal = Hash(genericArgTypeRef, ctx, BfHashFlag_AllowGenericParamConstValue, hashSeed + 1); |
| 3581 | if ((allowUnboundGeneric) && ((ctx->mResolveFlags & BfResolveTypeRefFlag_ForceUnboundGeneric) != 0)) |
| 3582 | genericArgTypeRef = NULL; |
| 3583 | } |
| 3584 | |
| 3585 | if (genericArgTypeRef == NULL) |
| 3586 | { |
| 3587 | if (allowUnboundGeneric) |
| 3588 | { |
| 3589 | ctx->mIsUnboundGeneric = true; |
| 3590 | argHashVal = (((int)BfGenericParamKind_Type + 0xB00) << 8) ^ (genericIdx + 1); |
| 3591 | argHashVal = HASH_MIX(argHashVal, hashSeed + 1); |
| 3592 | } |
| 3593 | else |
| 3594 | { |
| 3595 | ctx->mModule->Fail("Generic argument expected", genericTypeRef->mOpenChevron); |
| 3596 | ctx->mFailed = true; |
| 3597 | return; |
| 3598 | } |
| 3599 | } |
| 3600 | |
| 3601 | hashVal = HASH_MIX(hashVal, argHashVal); |
| 3602 | } |
| 3603 | } |
| 3604 | } |
| 3605 | |
| 3606 | static int HashNode(BfAstNode* node) |
| 3607 | { |