diff --git a/IDEHelper/Compiler/BfExprEvaluator.cpp b/IDEHelper/Compiler/BfExprEvaluator.cpp index ab3e38cd..cfd5dedd 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.cpp +++ b/IDEHelper/Compiler/BfExprEvaluator.cpp @@ -17660,6 +17660,41 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod } } + // Check for constant equality checks (mostly for strings) + if ((binaryOp == BfBinaryOp_Equality) || (binaryOp == BfBinaryOp_InEquality)) + { + auto leftConstant = mModule->mBfIRBuilder->GetConstant(leftValue.mValue); + auto rightConstant = mModule->mBfIRBuilder->GetConstant(rightValue.mValue); + + if ((leftConstant != NULL) && (rightConstant != NULL)) + { + auto boolType = mModule->GetPrimitiveType(BfTypeCode_Boolean); + int leftStringPoolIdx = mModule->GetStringPoolIdx(leftValue.mValue, mModule->mBfIRBuilder); + if (leftStringPoolIdx != -1) + { + int rightStringPoolIdx = mModule->GetStringPoolIdx(rightValue.mValue, mModule->mBfIRBuilder); + if (rightStringPoolIdx != -1) + { + bool isEqual = leftStringPoolIdx == rightStringPoolIdx; + if (binaryOp == BfBinaryOp_InEquality) + isEqual = !isEqual; + mResult = BfTypedValue(mModule->GetConstValue(isEqual ? 1 : 0, boolType), boolType); + return; + } + } + + int eqResult = mModule->mBfIRBuilder->CheckConstEquality(leftValue.mValue, rightValue.mValue); + if (eqResult != -1) + { + bool isEqual = eqResult == 1; + if (binaryOp == BfBinaryOp_InEquality) + isEqual = !isEqual; + mResult = BfTypedValue(mModule->GetConstValue(isEqual ? 1 : 0, boolType), boolType); + return; + } + } + } + if ((leftValue.mType->IsTypeInstance()) || (leftValue.mType->IsGenericParam()) || (rightValue.mType->IsTypeInstance()) || (rightValue.mType->IsGenericParam())) { diff --git a/IDEHelper/Compiler/BfIRBuilder.cpp b/IDEHelper/Compiler/BfIRBuilder.cpp index a662d5c4..2f57aed7 100644 --- a/IDEHelper/Compiler/BfIRBuilder.cpp +++ b/IDEHelper/Compiler/BfIRBuilder.cpp @@ -344,6 +344,29 @@ bool BfIRConstHolder::TryGetBool(BfIRValue id, bool& boolVal) return false; } +int BfIRConstHolder::CheckConstEquality(BfIRValue lhs, BfIRValue rhs) +{ + auto constLHS = GetConstant(lhs); + if (constLHS == NULL) + return -1; + auto constRHS = GetConstant(rhs); + if (constRHS == NULL) + return -1; + + if (constLHS->mConstType == BfConstType_BitCast) + return CheckConstEquality(BfIRValue(BfIRValueFlags_Const, ((BfConstantBitCast*)constLHS)->mTarget), rhs); + if (constRHS->mConstType == BfConstType_BitCast) + return CheckConstEquality(lhs, BfIRValue(BfIRValueFlags_Const, ((BfConstantBitCast*)constRHS)->mTarget)); + + if ((constLHS->mConstType == BfConstType_GlobalVar) && + (constRHS->mConstType == BfConstType_GlobalVar)) + { + return (constLHS == constRHS) ? 1 : 0; + } + + return -1; +} + BfIRValue BfIRConstHolder::CreateConst(BfTypeCode typeCode, uint64 val) { if (typeCode == BfTypeCode_IntUnknown) diff --git a/IDEHelper/Compiler/BfIRBuilder.h b/IDEHelper/Compiler/BfIRBuilder.h index 610b4fd1..2a2c2414 100644 --- a/IDEHelper/Compiler/BfIRBuilder.h +++ b/IDEHelper/Compiler/BfIRBuilder.h @@ -830,6 +830,7 @@ public: BfConstant* GetConstantById(int id); BfConstant* GetConstant(BfIRValue id); bool TryGetBool(BfIRValue id, bool& boolVal); + int CheckConstEquality(BfIRValue lhs, BfIRValue rhs); // -1 = fail, 0 = false, 1 = true BfIRValue CreateConst(BfTypeCode typeCode, uint64 val); BfIRValue CreateConst(BfTypeCode typeCode, int val); @@ -840,7 +841,7 @@ public: BfIRValue CreateConstStructZero(BfIRType aggType); BfIRValue CreateConstArray(BfIRType type, const BfSizedArray& values); BfIRValue CreateTypeOf(BfType* type); - BfIRValue GetUndefConstValue(BfTypeCode typeCode); + BfIRValue GetUndefConstValue(BfTypeCode typeCode); }; enum BfIRPopulateType