BfConstResolver.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443
  1. #pragma warning(push)
  2. #pragma warning(disable:4800)
  3. #pragma warning(disable:4244)
  4. #pragma warning(disable:4141)
  5. #pragma warning(disable:4624)
  6. #pragma warning(disable:4146)
  7. #pragma warning(disable:4267)
  8. #pragma warning(disable:4291)
  9. #include "BfCompiler.h"
  10. #include "BfConstResolver.h"
  11. #include "BfAutoComplete.h"
  12. #include "BfResolvePass.h"
  13. #include "llvm/IR/GlobalVariable.h"
  14. #include "BfExprEvaluator.h"
  15. #pragma warning(pop)
  16. USING_NS_BF;
  17. using namespace llvm;
  18. bool BfConstResolver::CheckAllowValue(const BfTypedValue& typedValue, BfAstNode* refNode)
  19. {
  20. if (typedValue.mValue.IsConst())
  21. return true;
  22. mModule->Fail("Expression does not evaluate to a constant value", refNode);
  23. return false;
  24. }
  25. BfConstResolver::BfConstResolver(BfModule* bfModule) : BfExprEvaluator(bfModule)
  26. {
  27. mIsInvalidConstExpr = false;
  28. }
  29. BfTypedValue BfConstResolver::Resolve(BfExpression* expr, BfType* wantType, BfConstResolveFlags flags)
  30. {
  31. mBfEvalExprFlags = (BfEvalExprFlags)(mBfEvalExprFlags | BfEvalExprFlags_Comptime);
  32. // Handle the 'int[?] val = .(1, 2, 3)' case
  33. if ((flags & BfConstResolveFlag_ArrayInitSize) != 0)
  34. {
  35. if (auto uninitExpr = BfNodeDynCast<BfUninitializedExpression>(expr))
  36. {
  37. BfAstNode* initializer = NULL;
  38. int arraySize = -1;
  39. if (mModule->mContext->mCurTypeState != NULL)
  40. {
  41. if (mModule->mContext->mCurTypeState->mCurFieldDef != NULL)
  42. initializer = mModule->mContext->mCurTypeState->mCurFieldDef->GetInitializer();
  43. if (mModule->mContext->mCurTypeState->mCurVarInitializer != NULL)
  44. initializer = mModule->mContext->mCurTypeState->mCurVarInitializer;
  45. if (mModule->mContext->mCurTypeState->mArrayInitializerSize != -1)
  46. arraySize = mModule->mContext->mCurTypeState->mArrayInitializerSize;
  47. }
  48. if (initializer != NULL)
  49. {
  50. if (auto invocationExpr = BfNodeDynCast<BfInvocationExpression>(initializer))
  51. {
  52. if (auto memberRefExpr = BfNodeDynCast<BfMemberReferenceExpression>(invocationExpr->mTarget))
  53. {
  54. // Dot-initialized
  55. if (memberRefExpr->mTarget == NULL)
  56. arraySize = (int)invocationExpr->mArguments.size();
  57. }
  58. else if (auto indexerExpr = BfNodeDynCast<BfIndexerExpression>(invocationExpr->mTarget))
  59. {
  60. if (indexerExpr->mArguments.size() == 0)
  61. {
  62. // Inferred-type sized array initializer
  63. arraySize = (int)invocationExpr->mArguments.size();
  64. }
  65. }
  66. }
  67. }
  68. if (arraySize != -1)
  69. {
  70. mResult = BfTypedValue(mModule->GetConstValue(arraySize), mModule->GetPrimitiveType(BfTypeCode_IntPtr));
  71. return mResult;
  72. }
  73. else
  74. {
  75. mResult = BfTypedValue(mModule->mBfIRBuilder->GetUndefConstValue(mModule->mBfIRBuilder->GetPrimitiveType(BfTypeCode_IntPtr)), mModule->GetPrimitiveType(BfTypeCode_IntPtr));
  76. return mResult;
  77. }
  78. }
  79. }
  80. bool explicitCast = (flags & BfConstResolveFlag_ExplicitCast) != 0;
  81. bool noCast = (flags & BfConstResolveFlag_NoCast) != 0;
  82. bool allowSoftFail = (flags & BfConstResolveFlag_AllowSoftFail) != 0;
  83. bool wantIgnoreWrites = mModule->mBfIRBuilder->mIgnoreWrites;
  84. /*if (BfNodeDynCastExact<BfTypeOfExpression>(expr) != NULL)
  85. {
  86. // Some specific expressions should be allowed to do writes like creating global variables
  87. }
  88. else*/
  89. {
  90. wantIgnoreWrites = true;
  91. }
  92. SetAndRestoreValue<bool> prevIgnoreWrites(mModule->mBfIRBuilder->mIgnoreWrites, wantIgnoreWrites);
  93. auto prevInsertBlock = mModule->mBfIRBuilder->GetInsertBlock();
  94. mNoBind = true;
  95. if (wantType != NULL)
  96. mExpectingType = wantType;
  97. VisitChildNoRef(expr);
  98. mResult = GetResult();
  99. auto compilerVal = mModule->GetCompilerFieldValue(mResult);
  100. if (compilerVal)
  101. mResult = compilerVal;
  102. if ((mResult) && (wantType != NULL))
  103. {
  104. auto typeInst = mResult.mType->ToTypeInstance();
  105. if ((typeInst != NULL) && (typeInst->IsInstanceOf(mModule->mCompiler->mStringTypeDef)))
  106. {
  107. BfType* toType = wantType;
  108. if (toType == NULL)
  109. toType = mResult.mType;
  110. if ((mResult.mValue.IsConst()) &&
  111. (((toType->IsPointer()) && (toType->GetUnderlyingType() == mModule->GetPrimitiveType(BfTypeCode_Char8))) ||
  112. (toType == mResult.mType)))
  113. {
  114. auto constant = mModule->mBfIRBuilder->GetConstant(mResult.mValue);
  115. if (constant->mTypeCode == BfTypeCode_NullPtr)
  116. {
  117. return mModule->GetDefaultTypedValue(toType);
  118. }
  119. else
  120. {
  121. int stringId = mModule->GetStringPoolIdx(mResult.mValue);
  122. if (stringId != -1)
  123. {
  124. if ((flags & BfConstResolveFlag_ActualizeValues) != 0)
  125. {
  126. prevIgnoreWrites.Restore();
  127. mModule->mBfIRBuilder->PopulateType(mResult.mType);
  128. return BfTypedValue(mModule->GetStringObjectValue(stringId, false, true), mResult.mType);
  129. }
  130. return BfTypedValue(mModule->mBfIRBuilder->CreateConst(BfTypeCode_StringId, stringId), toType);
  131. }
  132. }
  133. }
  134. }
  135. if (noCast)
  136. {
  137. //
  138. }
  139. else if (allowSoftFail)
  140. {
  141. SetAndRestoreValue<bool> prevIgnoreFail(mModule->mIgnoreErrors, true);
  142. auto convValue = mModule->Cast(expr, mResult, wantType, explicitCast ? BfCastFlags_Explicit : BfCastFlags_None);
  143. if (convValue)
  144. mResult = convValue;
  145. }
  146. else
  147. {
  148. mResult = mModule->Cast(expr, mResult, wantType, (BfCastFlags)(BfCastFlags_NoConversionOperator | (explicitCast ? BfCastFlags_Explicit : BfCastFlags_None)));
  149. }
  150. }
  151. if (mResult.mKind == BfTypedValueKind_GenericConstValue)
  152. {
  153. if ((mBfEvalExprFlags & BfEvalExprFlags_AllowGenericConstValue) != 0)
  154. return mResult;
  155. }
  156. if (mResult)
  157. {
  158. bool isConst = mResult.mValue.IsConst();
  159. if (isConst)
  160. {
  161. auto constant = mModule->mBfIRBuilder->GetConstant(mResult.mValue);
  162. if ((constant->mConstType == BfConstType_GlobalVar) && ((flags & BfConstResolveFlag_AllowGlobalVariable) == 0))
  163. {
  164. int stringId = mModule->GetStringPoolIdx(mResult.mValue, mModule->mBfIRBuilder);
  165. if (stringId != -1)
  166. {
  167. mResult.mValue = mModule->mBfIRBuilder->CreateConst(BfTypeCode_StringId, stringId);
  168. }
  169. else
  170. isConst = false;
  171. }
  172. }
  173. if ((!isConst) && ((mBfEvalExprFlags & BfEvalExprFlags_AllowNonConst) == 0))
  174. {
  175. mModule->Fail("Expression does not evaluate to a constant value", expr);
  176. if (wantType != NULL)
  177. mResult = mModule->GetDefaultTypedValue(wantType);
  178. else
  179. mResult = BfTypedValue();
  180. }
  181. }
  182. else
  183. {
  184. if (wantType != NULL)
  185. mResult = mModule->GetDefaultTypedValue(wantType);
  186. }
  187. if (prevInsertBlock)
  188. mModule->mBfIRBuilder->SetInsertPoint(prevInsertBlock);
  189. /*ignoreWrites.Restore();
  190. if ((!mModule->mBfIRBuilder->mIgnoreWrites) && (prevInsertBlock))
  191. {
  192. BF_ASSERT(!prevInsertBlock.IsFake());
  193. mModule->mBfIRBuilder->SetInsertPoint(prevInsertBlock);
  194. }*/
  195. mModule->FixIntUnknown(mResult);
  196. if ((flags & BfConstResolveFlag_NoActualizeValues) == 0)
  197. {
  198. prevIgnoreWrites.Restore();
  199. mModule->FixValueActualization(mResult, !prevIgnoreWrites.mPrevVal || ((flags & BfConstResolveFlag_ActualizeValues) != 0));
  200. }
  201. return mResult;
  202. }
  203. bool BfConstResolver::PrepareMethodArguments(BfAstNode* targetSrc, BfMethodMatcher* methodMatcher, Array<BfIRValue>& llvmArgs)
  204. {
  205. int argIdx = 0;
  206. int paramIdx = 0;
  207. int extendedParamIdx = 0;
  208. SetAndRestoreValue<bool> ignoreWrites(mModule->mBfIRBuilder->mIgnoreWrites, true);
  209. llvm::SmallVector<BfIRValue, 4> expandedParamsConstValues;
  210. BfType* expandedParamsElementType = NULL;
  211. // We don't do GetMethodInstance in mModule, because our module may not have init finished yet
  212. //auto targetModule = methodMatcher->mBestMethodTypeInstance->mModule;
  213. auto targetModule = mModule->mContext->mUnreifiedModule;
  214. auto moduleMethodInstance = targetModule->GetMethodInstance(methodMatcher->mBestMethodTypeInstance, methodMatcher->mBestMethodDef, methodMatcher->mBestMethodGenericArguments);
  215. auto methodInstance = moduleMethodInstance.mMethodInstance;
  216. if (methodInstance->mReturnType == NULL)
  217. {
  218. mModule->AssertErrorState();
  219. return false;
  220. }
  221. auto methodDef = methodMatcher->mBestMethodDef;
  222. auto& arguments = methodMatcher->mArguments;
  223. mModule->AddDependency(methodInstance->mReturnType, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_LocalUsage);
  224. for (int paramIdx = 0; paramIdx < methodInstance->GetParamCount(); paramIdx++)
  225. {
  226. auto paramType = methodInstance->GetParamType(paramIdx);
  227. mModule->AddDependency(paramType, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_LocalUsage);
  228. }
  229. while (true)
  230. {
  231. if (paramIdx >= (int)methodInstance->GetParamCount())
  232. {
  233. if (argIdx < (int)arguments.size())
  234. {
  235. BfAstNode* errorRef = arguments[methodInstance->GetParamCount()].mExpression;
  236. if (errorRef->GetSourceData() == NULL)
  237. errorRef = targetSrc;
  238. mModule->Fail(StrFormat("Too many arguments. Expected %d fewer.", (int)arguments.size() - methodInstance->GetParamCount()), errorRef);
  239. if (methodInstance->mMethodDef->mMethodDeclaration != NULL)
  240. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See method declaration"), methodInstance->mMethodDef->mMethodDeclaration);
  241. return false;
  242. }
  243. break;
  244. }
  245. BfType* wantType = NULL;
  246. if (expandedParamsElementType != NULL)
  247. {
  248. wantType = expandedParamsElementType;
  249. }
  250. else
  251. {
  252. wantType = methodInstance->GetParamType(paramIdx);
  253. if (methodInstance->GetParamKind(paramIdx) == BfParamKind_Params)
  254. {
  255. //TODO: Check to see if it's a direct array pass
  256. bool isDirectPass = false;
  257. if (argIdx < (int)arguments.size())
  258. {
  259. if (!arguments[argIdx].mTypedValue.mValue)
  260. return false;
  261. if (mModule->CanCast(arguments[argIdx].mTypedValue, wantType))
  262. isDirectPass = true;
  263. }
  264. if (!isDirectPass)
  265. {
  266. BfArrayType* arrayType = (BfArrayType*)wantType;
  267. if (arrayType->IsIncomplete())
  268. mModule->PopulateType(arrayType, BfPopulateType_DataAndMethods);
  269. expandedParamsElementType = arrayType->mGenericTypeInfo->mTypeGenericArguments[0];
  270. continue;
  271. }
  272. }
  273. }
  274. BfTypedValue argValue;
  275. BfAstNode* argExpr = NULL;
  276. if (argIdx < (int)arguments.size())
  277. {
  278. argExpr = arguments[argIdx].mExpression;
  279. }
  280. else
  281. {
  282. if (expandedParamsElementType != NULL)
  283. break;
  284. if ((argIdx >= (int)methodInstance->mDefaultValues.size()) || (!methodInstance->mDefaultValues[argIdx]))
  285. {
  286. BfAstNode* refNode = targetSrc;
  287. if (arguments.size() > 0)
  288. refNode = arguments.back().mExpression;
  289. BfAstNode* prevNode = NULL;
  290. #ifdef BF_AST_HAS_PARENT_MEMBER
  291. if (auto attributeDirective = BfNodeDynCast<BfAttributeDirective>(targetSrc->mParent))
  292. {
  293. BF_ASSERT(mModule->mParentNodeEntry->mNode == attributeDirective);
  294. }
  295. #endif
  296. if (mModule->mParentNodeEntry != NULL)
  297. {
  298. if (auto attributeDirective = BfNodeDynCast<BfAttributeDirective>(mModule->mParentNodeEntry->mNode))
  299. {
  300. if (attributeDirective->mCommas.size() > 0)
  301. prevNode = attributeDirective->mCommas.back();
  302. else
  303. prevNode = attributeDirective->mCtorOpenParen;
  304. if (attributeDirective->mCtorCloseParen != NULL)
  305. refNode = attributeDirective->mCtorCloseParen;
  306. }
  307. }
  308. auto autoComplete = GetAutoComplete();
  309. if (autoComplete != NULL)
  310. {
  311. if (prevNode != NULL)
  312. {
  313. autoComplete->CheckEmptyStart(prevNode, wantType);
  314. }
  315. }
  316. if (mModule->PreFail())
  317. mModule->Fail(StrFormat("Not enough parameters specified. Expected %d more.", methodInstance->GetParamCount() - (int)arguments.size()), refNode);
  318. return false;
  319. }
  320. auto foreignDefaultVal = methodInstance->mDefaultValues[argIdx];
  321. auto foreignConst = methodInstance->GetOwner()->mConstHolder->GetConstant(foreignDefaultVal.mValue);
  322. argValue = mModule->GetTypedValueFromConstant(foreignConst, methodInstance->GetOwner()->mConstHolder, foreignDefaultVal.mType);
  323. }
  324. if ((!argValue) && (argIdx < arguments.size()))
  325. {
  326. argValue = arguments[argIdx].mTypedValue;
  327. auto& arg = arguments[argIdx];
  328. if ((arg.mArgFlags & BfArgFlag_DeferredEval) != 0)
  329. {
  330. mExpectingType = arg.mExpectedType;
  331. if (mExpectingType == NULL)
  332. mExpectingType = wantType;
  333. if (auto expr = BfNodeDynCast<BfExpression>(argExpr))
  334. argValue = Resolve(expr, mExpectingType);
  335. arg.mArgFlags = BfArgFlag_None;
  336. }
  337. }
  338. if (!argValue)
  339. return BfTypedValue();
  340. if (argExpr != NULL)
  341. {
  342. argValue = mModule->Cast(argExpr, argValue, wantType);
  343. if (!argValue)
  344. return false;
  345. }
  346. if (!argValue)
  347. {
  348. mModule->Fail("Invalid expression type", argExpr);
  349. return false;
  350. }
  351. if (expandedParamsElementType != NULL)
  352. {
  353. expandedParamsConstValues.push_back(argValue.mValue);
  354. extendedParamIdx++;
  355. }
  356. else
  357. {
  358. bool requiresConst = false;
  359. if ((mModule->mCurMethodInstance == NULL) || (mModule->mCurMethodInstance->mMethodDef->mMethodType != BfMethodType_Mixin))
  360. requiresConst = true;
  361. if ((requiresConst) && (argValue.mValue.IsFake()) && (!argValue.mType->IsValuelessType()))
  362. {
  363. mModule->Fail("Expression does not evaluate to a constant value", argExpr);
  364. }
  365. if (!argValue.mType->IsVar())
  366. {
  367. if ((!requiresConst) || (argValue.mValue.IsConst()) || (argValue.mType->IsValuelessType()))
  368. llvmArgs.push_back(argValue.mValue);
  369. else
  370. llvmArgs.push_back(mModule->GetDefaultValue(argValue.mType));
  371. }
  372. paramIdx++;
  373. }
  374. argIdx++;
  375. }
  376. if (expandedParamsElementType != NULL)
  377. {
  378. auto arrayType = mModule->mBfIRBuilder->GetSizedArrayType(mModule->mBfIRBuilder->MapType(expandedParamsElementType), (int)expandedParamsConstValues.size());
  379. auto constArray = mModule->mBfIRBuilder->CreateConstAgg(arrayType, expandedParamsConstValues);
  380. llvmArgs.push_back(constArray);
  381. }
  382. return true;
  383. }