123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453 |
- #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;
- }
- BfTypedValue BfConstResolver::Resolve(BfExpression* expr, BfType* wantType, BfConstResolveFlags flags)
- {
- mBfEvalExprFlags = (BfEvalExprFlags)(mBfEvalExprFlags | BfEvalExprFlags_Comptime);
- // Handle the 'int[?] val = .(1, 2, 3)' case
- if ((flags & BfConstResolveFlag_ArrayInitSize) != 0)
- {
- if (auto uninitExpr = BfNodeDynCast<BfUninitializedExpression>(expr))
- {
- BfAstNode* initializer = NULL;
- int arraySize = -1;
- if (mModule->mContext->mCurTypeState != NULL)
- {
- if (mModule->mContext->mCurTypeState->mCurFieldDef != NULL)
- initializer = mModule->mContext->mCurTypeState->mCurFieldDef->GetInitializer();
- if (mModule->mContext->mCurTypeState->mCurVarInitializer != NULL)
- initializer = mModule->mContext->mCurTypeState->mCurVarInitializer;
- if (mModule->mContext->mCurTypeState->mArrayInitializerSize != -1)
- arraySize = mModule->mContext->mCurTypeState->mArrayInitializerSize;
- }
- if (initializer != NULL)
- {
- if (auto invocationExpr = BfNodeDynCast<BfInvocationExpression>(initializer))
- {
- if (auto memberRefExpr = BfNodeDynCast<BfMemberReferenceExpression>(invocationExpr->mTarget))
- {
- // Dot-initialized
- if (memberRefExpr->mTarget == NULL)
- arraySize = (int)invocationExpr->mArguments.size();
- }
- else if (auto indexerExpr = BfNodeDynCast<BfIndexerExpression>(invocationExpr->mTarget))
- {
- if (indexerExpr->mArguments.size() == 0)
- {
- // Inferred-type sized array initializer
- arraySize = (int)invocationExpr->mArguments.size();
- }
- }
- }
- }
- if (arraySize != -1)
- {
- mResult = BfTypedValue(mModule->GetConstValue(arraySize), mModule->GetPrimitiveType(BfTypeCode_IntPtr));
- return mResult;
- }
- else
- {
- mResult = BfTypedValue(mModule->mBfIRBuilder->GetUndefConstValue(mModule->mBfIRBuilder->GetPrimitiveType(BfTypeCode_IntPtr)), mModule->GetPrimitiveType(BfTypeCode_IntPtr));
- return mResult;
- }
- }
- }
- 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> prevIgnoreWrites(mModule->mBfIRBuilder->mIgnoreWrites, wantIgnoreWrites);
- auto prevInsertBlock = mModule->mBfIRBuilder->GetInsertBlock();
- mNoBind = true;
- if (wantType != NULL)
- mExpectingType = wantType;
- VisitChildNoRef(expr);
- mResult = GetResult();
- auto compilerVal = mModule->GetCompilerFieldValue(mResult);
- if (compilerVal)
- mResult = compilerVal;
- if ((mResult) && (wantType != NULL))
- {
- auto typeInst = mResult.mType->ToTypeInstance();
- if ((typeInst != NULL) && (typeInst->IsInstanceOf(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);
- if (stringId != -1)
- {
- if ((flags & BfConstResolveFlag_ActualizeValues) != 0)
- {
- prevIgnoreWrites.Restore();
- mModule->mBfIRBuilder->PopulateType(mResult.mType);
- return BfTypedValue(mModule->GetStringObjectValue(stringId, false, true), mResult.mType);
- }
- return BfTypedValue(mModule->mBfIRBuilder->CreateConst(BfTypeCode_StringId, 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
- {
- BfCastFlags castFlags = (BfCastFlags)(BfCastFlags_WantsConst | (explicitCast ? BfCastFlags_Explicit : BfCastFlags_None));
- if ((flags & BfConstResolveFlag_NoConversionOperator) != 0)
- castFlags = (BfCastFlags)(castFlags | BfCastFlags_NoConversionOperator);
- mResult = mModule->Cast(expr, mResult, wantType, castFlags);
- }
- }
- if (mResult.mKind == BfTypedValueKind_GenericConstValue)
- {
- if ((mBfEvalExprFlags & BfEvalExprFlags_AllowGenericConstValue) != 0)
- return mResult;
- }
- if (mResult)
- {
- bool isConst = mResult.mValue.IsConst();
- if (isConst)
- {
- auto constant = mModule->mBfIRBuilder->GetConstant(mResult.mValue);
- if ((constant->mTypeCode != BfTypeCode_StringId) && (mModule->HasStringId(mResult.mValue, mModule->mBfIRBuilder)))
- {
- mModule->Fail("Invalid usage of string constant", expr);
- mResult = BfTypedValue();
- }
- else if ((constant->mConstType == BfConstType_GlobalVar) && ((flags & BfConstResolveFlag_AllowGlobalVariable) == 0))
- {
- int stringId = mModule->GetStringPoolIdx(mResult.mValue, mModule->mBfIRBuilder);
- if (stringId != -1)
- {
- mResult.mValue = mModule->mBfIRBuilder->CreateConst(BfTypeCode_StringId, stringId);
- }
- else
- 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);
- if ((flags & BfConstResolveFlag_NoActualizeValues) == 0)
- {
- if (mModule->mBfIRBuilder->mHasStarted)
- prevIgnoreWrites.Restore();
- mModule->FixValueActualization(mResult, !prevIgnoreWrites.mPrevVal || ((flags & BfConstResolveFlag_ActualizeValues) != 0));
- }
- return mResult;
- }
- bool BfConstResolver::PrepareMethodArguments(BfAstNode* targetSrc, BfMethodMatcher* methodMatcher, Array<BfIRValue>& llvmArgs)
- {
- int argIdx = 0;
- int paramIdx = 0;
- int extendedParamIdx = 0;
- SetAndRestoreValue<bool> ignoreWrites(mModule->mBfIRBuilder->mIgnoreWrites, true);
- 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->CanCast(arguments[argIdx].mTypedValue, wantType))
- isDirectPass = true;
- }
- if ((!isDirectPass) && (wantType->IsArray()))
- {
- BfArrayType* arrayType = (BfArrayType*)wantType;
- if (arrayType->IsIncomplete())
- mModule->PopulateType(arrayType, BfPopulateType_DataAndMethods);
- expandedParamsElementType = arrayType->mGenericTypeInfo->mTypeGenericArguments[0];
- continue;
- }
- }
- }
- BfTypedValue argValue;
- 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);
- }
- }
- if (mModule->PreFail())
- mModule->Fail(StrFormat("Not enough parameters specified. Expected %d more.", methodInstance->GetParamCount() - (int)arguments.size()), refNode);
- return false;
- }
- auto foreignDefaultVal = methodInstance->mDefaultValues[argIdx];
- auto foreignConst = methodInstance->GetOwner()->mConstHolder->GetConstant(foreignDefaultVal.mValue);
- argValue = mModule->GetTypedValueFromConstant(foreignConst, methodInstance->GetOwner()->mConstHolder, foreignDefaultVal.mType);
- }
- if ((!argValue) && (argIdx < arguments.size()))
- {
- argValue = arguments[argIdx].mTypedValue;
- auto& arg = arguments[argIdx];
- if ((arg.mArgFlags & BfArgFlag_DeferredEval) != 0)
- {
- mExpectingType = arg.mExpectedType;
- if (mExpectingType == NULL)
- mExpectingType = wantType;
- 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, (BfCastFlags)(BfCastFlags_WantsConst));
- if (!argValue)
- return false;
- }
- if (!argValue)
- {
- mModule->Fail("Invalid expression type", argExpr);
- return false;
- }
- if (expandedParamsElementType != NULL)
- {
- expandedParamsConstValues.push_back(argValue.mValue);
- extendedParamIdx++;
- }
- else
- {
- bool requiresConst = false;
- if ((mModule->mCurMethodInstance == NULL) || (mModule->mCurMethodInstance->mMethodDef->mMethodType != BfMethodType_Mixin))
- requiresConst = true;
- if ((requiresConst) && (!mModule->mBfIRBuilder->IsConstValue(argValue.mValue)) && (!argValue.mType->IsValuelessType()))
- {
- mModule->Fail("Expression does not evaluate to a constant value", argExpr);
- }
- if (!argValue.mType->IsVar())
- {
- if ((!requiresConst) || (argValue.mValue.IsConst()) || (argValue.mType->IsValuelessType()))
- llvmArgs.push_back(argValue.mValue);
- else
- llvmArgs.push_back(mModule->GetDefaultValue(argValue.mType));
- }
- paramIdx++;
- }
- argIdx++;
- }
- if (expandedParamsElementType != NULL)
- {
- auto arrayType = mModule->mBfIRBuilder->GetSizedArrayType(mModule->mBfIRBuilder->MapType(expandedParamsElementType), (int)expandedParamsConstValues.size());
- auto constArray = mModule->mBfIRBuilder->CreateConstAgg(arrayType, expandedParamsConstValues);
- llvmArgs.push_back(constArray);
- }
- return true;
- }
|