BfConstResolver.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453
  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. BfCastFlags castFlags = (BfCastFlags)(BfCastFlags_WantsConst | (explicitCast ? BfCastFlags_Explicit : BfCastFlags_None));
  149. if ((flags & BfConstResolveFlag_NoConversionOperator) != 0)
  150. castFlags = (BfCastFlags)(castFlags | BfCastFlags_NoConversionOperator);
  151. mResult = mModule->Cast(expr, mResult, wantType, castFlags);
  152. }
  153. }
  154. if (mResult.mKind == BfTypedValueKind_GenericConstValue)
  155. {
  156. if ((mBfEvalExprFlags & BfEvalExprFlags_AllowGenericConstValue) != 0)
  157. return mResult;
  158. }
  159. if (mResult)
  160. {
  161. bool isConst = mResult.mValue.IsConst();
  162. if (isConst)
  163. {
  164. auto constant = mModule->mBfIRBuilder->GetConstant(mResult.mValue);
  165. if ((constant->mTypeCode != BfTypeCode_StringId) && (mModule->HasStringId(mResult.mValue, mModule->mBfIRBuilder)))
  166. {
  167. mModule->Fail("Invalid usage of string constant", expr);
  168. mResult = BfTypedValue();
  169. }
  170. else if ((constant->mConstType == BfConstType_GlobalVar) && ((flags & BfConstResolveFlag_AllowGlobalVariable) == 0))
  171. {
  172. int stringId = mModule->GetStringPoolIdx(mResult.mValue, mModule->mBfIRBuilder);
  173. if (stringId != -1)
  174. {
  175. mResult.mValue = mModule->mBfIRBuilder->CreateConst(BfTypeCode_StringId, stringId);
  176. }
  177. else
  178. isConst = false;
  179. }
  180. }
  181. if ((!isConst) && ((mBfEvalExprFlags & BfEvalExprFlags_AllowNonConst) == 0))
  182. {
  183. mModule->Fail("Expression does not evaluate to a constant value", expr);
  184. if (wantType != NULL)
  185. mResult = mModule->GetDefaultTypedValue(wantType);
  186. else
  187. mResult = BfTypedValue();
  188. }
  189. }
  190. else
  191. {
  192. if (wantType != NULL)
  193. mResult = mModule->GetDefaultTypedValue(wantType);
  194. }
  195. if (prevInsertBlock)
  196. mModule->mBfIRBuilder->SetInsertPoint(prevInsertBlock);
  197. /*ignoreWrites.Restore();
  198. if ((!mModule->mBfIRBuilder->mIgnoreWrites) && (prevInsertBlock))
  199. {
  200. BF_ASSERT(!prevInsertBlock.IsFake());
  201. mModule->mBfIRBuilder->SetInsertPoint(prevInsertBlock);
  202. }*/
  203. mModule->FixIntUnknown(mResult);
  204. if ((flags & BfConstResolveFlag_NoActualizeValues) == 0)
  205. {
  206. if (mModule->mBfIRBuilder->mHasStarted)
  207. prevIgnoreWrites.Restore();
  208. mModule->FixValueActualization(mResult, !prevIgnoreWrites.mPrevVal || ((flags & BfConstResolveFlag_ActualizeValues) != 0));
  209. }
  210. return mResult;
  211. }
  212. bool BfConstResolver::PrepareMethodArguments(BfAstNode* targetSrc, BfMethodMatcher* methodMatcher, Array<BfIRValue>& llvmArgs)
  213. {
  214. int argIdx = 0;
  215. int paramIdx = 0;
  216. int extendedParamIdx = 0;
  217. SetAndRestoreValue<bool> ignoreWrites(mModule->mBfIRBuilder->mIgnoreWrites, true);
  218. llvm::SmallVector<BfIRValue, 4> expandedParamsConstValues;
  219. BfType* expandedParamsElementType = NULL;
  220. // We don't do GetMethodInstance in mModule, because our module may not have init finished yet
  221. //auto targetModule = methodMatcher->mBestMethodTypeInstance->mModule;
  222. auto targetModule = mModule->mContext->mUnreifiedModule;
  223. auto moduleMethodInstance = targetModule->GetMethodInstance(methodMatcher->mBestMethodTypeInstance, methodMatcher->mBestMethodDef, methodMatcher->mBestMethodGenericArguments);
  224. auto methodInstance = moduleMethodInstance.mMethodInstance;
  225. if (methodInstance->mReturnType == NULL)
  226. {
  227. mModule->AssertErrorState();
  228. return false;
  229. }
  230. auto methodDef = methodMatcher->mBestMethodDef;
  231. auto& arguments = methodMatcher->mArguments;
  232. mModule->AddDependency(methodInstance->mReturnType, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_LocalUsage);
  233. for (int paramIdx = 0; paramIdx < methodInstance->GetParamCount(); paramIdx++)
  234. {
  235. auto paramType = methodInstance->GetParamType(paramIdx);
  236. mModule->AddDependency(paramType, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_LocalUsage);
  237. }
  238. while (true)
  239. {
  240. if (paramIdx >= (int)methodInstance->GetParamCount())
  241. {
  242. if (argIdx < (int)arguments.size())
  243. {
  244. BfAstNode* errorRef = arguments[methodInstance->GetParamCount()].mExpression;
  245. if (errorRef->GetSourceData() == NULL)
  246. errorRef = targetSrc;
  247. mModule->Fail(StrFormat("Too many arguments. Expected %d fewer.", (int)arguments.size() - methodInstance->GetParamCount()), errorRef);
  248. if (methodInstance->mMethodDef->mMethodDeclaration != NULL)
  249. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See method declaration"), methodInstance->mMethodDef->mMethodDeclaration);
  250. return false;
  251. }
  252. break;
  253. }
  254. BfType* wantType = NULL;
  255. if (expandedParamsElementType != NULL)
  256. {
  257. wantType = expandedParamsElementType;
  258. }
  259. else
  260. {
  261. wantType = methodInstance->GetParamType(paramIdx);
  262. if (methodInstance->GetParamKind(paramIdx) == BfParamKind_Params)
  263. {
  264. //TODO: Check to see if it's a direct array pass
  265. bool isDirectPass = false;
  266. if (argIdx < (int)arguments.size())
  267. {
  268. if (!arguments[argIdx].mTypedValue.mValue)
  269. return false;
  270. if (mModule->CanCast(arguments[argIdx].mTypedValue, wantType))
  271. isDirectPass = true;
  272. }
  273. if ((!isDirectPass) && (wantType->IsArray()))
  274. {
  275. BfArrayType* arrayType = (BfArrayType*)wantType;
  276. if (arrayType->IsIncomplete())
  277. mModule->PopulateType(arrayType, BfPopulateType_DataAndMethods);
  278. expandedParamsElementType = arrayType->mGenericTypeInfo->mTypeGenericArguments[0];
  279. continue;
  280. }
  281. }
  282. }
  283. BfTypedValue argValue;
  284. BfAstNode* argExpr = NULL;
  285. if (argIdx < (int)arguments.size())
  286. {
  287. argExpr = arguments[argIdx].mExpression;
  288. }
  289. else
  290. {
  291. if (expandedParamsElementType != NULL)
  292. break;
  293. if ((argIdx >= (int)methodInstance->mDefaultValues.size()) || (!methodInstance->mDefaultValues[argIdx]))
  294. {
  295. BfAstNode* refNode = targetSrc;
  296. if (arguments.size() > 0)
  297. refNode = arguments.back().mExpression;
  298. BfAstNode* prevNode = NULL;
  299. #ifdef BF_AST_HAS_PARENT_MEMBER
  300. if (auto attributeDirective = BfNodeDynCast<BfAttributeDirective>(targetSrc->mParent))
  301. {
  302. BF_ASSERT(mModule->mParentNodeEntry->mNode == attributeDirective);
  303. }
  304. #endif
  305. if (mModule->mParentNodeEntry != NULL)
  306. {
  307. if (auto attributeDirective = BfNodeDynCast<BfAttributeDirective>(mModule->mParentNodeEntry->mNode))
  308. {
  309. if (attributeDirective->mCommas.size() > 0)
  310. prevNode = attributeDirective->mCommas.back();
  311. else
  312. prevNode = attributeDirective->mCtorOpenParen;
  313. if (attributeDirective->mCtorCloseParen != NULL)
  314. refNode = attributeDirective->mCtorCloseParen;
  315. }
  316. }
  317. auto autoComplete = GetAutoComplete();
  318. if (autoComplete != NULL)
  319. {
  320. if (prevNode != NULL)
  321. {
  322. autoComplete->CheckEmptyStart(prevNode, wantType);
  323. }
  324. }
  325. if (mModule->PreFail())
  326. mModule->Fail(StrFormat("Not enough parameters specified. Expected %d more.", methodInstance->GetParamCount() - (int)arguments.size()), refNode);
  327. return false;
  328. }
  329. auto foreignDefaultVal = methodInstance->mDefaultValues[argIdx];
  330. auto foreignConst = methodInstance->GetOwner()->mConstHolder->GetConstant(foreignDefaultVal.mValue);
  331. argValue = mModule->GetTypedValueFromConstant(foreignConst, methodInstance->GetOwner()->mConstHolder, foreignDefaultVal.mType);
  332. }
  333. if ((!argValue) && (argIdx < arguments.size()))
  334. {
  335. argValue = arguments[argIdx].mTypedValue;
  336. auto& arg = arguments[argIdx];
  337. if ((arg.mArgFlags & BfArgFlag_DeferredEval) != 0)
  338. {
  339. mExpectingType = arg.mExpectedType;
  340. if (mExpectingType == NULL)
  341. mExpectingType = wantType;
  342. if (auto expr = BfNodeDynCast<BfExpression>(argExpr))
  343. argValue = Resolve(expr, mExpectingType);
  344. arg.mArgFlags = BfArgFlag_None;
  345. }
  346. }
  347. if (!argValue)
  348. return BfTypedValue();
  349. if (argExpr != NULL)
  350. {
  351. argValue = mModule->Cast(argExpr, argValue, wantType, (BfCastFlags)(BfCastFlags_WantsConst));
  352. if (!argValue)
  353. return false;
  354. }
  355. if (!argValue)
  356. {
  357. mModule->Fail("Invalid expression type", argExpr);
  358. return false;
  359. }
  360. if (expandedParamsElementType != NULL)
  361. {
  362. expandedParamsConstValues.push_back(argValue.mValue);
  363. extendedParamIdx++;
  364. }
  365. else
  366. {
  367. bool requiresConst = false;
  368. if ((mModule->mCurMethodInstance == NULL) || (mModule->mCurMethodInstance->mMethodDef->mMethodType != BfMethodType_Mixin))
  369. requiresConst = true;
  370. if ((requiresConst) && (!mModule->mBfIRBuilder->IsConstValue(argValue.mValue)) && (!argValue.mType->IsValuelessType()))
  371. {
  372. mModule->Fail("Expression does not evaluate to a constant value", argExpr);
  373. }
  374. if (!argValue.mType->IsVar())
  375. {
  376. if ((!requiresConst) || (argValue.mValue.IsConst()) || (argValue.mType->IsValuelessType()))
  377. llvmArgs.push_back(argValue.mValue);
  378. else
  379. llvmArgs.push_back(mModule->GetDefaultValue(argValue.mType));
  380. }
  381. paramIdx++;
  382. }
  383. argIdx++;
  384. }
  385. if (expandedParamsElementType != NULL)
  386. {
  387. auto arrayType = mModule->mBfIRBuilder->GetSizedArrayType(mModule->mBfIRBuilder->MapType(expandedParamsElementType), (int)expandedParamsConstValues.size());
  388. auto constArray = mModule->mBfIRBuilder->CreateConstAgg(arrayType, expandedParamsConstValues);
  389. llvmArgs.push_back(constArray);
  390. }
  391. return true;
  392. }