123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366 |
- #pragma warning(push)
- #pragma warning(disable:4800)
- #pragma warning(disable:4244)
- #pragma warning(disable:4141)
- #pragma warning(disable:4624)
- #pragma warning(disable:4146)
- #pragma warning(disable:4267)
- #pragma warning(disable:4291)
- #include "BfCompiler.h"
- #include "BfConstResolver.h"
- #include "BfAutoComplete.h"
- #include "BfResolvePass.h"
- #include "llvm/IR/GlobalVariable.h"
- #include "BfExprEvaluator.h"
- #pragma warning(pop)
- USING_NS_BF;
- using namespace llvm;
- bool BfConstResolver::CheckAllowValue(const BfTypedValue& typedValue, BfAstNode* refNode)
- {
- if (typedValue.mValue.IsConst())
- return true;
- mModule->Fail("Expression does not evaluate to a constant value", refNode);
- return false;
- }
- BfConstResolver::BfConstResolver(BfModule* bfModule) : BfExprEvaluator(bfModule)
- {
- mIsInvalidConstExpr = false;
- mAllowGenericConstValue = false;
- }
- BfTypedValue BfConstResolver::Resolve(BfExpression* expr, BfType* wantType, BfConstResolveFlags flags)
- {
- bool explicitCast = (flags & BfConstResolveFlag_ExplicitCast) != 0;
- bool noCast = (flags & BfConstResolveFlag_NoCast) != 0;
- bool allowSoftFail = (flags & BfConstResolveFlag_AllowSoftFail) != 0;
- bool wantIgnoreWrites = mModule->mBfIRBuilder->mIgnoreWrites;
- /*if (BfNodeDynCastExact<BfTypeOfExpression>(expr) != NULL)
- {
- // Some specific expressions should be allowed to do writes like creating global variables
- }
- else*/
- {
- wantIgnoreWrites = true;
- }
- SetAndRestoreValue<bool> ignoreWrites(mModule->mBfIRBuilder->mIgnoreWrites, wantIgnoreWrites);
-
- auto prevInsertBlock = mModule->mBfIRBuilder->GetInsertBlock();
- mNoBind = true;
- if (wantType != NULL)
- mExpectingType = wantType;
- VisitChildNoRef(expr);
- mResult = GetResult();
- if (mResult)
- mResult = mModule->LoadValue(mResult);
- if ((mResult) && (wantType != NULL))
- {
- auto typeInst = mResult.mType->ToTypeInstance();
- if ((typeInst != NULL) && (typeInst->mTypeDef == mModule->mCompiler->mStringTypeDef))
- {
- BfType* toType = wantType;
- if (toType == NULL)
- toType = mResult.mType;
- if ((mResult.mValue.IsConst()) &&
- (((toType->IsPointer()) && (toType->GetUnderlyingType() == mModule->GetPrimitiveType(BfTypeCode_Char8))) ||
- (toType == mResult.mType)))
- {
- auto constant = mModule->mBfIRBuilder->GetConstant(mResult.mValue);
- if (constant->mTypeCode == BfTypeCode_NullPtr)
- {
- return mModule->GetDefaultTypedValue(toType);
- }
- else
- {
- int stringId = mModule->GetStringPoolIdx(mResult.mValue);
- BF_ASSERT(stringId >= 0);
- return BfTypedValue(mModule->GetConstValue(stringId), toType);
- }
- }
- }
- if (noCast)
- {
- //
- }
- else if (allowSoftFail)
- {
- SetAndRestoreValue<bool> prevIgnoreFail(mModule->mIgnoreErrors, true);
- auto convValue = mModule->Cast(expr, mResult, wantType, explicitCast ? BfCastFlags_Explicit : BfCastFlags_None);
- if (convValue)
- mResult = convValue;
- }
- else
- {
- mResult = mModule->Cast(expr, mResult, wantType, (BfCastFlags)(BfCastFlags_NoConversionOperator | (explicitCast ? BfCastFlags_Explicit : BfCastFlags_None)));
- }
- }
- if (mResult.mKind == BfTypedValueKind_GenericConstValue)
- {
- if (mAllowGenericConstValue)
- return mResult;
-
- auto genericParamDef = mModule->GetGenericParamInstance((BfGenericParamType*)mResult.mType);
- if ((genericParamDef->mGenericParamFlags & BfGenericParamFlag_Const) != 0)
- {
- auto genericTypeConstraint = genericParamDef->mTypeConstraint;
- if (genericTypeConstraint != NULL)
- {
- auto primType = genericTypeConstraint->ToPrimitiveType();
- if (primType != NULL)
- {
- BfTypedValue result;
- result.mKind = BfTypedValueKind_Value;
- result.mType = genericTypeConstraint;
- result.mValue = mModule->mBfIRBuilder->GetUndefConstValue(primType->mTypeDef->mTypeCode);
- return result;
- }
- }
- else
- {
- BF_FATAL("Error");
- }
- }
- }
- if (mResult)
- {
- bool isConst = mResult.mValue.IsConst();
- if (isConst)
- {
- auto constant = mModule->mBfIRBuilder->GetConstant(mResult.mValue);
- if (constant->mConstType == BfConstType_GlobalVar)
- isConst = false;
- }
- if ((!isConst) && ((mBfEvalExprFlags & BfEvalExprFlags_AllowNonConst) == 0))
- {
- mModule->Fail("Expression does not evaluate to a constant value", expr);
- if (wantType != NULL)
- mResult = mModule->GetDefaultTypedValue(wantType);
- else
- mResult = BfTypedValue();
- }
- }
- else
- {
- if (wantType != NULL)
- mResult = mModule->GetDefaultTypedValue(wantType);
- }
- if (prevInsertBlock)
- mModule->mBfIRBuilder->SetInsertPoint(prevInsertBlock);
- /*ignoreWrites.Restore();
- if ((!mModule->mBfIRBuilder->mIgnoreWrites) && (prevInsertBlock))
- {
- BF_ASSERT(!prevInsertBlock.IsFake());
- mModule->mBfIRBuilder->SetInsertPoint(prevInsertBlock);
- }*/
- mModule->FixIntUnknown(mResult);
- return mResult;
- }
- bool BfConstResolver::PrepareMethodArguments(BfAstNode* targetSrc, BfMethodMatcher* methodMatcher, Array<BfIRValue>& llvmArgs)
- {
- int argIdx = 0;
- int paramIdx = 0;
- int extendedParamIdx = 0;
- llvm::SmallVector<BfIRValue, 4> expandedParamsConstValues;
- BfType* expandedParamsElementType = NULL;
-
- // We don't do GetMethodInstance in mModule, because our module may not have init finished yet
- //auto targetModule = methodMatcher->mBestMethodTypeInstance->mModule;
- auto targetModule = mModule->mContext->mUnreifiedModule;
- auto moduleMethodInstance = targetModule->GetMethodInstance(methodMatcher->mBestMethodTypeInstance, methodMatcher->mBestMethodDef, methodMatcher->mBestMethodGenericArguments);
- auto methodInstance = moduleMethodInstance.mMethodInstance;
- if (methodInstance->mReturnType == NULL)
- {
- mModule->AssertErrorState();
- return false;
- }
- auto methodDef = methodMatcher->mBestMethodDef;
- auto& arguments = methodMatcher->mArguments;
- mModule->AddDependency(methodInstance->mReturnType, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_LocalUsage);
- for (int paramIdx = 0; paramIdx < methodInstance->GetParamCount(); paramIdx++)
- {
- auto paramType = methodInstance->GetParamType(paramIdx);
- mModule->AddDependency(paramType, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_LocalUsage);
- }
- while (true)
- {
- if (paramIdx >= (int)methodInstance->GetParamCount())
- {
- if (argIdx < (int)arguments.size())
- {
- BfAstNode* errorRef = arguments[methodInstance->GetParamCount()].mExpression;
- if (errorRef->GetSourceData() == NULL)
- errorRef = targetSrc;
- mModule->Fail(StrFormat("Too many arguments. Expected %d fewer.", (int)arguments.size() - methodInstance->GetParamCount()), errorRef);
- if (methodInstance->mMethodDef->mMethodDeclaration != NULL)
- mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See method declaration"), methodInstance->mMethodDef->mMethodDeclaration);
- return false;
- }
- break;
- }
- BfType* wantType = NULL;
- if (expandedParamsElementType != NULL)
- {
- wantType = expandedParamsElementType;
- }
- else
- {
- wantType = methodInstance->GetParamType(paramIdx);
- if (methodInstance->GetParamKind(paramIdx) == BfParamKind_Params)
- {
- //TODO: Check to see if it's a direct array pass
- bool isDirectPass = false;
- if (argIdx < (int)arguments.size())
- {
- if (!arguments[argIdx].mTypedValue.mValue)
- return false;
- if (mModule->CanImplicitlyCast(arguments[argIdx].mTypedValue, wantType))
- isDirectPass = true;
- }
- if (!isDirectPass)
- {
- BfArrayType* arrayType = (BfArrayType*)wantType;
- if (arrayType->IsIncomplete())
- mModule->PopulateType(arrayType, BfPopulateType_DataAndMethods);
- expandedParamsElementType = arrayType->mTypeGenericArguments[0];
- continue;
- }
- }
- }
- BfAstNode* argExpr = NULL;
- if (argIdx < (int)arguments.size())
- {
- argExpr = arguments[argIdx].mExpression;
- }
- else
- {
- if (expandedParamsElementType != NULL)
- break;
- if ((argIdx >= (int)methodInstance->mDefaultValues.size()) || (!methodInstance->mDefaultValues[argIdx]))
- {
- BfAstNode* refNode = targetSrc;
- if (arguments.size() > 0)
- refNode = arguments.back().mExpression;
- BfAstNode* prevNode = NULL;
- #ifdef BF_AST_HAS_PARENT_MEMBER
- if (auto attributeDirective = BfNodeDynCast<BfAttributeDirective>(targetSrc->mParent))
- {
- BF_ASSERT(mModule->mParentNodeEntry->mNode == attributeDirective);
- }
- #endif
- if (mModule->mParentNodeEntry != NULL)
- {
- if (auto attributeDirective = BfNodeDynCast<BfAttributeDirective>(mModule->mParentNodeEntry->mNode))
- {
- if (attributeDirective->mCommas.size() > 0)
- prevNode = attributeDirective->mCommas.back();
- else
- prevNode = attributeDirective->mCtorOpenParen;
- if (attributeDirective->mCtorCloseParen != NULL)
- refNode = attributeDirective->mCtorCloseParen;
- }
- }
- auto autoComplete = GetAutoComplete();
- if (autoComplete != NULL)
- {
- if (prevNode != NULL)
- {
- autoComplete->CheckEmptyStart(prevNode, wantType);
- }
- }
- mModule->Fail(StrFormat("Not enough parameters specified. Expected %d fewer.", methodInstance->GetParamCount() - (int)arguments.size()), refNode);
- return false;
- }
- auto foreignDefaultVal = methodInstance->mDefaultValues[argIdx];
- auto foreignConst = methodInstance->GetOwner()->mConstHolder->GetConstant(methodInstance->mDefaultValues[argIdx]);
- auto constVal = mModule->ConstantToCurrent(foreignConst, methodInstance->GetOwner()->mConstHolder, wantType);
- llvmArgs.push_back(constVal);
- argIdx++;
- paramIdx++;
- continue;
- }
- auto argValue = arguments[argIdx].mTypedValue;
- auto& arg = arguments[argIdx];
- if ((arg.mArgFlags & BfArgFlag_DeferredEval) != 0)
- {
- mExpectingType = arg.mExpectedType;
- if (auto expr = BfNodeDynCast<BfExpression>(argExpr))
- argValue = Resolve(expr, mExpectingType);
- arg.mArgFlags = BfArgFlag_None;
- }
-
- if (!argValue)
- return BfTypedValue();
- if (argExpr != NULL)
- {
- argValue = mModule->Cast(argExpr, argValue, wantType);
- if (!argValue)
- return false;
- }
- if (!argValue)
- {
- mModule->Fail("Invalid expression type", argExpr);
- return false;
- }
- if (expandedParamsElementType != NULL)
- {
- expandedParamsConstValues.push_back(argValue.mValue);
- extendedParamIdx++;
- }
- else
- {
- llvmArgs.push_back(argValue.mValue);
- paramIdx++;
- }
- argIdx++;
- }
- if (expandedParamsElementType != NULL)
- {
- auto arrayType = mModule->mBfIRBuilder->GetSizedArrayType(mModule->mBfIRBuilder->MapType(expandedParamsElementType), (int)expandedParamsConstValues.size());
- auto constArray = mModule->mBfIRBuilder->CreateConstArray(arrayType, expandedParamsConstValues);
- llvmArgs.push_back(constArray);
- }
- return true;
- }
|