BfConstResolver.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  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. mAllowGenericConstValue = false;
  29. }
  30. BfTypedValue BfConstResolver::Resolve(BfExpression* expr, BfType* wantType, BfConstResolveFlags flags)
  31. {
  32. bool explicitCast = (flags & BfConstResolveFlag_ExplicitCast) != 0;
  33. bool noCast = (flags & BfConstResolveFlag_NoCast) != 0;
  34. bool allowSoftFail = (flags & BfConstResolveFlag_AllowSoftFail) != 0;
  35. bool wantIgnoreWrites = mModule->mBfIRBuilder->mIgnoreWrites;
  36. /*if (BfNodeDynCastExact<BfTypeOfExpression>(expr) != NULL)
  37. {
  38. // Some specific expressions should be allowed to do writes like creating global variables
  39. }
  40. else*/
  41. {
  42. wantIgnoreWrites = true;
  43. }
  44. SetAndRestoreValue<bool> ignoreWrites(mModule->mBfIRBuilder->mIgnoreWrites, wantIgnoreWrites);
  45. auto prevInsertBlock = mModule->mBfIRBuilder->GetInsertBlock();
  46. mNoBind = true;
  47. if (wantType != NULL)
  48. mExpectingType = wantType;
  49. VisitChildNoRef(expr);
  50. mResult = GetResult();
  51. if (mResult)
  52. mResult = mModule->LoadValue(mResult);
  53. if ((mResult) && (wantType != NULL))
  54. {
  55. auto typeInst = mResult.mType->ToTypeInstance();
  56. if ((typeInst != NULL) && (typeInst->mTypeDef == mModule->mCompiler->mStringTypeDef))
  57. {
  58. BfType* toType = wantType;
  59. if (toType == NULL)
  60. toType = mResult.mType;
  61. if ((mResult.mValue.IsConst()) &&
  62. (((toType->IsPointer()) && (toType->GetUnderlyingType() == mModule->GetPrimitiveType(BfTypeCode_Char8))) ||
  63. (toType == mResult.mType)))
  64. {
  65. auto constant = mModule->mBfIRBuilder->GetConstant(mResult.mValue);
  66. if (constant->mTypeCode == BfTypeCode_NullPtr)
  67. {
  68. return mModule->GetDefaultTypedValue(toType);
  69. }
  70. else
  71. {
  72. int stringId = mModule->GetStringPoolIdx(mResult.mValue);
  73. BF_ASSERT(stringId >= 0);
  74. return BfTypedValue(mModule->GetConstValue(stringId), toType);
  75. }
  76. }
  77. }
  78. if (noCast)
  79. {
  80. //
  81. }
  82. else if (allowSoftFail)
  83. {
  84. SetAndRestoreValue<bool> prevIgnoreFail(mModule->mIgnoreErrors, true);
  85. auto convValue = mModule->Cast(expr, mResult, wantType, explicitCast ? BfCastFlags_Explicit : BfCastFlags_None);
  86. if (convValue)
  87. mResult = convValue;
  88. }
  89. else
  90. {
  91. mResult = mModule->Cast(expr, mResult, wantType, (BfCastFlags)(BfCastFlags_NoConversionOperator | (explicitCast ? BfCastFlags_Explicit : BfCastFlags_None)));
  92. }
  93. }
  94. if (mResult.mKind == BfTypedValueKind_GenericConstValue)
  95. {
  96. if (mAllowGenericConstValue)
  97. return mResult;
  98. auto genericParamDef = mModule->GetGenericParamInstance((BfGenericParamType*)mResult.mType);
  99. if ((genericParamDef->mGenericParamFlags & BfGenericParamFlag_Const) != 0)
  100. {
  101. auto genericTypeConstraint = genericParamDef->mTypeConstraint;
  102. if (genericTypeConstraint != NULL)
  103. {
  104. auto primType = genericTypeConstraint->ToPrimitiveType();
  105. if (primType != NULL)
  106. {
  107. BfTypedValue result;
  108. result.mKind = BfTypedValueKind_Value;
  109. result.mType = genericTypeConstraint;
  110. result.mValue = mModule->mBfIRBuilder->GetUndefConstValue(primType->mTypeDef->mTypeCode);
  111. return result;
  112. }
  113. }
  114. else
  115. {
  116. BF_FATAL("Error");
  117. }
  118. }
  119. }
  120. if (mResult)
  121. {
  122. bool isConst = mResult.mValue.IsConst();
  123. if (isConst)
  124. {
  125. auto constant = mModule->mBfIRBuilder->GetConstant(mResult.mValue);
  126. if (constant->mConstType == BfConstType_GlobalVar)
  127. isConst = false;
  128. }
  129. if ((!isConst) && ((mBfEvalExprFlags & BfEvalExprFlags_AllowNonConst) == 0))
  130. {
  131. mModule->Fail("Expression does not evaluate to a constant value", expr);
  132. if (wantType != NULL)
  133. mResult = mModule->GetDefaultTypedValue(wantType);
  134. else
  135. mResult = BfTypedValue();
  136. }
  137. }
  138. else
  139. {
  140. if (wantType != NULL)
  141. mResult = mModule->GetDefaultTypedValue(wantType);
  142. }
  143. if (prevInsertBlock)
  144. mModule->mBfIRBuilder->SetInsertPoint(prevInsertBlock);
  145. /*ignoreWrites.Restore();
  146. if ((!mModule->mBfIRBuilder->mIgnoreWrites) && (prevInsertBlock))
  147. {
  148. BF_ASSERT(!prevInsertBlock.IsFake());
  149. mModule->mBfIRBuilder->SetInsertPoint(prevInsertBlock);
  150. }*/
  151. mModule->FixIntUnknown(mResult);
  152. return mResult;
  153. }
  154. bool BfConstResolver::PrepareMethodArguments(BfAstNode* targetSrc, BfMethodMatcher* methodMatcher, Array<BfIRValue>& llvmArgs)
  155. {
  156. int argIdx = 0;
  157. int paramIdx = 0;
  158. int extendedParamIdx = 0;
  159. llvm::SmallVector<BfIRValue, 4> expandedParamsConstValues;
  160. BfType* expandedParamsElementType = NULL;
  161. // We don't do GetMethodInstance in mModule, because our module may not have init finished yet
  162. //auto targetModule = methodMatcher->mBestMethodTypeInstance->mModule;
  163. auto targetModule = mModule->mContext->mUnreifiedModule;
  164. auto moduleMethodInstance = targetModule->GetMethodInstance(methodMatcher->mBestMethodTypeInstance, methodMatcher->mBestMethodDef, methodMatcher->mBestMethodGenericArguments);
  165. auto methodInstance = moduleMethodInstance.mMethodInstance;
  166. if (methodInstance->mReturnType == NULL)
  167. {
  168. mModule->AssertErrorState();
  169. return false;
  170. }
  171. auto methodDef = methodMatcher->mBestMethodDef;
  172. auto& arguments = methodMatcher->mArguments;
  173. mModule->AddDependency(methodInstance->mReturnType, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_LocalUsage);
  174. for (int paramIdx = 0; paramIdx < methodInstance->GetParamCount(); paramIdx++)
  175. {
  176. auto paramType = methodInstance->GetParamType(paramIdx);
  177. mModule->AddDependency(paramType, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_LocalUsage);
  178. }
  179. while (true)
  180. {
  181. if (paramIdx >= (int)methodInstance->GetParamCount())
  182. {
  183. if (argIdx < (int)arguments.size())
  184. {
  185. BfAstNode* errorRef = arguments[methodInstance->GetParamCount()].mExpression;
  186. if (errorRef->GetSourceData() == NULL)
  187. errorRef = targetSrc;
  188. mModule->Fail(StrFormat("Too many arguments. Expected %d fewer.", (int)arguments.size() - methodInstance->GetParamCount()), errorRef);
  189. if (methodInstance->mMethodDef->mMethodDeclaration != NULL)
  190. mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See method declaration"), methodInstance->mMethodDef->mMethodDeclaration);
  191. return false;
  192. }
  193. break;
  194. }
  195. BfType* wantType = NULL;
  196. if (expandedParamsElementType != NULL)
  197. {
  198. wantType = expandedParamsElementType;
  199. }
  200. else
  201. {
  202. wantType = methodInstance->GetParamType(paramIdx);
  203. if (methodInstance->GetParamKind(paramIdx) == BfParamKind_Params)
  204. {
  205. //TODO: Check to see if it's a direct array pass
  206. bool isDirectPass = false;
  207. if (argIdx < (int)arguments.size())
  208. {
  209. if (!arguments[argIdx].mTypedValue.mValue)
  210. return false;
  211. if (mModule->CanImplicitlyCast(arguments[argIdx].mTypedValue, wantType))
  212. isDirectPass = true;
  213. }
  214. if (!isDirectPass)
  215. {
  216. BfArrayType* arrayType = (BfArrayType*)wantType;
  217. if (arrayType->IsIncomplete())
  218. mModule->PopulateType(arrayType, BfPopulateType_DataAndMethods);
  219. expandedParamsElementType = arrayType->mTypeGenericArguments[0];
  220. continue;
  221. }
  222. }
  223. }
  224. BfAstNode* argExpr = NULL;
  225. if (argIdx < (int)arguments.size())
  226. {
  227. argExpr = arguments[argIdx].mExpression;
  228. }
  229. else
  230. {
  231. if (expandedParamsElementType != NULL)
  232. break;
  233. if ((argIdx >= (int)methodInstance->mDefaultValues.size()) || (!methodInstance->mDefaultValues[argIdx]))
  234. {
  235. BfAstNode* refNode = targetSrc;
  236. if (arguments.size() > 0)
  237. refNode = arguments.back().mExpression;
  238. BfAstNode* prevNode = NULL;
  239. #ifdef BF_AST_HAS_PARENT_MEMBER
  240. if (auto attributeDirective = BfNodeDynCast<BfAttributeDirective>(targetSrc->mParent))
  241. {
  242. BF_ASSERT(mModule->mParentNodeEntry->mNode == attributeDirective);
  243. }
  244. #endif
  245. if (mModule->mParentNodeEntry != NULL)
  246. {
  247. if (auto attributeDirective = BfNodeDynCast<BfAttributeDirective>(mModule->mParentNodeEntry->mNode))
  248. {
  249. if (attributeDirective->mCommas.size() > 0)
  250. prevNode = attributeDirective->mCommas.back();
  251. else
  252. prevNode = attributeDirective->mCtorOpenParen;
  253. if (attributeDirective->mCtorCloseParen != NULL)
  254. refNode = attributeDirective->mCtorCloseParen;
  255. }
  256. }
  257. auto autoComplete = GetAutoComplete();
  258. if (autoComplete != NULL)
  259. {
  260. if (prevNode != NULL)
  261. {
  262. autoComplete->CheckEmptyStart(prevNode, wantType);
  263. }
  264. }
  265. mModule->Fail(StrFormat("Not enough parameters specified. Expected %d fewer.", methodInstance->GetParamCount() - (int)arguments.size()), refNode);
  266. return false;
  267. }
  268. auto foreignDefaultVal = methodInstance->mDefaultValues[argIdx];
  269. auto foreignConst = methodInstance->GetOwner()->mConstHolder->GetConstant(methodInstance->mDefaultValues[argIdx]);
  270. auto constVal = mModule->ConstantToCurrent(foreignConst, methodInstance->GetOwner()->mConstHolder, wantType);
  271. llvmArgs.push_back(constVal);
  272. argIdx++;
  273. paramIdx++;
  274. continue;
  275. }
  276. auto argValue = arguments[argIdx].mTypedValue;
  277. auto& arg = arguments[argIdx];
  278. if ((arg.mArgFlags & BfArgFlag_DeferredEval) != 0)
  279. {
  280. mExpectingType = arg.mExpectedType;
  281. if (auto expr = BfNodeDynCast<BfExpression>(argExpr))
  282. argValue = Resolve(expr, mExpectingType);
  283. arg.mArgFlags = BfArgFlag_None;
  284. }
  285. if (!argValue)
  286. return BfTypedValue();
  287. if (argExpr != NULL)
  288. {
  289. argValue = mModule->Cast(argExpr, argValue, wantType);
  290. if (!argValue)
  291. return false;
  292. }
  293. if (!argValue)
  294. {
  295. mModule->Fail("Invalid expression type", argExpr);
  296. return false;
  297. }
  298. if (expandedParamsElementType != NULL)
  299. {
  300. expandedParamsConstValues.push_back(argValue.mValue);
  301. extendedParamIdx++;
  302. }
  303. else
  304. {
  305. llvmArgs.push_back(argValue.mValue);
  306. paramIdx++;
  307. }
  308. argIdx++;
  309. }
  310. if (expandedParamsElementType != NULL)
  311. {
  312. auto arrayType = mModule->mBfIRBuilder->GetSizedArrayType(mModule->mBfIRBuilder->MapType(expandedParamsElementType), (int)expandedParamsConstValues.size());
  313. auto constArray = mModule->mBfIRBuilder->CreateConstArray(arrayType, expandedParamsConstValues);
  314. llvmArgs.push_back(constArray);
  315. }
  316. return true;
  317. }