diff --git a/BeefySysLib/util/HashSet.h b/BeefySysLib/util/HashSet.h index 36d11247..32660f10 100644 --- a/BeefySysLib/util/HashSet.h +++ b/BeefySysLib/util/HashSet.h @@ -257,10 +257,10 @@ private: void Resize(intptr newSize, bool forceNewHashCodes) { BF_ASSERT(newSize >= mAllocSize); - int_cosize* newBuckets = (int_cosize*)rawAllocate(sizeof(int_cosize) * newSize); + int_cosize* newBuckets = (int_cosize*)this->rawAllocate(sizeof(int_cosize) * newSize); for (int_cosize i = 0; i < newSize; i++) newBuckets[i] = -1; - Entry* newEntries = (Entry*)rawAllocate(sizeof(Entry)*newSize); + Entry* newEntries = (Entry*)this->rawAllocate(sizeof(Entry)*newSize); for (int i = 0; i < mCount; i++) { @@ -294,8 +294,8 @@ private: } } - rawDeallocate(mBuckets); - rawDeallocate(mEntries); + this->rawDeallocate(mBuckets); + this->rawDeallocate(mEntries); mBuckets = newBuckets; mEntries = newEntries; @@ -332,10 +332,10 @@ private: void Initialize(intptr capacity) { int_cosize size = GetPrimeish((int_cosize)capacity); - mBuckets = (int_cosize*)rawAllocate(sizeof(int_cosize) * size); + mBuckets = (int_cosize*)this->rawAllocate(sizeof(int_cosize) * size); mAllocSize = size; for (int_cosize i = 0; i < (int_cosize)mAllocSize; i++) mBuckets[i] = -1; - mEntries = (Entry*)rawAllocate(sizeof(Entry) * size); + mEntries = (Entry*)this->rawAllocate(sizeof(Entry) * size); mFreeList = -1; } @@ -431,8 +431,8 @@ public: } else { - mBuckets = (int_cosize*)rawAllocate(sizeof(int_cosize) * mAllocSize); - mEntries = (Entry*)rawAllocate(sizeof(Entry) * mAllocSize); + mBuckets = (int_cosize*)this->rawAllocate(sizeof(int_cosize) * mAllocSize); + mEntries = (Entry*)this->rawAllocate(sizeof(Entry) * mAllocSize); for (int_cosize i = 0; i < mAllocSize; i++) mBuckets[i] = val.mBuckets[i]; @@ -476,8 +476,8 @@ public: } } - rawDeallocate(mBuckets); - rawDeallocate(mEntries); + this->rawDeallocate(mBuckets); + this->rawDeallocate(mEntries); } HashSet& operator=(const HashSet& rhs) diff --git a/IDEHelper/Compiler/BfExprEvaluator.cpp b/IDEHelper/Compiler/BfExprEvaluator.cpp index f14328e9..71bf25d6 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.cpp +++ b/IDEHelper/Compiler/BfExprEvaluator.cpp @@ -991,6 +991,101 @@ bool BfMethodMatcher::WantsCheckMethod(BfProtectionCheckFlags& flags, BfTypeInst return true; } +bool BfMethodMatcher::InferFromGenericConstraints(BfGenericParamInstance* genericParamInst, BfTypeVector* methodGenericArgs) +{ + if ((genericParamInst->mGenericParamFlags & BfGenericParamFlag_Equals) == 0) + return false; + + if (!genericParamInst->mExternType->IsGenericParam()) + return false; + + auto genericParamType = (BfGenericParamType*)genericParamInst->mExternType; + if (genericParamType->mGenericParamKind != BfGenericParamKind_Method) + return false; + + BfType* checkArgType = NULL; + + if ((genericParamInst->mGenericParamFlags & BfGenericParamFlag_Equals_Type) != 0) + { + checkArgType = genericParamInst->mTypeConstraint; + } + + if ((genericParamInst->mGenericParamFlags & BfGenericParamFlag_Equals_IFace) != 0) + { + if (!genericParamInst->mInterfaceConstraints.IsEmpty()) + checkArgType = genericParamInst->mInterfaceConstraints[0]; + } + + for (auto& checkOpConstraint : genericParamInst->mOperatorConstraints) + { + auto leftType = checkOpConstraint.mLeftType; + if ((leftType != NULL) && (leftType->IsUnspecializedType())) + leftType = mModule->ResolveGenericType(leftType, *methodGenericArgs); + if (leftType != NULL) + leftType = mModule->FixIntUnknown(leftType); + + auto rightType = checkOpConstraint.mRightType; + if ((rightType != NULL) && (rightType->IsUnspecializedType())) + rightType = mModule->ResolveGenericType(rightType, *methodGenericArgs); + if (rightType != NULL) + rightType = mModule->FixIntUnknown(rightType); + + if (checkOpConstraint.mBinaryOp != BfBinaryOp_None) + { + BfExprEvaluator exprEvaluator(mModule); + + BfTypedValue leftValue(mModule->mBfIRBuilder->GetFakeVal(), leftType); + BfTypedValue rightValue(mModule->mBfIRBuilder->GetFakeVal(), rightType); + + // + { + SetAndRestoreValue prevIgnoreErrors(mModule->mIgnoreErrors, true); + SetAndRestoreValue prevIgnoreWrites(mModule->mBfIRBuilder->mIgnoreWrites, true); + exprEvaluator.PerformBinaryOperation(NULL, NULL, checkOpConstraint.mBinaryOp, NULL, BfBinOpFlag_NoClassify, leftValue, rightValue); + } + + if ((genericParamInst->mGenericParamFlags & BfGenericParamFlag_Equals_Op) != 0) + checkArgType = exprEvaluator.mResult.mType; + } + else + { + BfTypedValue rightValue(mModule->mBfIRBuilder->GetFakeVal(), rightType); + + StringT<128> failedOpName; + + if (checkOpConstraint.mCastToken == BfToken_Implicit) + { + + } + else + { + SetAndRestoreValue prevIgnoreErrors(mModule->mIgnoreErrors, true); + SetAndRestoreValue prevIgnoreWrites(mModule->mBfIRBuilder->mIgnoreWrites, true); + + if (checkOpConstraint.mCastToken == BfToken_Explicit) + { + + } + else + { + BfExprEvaluator exprEvaluator(mModule); + exprEvaluator.mResult = rightValue; + exprEvaluator.PerformUnaryOperation(NULL, checkOpConstraint.mUnaryOp, NULL); + + if ((genericParamInst->mGenericParamFlags & BfGenericParamFlag_Equals_Op) != 0) + checkArgType = exprEvaluator.mResult.mType; + } + } + } + } + + if (checkArgType == NULL) + return false; + + (*methodGenericArgs)[genericParamType->mGenericParamIdx] = checkArgType; + return true; +} + bool BfMethodMatcher::CheckMethod(BfTypeInstance* typeInstance, BfMethodDef* checkMethod, bool isFailurePass) { BP_ZONE("BfMethodMatcher::CheckMethod"); @@ -1185,23 +1280,9 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* typeInstance, BfMethodDef* che if (genericArg == NULL) { auto genericParam = methodInstance->mMethodInfoEx->mGenericParams[genericArgIdx]; - //mModule->CheckGenericConstraints(BfGenericParamSource(), NULL, NULL, genericParam, &mCheckMethodGenericArguments, NULL); + InferFromGenericConstraints(genericParam, &mCheckMethodGenericArguments); if (genericArg != NULL) continue; - -// if ((genericParam->mGenericParamFlags & BfGenericParamFlag_Equals) != 0) -// { -// if ((genericParam->mGenericParamFlags & BfGenericParamFlag_Equals_Op) != 0) -// { -// -// } -// -// else if ((genericParam->mGenericParamFlags & BfGenericParamFlag_Equals_Type) != 0) -// { -// -// } -// } - if (!allowEmptyGenericSet.Contains(genericArgIdx)) goto NoMatch; } @@ -1361,11 +1442,11 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* typeInstance, BfMethodDef* che goto NoMatch; } - if (genericArg->IsPrimitiveType()) - { - auto primType = (BfPrimitiveType*) genericArg; - genericArg = mModule->GetPrimitiveStructType(primType->mTypeDef->mTypeCode); - } +// if (genericArg->IsPrimitiveType()) +// { +// auto primType = (BfPrimitiveType*) genericArg; +// genericArg = mModule->GetPrimitiveStructType(primType->mTypeDef->mTypeCode); +// } if (genericArg == NULL) goto NoMatch; diff --git a/IDEHelper/Compiler/BfExprEvaluator.h b/IDEHelper/Compiler/BfExprEvaluator.h index a3210dac..a1f4187b 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.h +++ b/IDEHelper/Compiler/BfExprEvaluator.h @@ -156,6 +156,7 @@ public: public: BfTypedValue ResolveArgTypedValue(BfResolvedArg& resolvedArg, BfType* checkType, BfTypeVector* genericArgumentsSubstitute); bool InferGenericArgument(BfMethodInstance* methodInstance, BfType* argType, BfType* wantType, BfIRValue argValue); + bool InferFromGenericConstraints(BfGenericParamInstance* genericParamInst, BfTypeVector* methodGenericArgs); void CompareMethods(BfMethodInstance* prevMethodInstance, BfTypeVector* prevGenericArgumentsSubstitute, BfMethodInstance* newMethodInstance, BfTypeVector* genericArgumentsSubstitute, bool* outNewIsBetter, bool* outNewIsWorse, bool allowSpecializeFail); diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index fff86946..70061fb7 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -6237,7 +6237,7 @@ void BfModule::ResolveGenericParamConstraints(BfGenericParamInstance* genericPar else { opConstraintInstance.mUnaryOp = BfTokenToUnaryOp(opConstraint->mOpToken->mToken); - if (opConstraintInstance.mUnaryOp == BfBinaryOp_None) + if (opConstraintInstance.mUnaryOp == BfUnaryOp_None) { Fail("Invalid unary operator", opConstraint->mOpToken); continue; @@ -6706,7 +6706,7 @@ bool BfModule::CheckGenericConstraints(const BfGenericParamSource& genericParamS exprEvaluator.PerformBinaryOperation(NULL, NULL, checkOpConstraint.mBinaryOp, NULL, BfBinOpFlag_NoClassify, leftValue, rightValue); } - if ((exprEvaluator.mResult == NULL) || + if ((!exprEvaluator.mResult) || (!CanImplicitlyCast(exprEvaluator.mResult, origCheckArgType))) { if (!ignoreErrors) @@ -6745,7 +6745,7 @@ bool BfModule::CheckGenericConstraints(const BfGenericParamSource& genericParamS exprEvaluator.mResult = rightValue; exprEvaluator.PerformUnaryOperation(NULL, checkOpConstraint.mUnaryOp, NULL); - if ((exprEvaluator.mResult == NULL) || + if ((!exprEvaluator.mResult) || (!CanImplicitlyCast(exprEvaluator.mResult, origCheckArgType))) { failedOpName += "unary operation '"; diff --git a/IDEHelper/Compiler/BfModuleTypeUtils.cpp b/IDEHelper/Compiler/BfModuleTypeUtils.cpp index eaea6d0e..151e8559 100644 --- a/IDEHelper/Compiler/BfModuleTypeUtils.cpp +++ b/IDEHelper/Compiler/BfModuleTypeUtils.cpp @@ -9021,7 +9021,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp Warn(0, "This implicit boxing will only be in scope during the constructor. Consider using a longer-term allocation such as 'box new'", srcNode); } - SetAndRestoreValue ignoreWrites(mBfIRBuilder->mIgnoreWrites, ignoreWrites); + SetAndRestoreValue prevIgnoreWrites(mBfIRBuilder->mIgnoreWrites, ignoreWrites); auto value = BoxValue(srcNode, typedVal, toType, scopeData, (castFlags & BfCastFlags_NoBoxDtor) == 0); if (value) return value.mValue; diff --git a/IDEHelper/IDEHelper.vcxproj b/IDEHelper/IDEHelper.vcxproj index 7b7740c9..cefba720 100644 --- a/IDEHelper/IDEHelper.vcxproj +++ b/IDEHelper/IDEHelper.vcxproj @@ -218,7 +218,7 @@ MaxSpeed true true - BP_DISABLED;WIN32;NDEBUG;_WINDOWS;_USRDLL;IDEHELPER_EXPORTS;BFSYSLIB_DYNAMIC;%(PreprocessorDefinitions) + zBP_DISABLED;WIN32;NDEBUG;_WINDOWS;_USRDLL;IDEHELPER_EXPORTS;BFSYSLIB_DYNAMIC;%(PreprocessorDefinitions) ../;../BeefySysLib/platform/win;../BeefySysLib/third_party;..\extern\llvm-project_8_0_1\llvm\include;..\extern\llvm_win64_8_0_1\include;..\extern\llvm-project_8_0_1\llvm\lib\Target;..\extern\llvm_win64_8_0_1\lib\Target\X86;..\extern\llvm-project_8_0_1\llvm\tools\clang\include;..\extern\curl\builds\libcurl-vc15-x64-release-static-zlib-static-ipv6-sspi-winssl\include MultiThreaded false