BfSystem.h 40 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702
  1. #pragma once
  2. #include "BeefySysLib/Common.h"
  3. #include "BeefySysLib/util/CritSect.h"
  4. #include "BeefySysLib/util/Hash.h"
  5. #include "BeefySysLib/util/HashSet.h"
  6. #include "BeefySysLib/util/Deque.h"
  7. #include "BeefySysLib/util/BumpAllocator.h"
  8. #include "BeefySysLib/util/MultiHashSet.h"
  9. #include "../Beef/BfCommon.h"
  10. #include "BfAst.h"
  11. #include "BfUtil.h"
  12. #include <unordered_map>
  13. #include <unordered_set>
  14. #include <set>
  15. #include "MemReporter.h"
  16. namespace llvm
  17. {
  18. class Type;
  19. class Function;
  20. }
  21. #define BF_NEW_INT_TYPES
  22. #ifdef BF_NEW_INT_TYPES
  23. #define BF_INT32_NAME "int32"
  24. #else
  25. #define BF_INT32_NAME "int"
  26. #endif
  27. #ifdef BF_PLATFORM_WINDOWS
  28. #define BF_OBJ_EXT ".obj"
  29. #else
  30. #define BF_OBJ_EXT ".o"
  31. #endif
  32. NS_BF_BEGIN
  33. class BfSystem;
  34. class BfTypeReference;
  35. class BfCompiler;
  36. class BfProject;
  37. struct BfTypeDefMapFuncs;
  38. typedef MultiHashSet<BfTypeDef*, BfTypeDefMapFuncs> BfTypeDefMap;
  39. typedef HashSet<BfProject*> BfProjectSet;
  40. class BfAtom
  41. {
  42. public:
  43. StringView mString;
  44. int mRefCount;
  45. int mHash;
  46. uint32 mAtomUpdateIdx;
  47. bool mIsSystemType;
  48. Dictionary<BfAtom*, int> mPrevNamesMap;
  49. public:
  50. ~BfAtom();
  51. const StringView& ToString()
  52. {
  53. return mString;
  54. }
  55. void ToString(StringImpl& str)
  56. {
  57. str += mString;
  58. }
  59. void Ref();
  60. };
  61. class BfAtomComposite
  62. {
  63. public:
  64. BfAtom** mParts;
  65. int16 mSize;
  66. int16 mAllocSize;
  67. bool mOwns;
  68. public:
  69. BfAtomComposite();
  70. BfAtomComposite(BfAtomComposite&& rhs);
  71. BfAtomComposite(const BfAtomComposite& rhs);
  72. BfAtomComposite(BfAtom* atom);
  73. BfAtomComposite(const BfAtomComposite& left, const BfAtomComposite& right);
  74. BfAtomComposite(const BfAtomComposite& left, BfAtom* right);
  75. ~BfAtomComposite();
  76. void Set(const BfAtomComposite& left, const BfAtomComposite& right);
  77. void Set(BfAtom** atomsA, int countA, BfAtom** atomsB, int countB);
  78. BfAtomComposite& operator=(const BfAtomComposite& rhs);
  79. bool operator==(const BfAtomComposite& other) const;
  80. bool operator!=(const BfAtomComposite& other) const;
  81. bool IsValid() const;
  82. bool IsEmpty() const;
  83. int GetPartsCount() const;
  84. String ToString() const;
  85. void ToString(StringImpl& str) const;
  86. bool StartsWith(const BfAtomComposite& other) const;
  87. bool EndsWith(const BfAtomComposite& other) const;
  88. BfAtomComposite GetSub(int start, int len) const;
  89. void Reference(const BfAtomComposite& other);
  90. uint32 GetAtomUpdateIdx();
  91. };
  92. class BfSizedAtomComposite : public BfAtomComposite
  93. {
  94. public:
  95. BfAtom* mInitialAlloc[8];
  96. BfSizedAtomComposite();
  97. ~BfSizedAtomComposite();
  98. };
  99. struct BfAtomCompositeHash
  100. {
  101. size_t operator()(const BfAtomComposite& composite) const
  102. {
  103. int curHash = 0;
  104. for (int i = 0; i < (int)composite.mSize; i++)
  105. curHash = ((curHash ^ (int)(intptr)composite.mParts[i]->mHash) << 5) - curHash;
  106. return curHash;
  107. }
  108. };
  109. struct BfAtomCompositeEquals
  110. {
  111. bool operator()(const BfAtomComposite& lhs, const BfAtomComposite& rhs) const
  112. {
  113. if (lhs.mSize != rhs.mSize)
  114. return false;
  115. for (int i = 0; i < lhs.mSize; i++)
  116. if (lhs.mParts[i] != rhs.mParts[i])
  117. return false;
  118. return true;
  119. }
  120. };
  121. enum BfCompilerOptionFlags
  122. {
  123. BfCompilerOptionFlag_EmitDebugInfo = 1,
  124. BfCompilerOptionFlag_EmitLineInfo = 2,
  125. BfCompilerOptionFlag_WriteIR = 4,
  126. BfCompilerOptionFlag_GenerateOBJ = 8,
  127. BfCompilerOptionFlag_GenerateBitcode = 0x10,
  128. BfCompilerOptionFlag_ClearLocalVars = 0x20,
  129. BfCompilerOptionFlag_RuntimeChecks = 0x40,
  130. BfCompilerOptionFlag_EmitDynamicCastCheck = 0x80,
  131. BfCompilerOptionFlag_EnableObjectDebugFlags = 0x100,
  132. BfCompilerOptionFlag_EmitObjectAccessCheck = 0x200,
  133. BfCompilerOptionFlag_EnableCustodian = 0x400,
  134. BfCompilerOptionFlag_EnableRealtimeLeakCheck = 0x800,
  135. BfCompilerOptionFlag_EnableSideStack = 0x1000,
  136. BfCompilerOptionFlag_EnableHotSwapping = 0x2000,
  137. BfCompilerOptionFlag_IncrementalBuild = 0x4000,
  138. BfCompilerOptionFlag_DebugAlloc = 0x8000,
  139. BfCompilerOptionFlag_OmitDebugHelpers = 0x10000,
  140. BfCompilerOptionFlag_NoFramePointerElim = 0x20000,
  141. };
  142. enum BfTypeFlags
  143. {
  144. BfTypeFlags_UnspecializedGeneric = 0x0001,
  145. BfTypeFlags_SpecializedGeneric = 0x0002,
  146. BfTypeFlags_Array = 0x0004,
  147. BfTypeFlags_Object = 0x0008,
  148. BfTypeFlags_Boxed = 0x0010,
  149. BfTypeFlags_Pointer = 0x0020,
  150. BfTypeFlags_Struct = 0x0040,
  151. BfTypeFlags_Interface = 0x0080,
  152. BfTypeFlags_Primitive = 0x0100,
  153. BfTypeFlags_TypedPrimitive = 0x0200,
  154. BfTypeFlags_Tuple = 0x0400,
  155. BfTypeFlags_Nullable = 0x0800,
  156. BfTypeFlags_SizedArray = 0x1000,
  157. BfTypeFlags_Splattable = 0x2000,
  158. BfTypeFlags_Union = 0x4000,
  159. //
  160. BfTypeFlags_WantsMarking = 0x8000,
  161. BfTypeFlags_Delegate = 0x10000,
  162. BfTypeFlags_Function = 0x20000,
  163. BfTypeFlags_HasDestructor = 0x40000,
  164. };
  165. enum BfObjectFlags : uint8
  166. {
  167. BfObjectFlag_None = 0,
  168. BfObjectFlag_MarkIdMask = 0x03,
  169. BfObjectFlag_Allocated = 0x04,
  170. BfObjectFlag_StackAlloc = 0x08,
  171. BfObjectFlag_AppendAlloc = 0x10,
  172. BfObjectFlag_AllocInfo = 0x20,
  173. BfObjectFlag_AllocInfo_Short = 0x40,
  174. BfObjectFlag_Deleted = 0x80,
  175. BfObjectFlag_StackDeleted = 0x80 // We remove StackAlloc so it doesn't get scanned
  176. };
  177. enum BfCustomAttributeFlags
  178. {
  179. BfCustomAttributeFlags_None,
  180. BfCustomAttributeFlags_DisallowAllowMultiple = 1,
  181. BfCustomAttributeFlags_NotInherited = 2,
  182. BfCustomAttributeFlags_ReflectAttribute = 4,
  183. BfCustomAttributeFlags_AlwaysIncludeTarget = 8
  184. };
  185. enum BfPlatformType
  186. {
  187. BfPlatformType_Unknown,
  188. BfPlatformType_Windows,
  189. BfPlatformType_Linux,
  190. BfPlatformType_macOS,
  191. BfPlatformType_iOS,
  192. BfPlatformType_Android,
  193. BfPlatformType_Wasm
  194. };
  195. enum BfMachineType
  196. {
  197. BfMachineType_Unknown,
  198. BfMachineType_x86,
  199. BfMachineType_x64,
  200. BfMachineType_ARM,
  201. BfMachineType_AArch64,
  202. BfMachineType_Wasm32,
  203. BfMachineType_Wasm64,
  204. };
  205. enum BfToolsetType
  206. {
  207. BfToolsetType_GNU,
  208. BfToolsetType_Microsoft,
  209. BfToolsetType_LLVM
  210. };
  211. enum BfSIMDSetting
  212. {
  213. BfSIMDSetting_None,
  214. BfSIMDSetting_MMX,
  215. BfSIMDSetting_SSE,
  216. BfSIMDSetting_SSE2,
  217. BfSIMDSetting_SSE3,
  218. BfSIMDSetting_SSE4,
  219. BfSIMDSetting_SSE41,
  220. BfSIMDSetting_AVX,
  221. BfSIMDSetting_AVX2,
  222. };
  223. enum BfAsmKind
  224. {
  225. BfAsmKind_None,
  226. BfAsmKind_ATT,
  227. BfAsmKind_Intel,
  228. };
  229. enum BfOptLevel
  230. {
  231. BfOptLevel_NotSet = -1,
  232. BfOptLevel_O0 = 0,
  233. BfOptLevel_O1,
  234. BfOptLevel_O2,
  235. BfOptLevel_O3,
  236. BfOptLevel_Og,
  237. BfOptLevel_OgPlus
  238. };
  239. enum BfLTOType
  240. {
  241. BfLTOType_None = 0,
  242. BfLTOType_Thin = 1
  243. };
  244. enum BfCFLAAType
  245. {
  246. BfCFLAAType_None,
  247. BfCFLAAType_Steensgaard,
  248. BfCFLAAType_Andersen,
  249. BfCFLAAType_Both
  250. };
  251. enum BfRelocType
  252. {
  253. BfRelocType_NotSet,
  254. BfRelocType_Static,
  255. BfRelocType_PIC,
  256. BfRelocType_DynamicNoPIC,
  257. BfRelocType_ROPI,
  258. BfRelocType_RWPI,
  259. BfRelocType_ROPI_RWPI
  260. };
  261. enum BfPICLevel
  262. {
  263. BfPICLevel_NotSet,
  264. BfPICLevel_Not,
  265. BfPICLevel_Small,
  266. BfPICLevel_Big
  267. };
  268. struct BfCodeGenOptions
  269. {
  270. bool mIsHotCompile;
  271. bool mWriteObj;
  272. bool mWriteBitcode;
  273. BfAsmKind mAsmKind;
  274. bool mWriteToLib;
  275. bool mWriteLLVMIR;
  276. int16 mVirtualMethodOfs;
  277. int16 mDynSlotOfs;
  278. BfRelocType mRelocType;
  279. BfPICLevel mPICLevel;
  280. BfSIMDSetting mSIMDSetting;
  281. BfOptLevel mOptLevel;
  282. BfLTOType mLTOType;
  283. int mSizeLevel;
  284. BfCFLAAType mUseCFLAA;
  285. bool mUseNewSROA;
  286. bool mDisableTailCalls;
  287. bool mDisableUnitAtATime;
  288. bool mDisableUnrollLoops;
  289. bool mBBVectorize;
  290. bool mSLPVectorize;
  291. bool mLoopVectorize;
  292. bool mRerollLoops;
  293. bool mLoadCombine;
  294. bool mDisableGVNLoadPRE;
  295. bool mVerifyInput;
  296. bool mVerifyOutput;
  297. bool mStripDebug;
  298. bool mMergeFunctions;
  299. bool mEnableMLSM;
  300. bool mRunSLPAfterLoopVectorization;
  301. bool mUseGVNAfterVectorization;
  302. bool mEnableLoopInterchange;
  303. bool mEnableLoopLoadElim;
  304. bool mExtraVectorizerPasses;
  305. bool mEnableEarlyCSEMemSSA;
  306. bool mEnableGVNHoist;
  307. bool mEnableGVNSink;
  308. bool mDisableLibCallsShrinkWrap;
  309. bool mExpensiveCombines;
  310. bool mEnableSimpleLoopUnswitch;
  311. bool mDivergentTarget;
  312. bool mNewGVN;
  313. bool mRunPartialInlining;
  314. bool mUseLoopVersioningLICM;
  315. bool mEnableUnrollAndJam;
  316. bool mEnableHotColdSplit;
  317. Val128 mHash;
  318. BfCodeGenOptions()
  319. {
  320. mIsHotCompile = false;
  321. mWriteObj = true;
  322. mWriteBitcode = false;
  323. mAsmKind = BfAsmKind_None;
  324. mWriteToLib = false;
  325. mWriteLLVMIR = false;
  326. mVirtualMethodOfs = 0;
  327. mDynSlotOfs = 0;
  328. mRelocType = BfRelocType_NotSet;
  329. mPICLevel = BfPICLevel_NotSet;
  330. mSIMDSetting = BfSIMDSetting_None;
  331. mOptLevel = BfOptLevel_O0;
  332. mLTOType = BfLTOType_None;
  333. mSizeLevel = 0;
  334. mUseCFLAA = BfCFLAAType_None;
  335. mUseNewSROA = false;
  336. mDisableTailCalls = false;
  337. mDisableUnitAtATime = false;
  338. mDisableUnrollLoops = false;
  339. mBBVectorize = false;
  340. mSLPVectorize = false;
  341. mLoopVectorize = false;
  342. mRerollLoops = false;
  343. mLoadCombine = false;
  344. mDisableGVNLoadPRE = false;
  345. mVerifyInput = false;
  346. mVerifyOutput = false;
  347. mStripDebug = false;
  348. mMergeFunctions = false;
  349. mEnableMLSM = false;
  350. mRunSLPAfterLoopVectorization = false;
  351. mUseGVNAfterVectorization = false;
  352. mEnableLoopInterchange = false;
  353. mEnableLoopLoadElim = true;
  354. mExtraVectorizerPasses = false;
  355. mEnableEarlyCSEMemSSA = true;
  356. mEnableGVNHoist = false;
  357. mEnableGVNSink = false;
  358. mDisableLibCallsShrinkWrap = false;
  359. mExpensiveCombines = false;
  360. mEnableSimpleLoopUnswitch = false;
  361. mDivergentTarget = false;
  362. mNewGVN = false;
  363. mRunPartialInlining = false;
  364. mUseLoopVersioningLICM = false;
  365. mEnableUnrollAndJam = false;
  366. mEnableHotColdSplit = false;
  367. }
  368. void GenerateHash()
  369. {
  370. HashContext hashCtx;
  371. hashCtx.Mixin(mWriteObj);
  372. hashCtx.Mixin(mWriteBitcode);
  373. hashCtx.Mixin(mAsmKind);
  374. hashCtx.Mixin(mWriteToLib);
  375. hashCtx.Mixin(mWriteLLVMIR);
  376. hashCtx.Mixin(mVirtualMethodOfs);
  377. hashCtx.Mixin(mDynSlotOfs);
  378. hashCtx.Mixin(mRelocType);
  379. hashCtx.Mixin(mPICLevel);
  380. hashCtx.Mixin(mSIMDSetting);
  381. hashCtx.Mixin(mOptLevel);
  382. hashCtx.Mixin(mLTOType);
  383. hashCtx.Mixin(mSizeLevel);
  384. hashCtx.Mixin(mUseCFLAA);
  385. hashCtx.Mixin(mUseNewSROA);
  386. hashCtx.Mixin(mDisableTailCalls);
  387. hashCtx.Mixin(mDisableUnitAtATime);
  388. hashCtx.Mixin(mDisableUnrollLoops);
  389. hashCtx.Mixin(mBBVectorize);
  390. hashCtx.Mixin(mSLPVectorize);
  391. hashCtx.Mixin(mLoopVectorize);
  392. hashCtx.Mixin(mRerollLoops);
  393. hashCtx.Mixin(mLoadCombine);
  394. hashCtx.Mixin(mDisableGVNLoadPRE);
  395. hashCtx.Mixin(mVerifyInput);
  396. hashCtx.Mixin(mVerifyOutput);
  397. hashCtx.Mixin(mStripDebug);
  398. hashCtx.Mixin(mMergeFunctions);
  399. hashCtx.Mixin(mEnableMLSM);
  400. hashCtx.Mixin(mRunSLPAfterLoopVectorization);
  401. hashCtx.Mixin(mUseGVNAfterVectorization);
  402. hashCtx.Mixin(mEnableLoopInterchange);
  403. hashCtx.Mixin(mEnableLoopLoadElim);
  404. hashCtx.Mixin(mExtraVectorizerPasses);
  405. mHash = hashCtx.Finish128();
  406. }
  407. };
  408. enum BfParamKind : uint8
  409. {
  410. BfParamKind_Normal,
  411. BfParamKind_ExplicitThis,
  412. BfParamKind_Params,
  413. BfParamKind_DelegateParam,
  414. BfParamKind_ImplicitCapture,
  415. BfParamKind_AppendIdx,
  416. BfParamKind_VarArgs
  417. };
  418. class BfParameterDef
  419. {
  420. public:
  421. String mName;
  422. BfTypeReference* mTypeRef;
  423. BfParameterDeclaration* mParamDeclaration;
  424. int mMethodGenericParamIdx;
  425. BfParamKind mParamKind;
  426. public:
  427. BfParameterDef()
  428. {
  429. mTypeRef = NULL;
  430. mMethodGenericParamIdx = -1;
  431. mParamKind = BfParamKind_Normal;
  432. mParamDeclaration = NULL;
  433. }
  434. };
  435. class BfMemberDef
  436. {
  437. public:
  438. #ifdef _DEBUG
  439. StringT<48> mName;
  440. #else
  441. String mName;
  442. #endif
  443. BfTypeDef* mDeclaringType;
  444. BfProtection mProtection;
  445. bool mIsStatic;
  446. bool mIsNoShow;
  447. bool mIsReadOnly;
  448. bool mHasMultiDefs;
  449. public:
  450. BfMemberDef()
  451. {
  452. mDeclaringType = NULL;
  453. mProtection = BfProtection_Public;
  454. mIsStatic = false;
  455. mIsNoShow = false;
  456. mIsReadOnly = false;
  457. mHasMultiDefs = false;
  458. }
  459. virtual ~BfMemberDef()
  460. {
  461. }
  462. };
  463. class BfFieldDef : public BfMemberDef
  464. {
  465. public:
  466. int mIdx;
  467. bool mIsConst; // Note: Consts are also all considered Static
  468. bool mIsInline;
  469. bool mIsVolatile;
  470. bool mIsExtern;
  471. BfTypeReference* mTypeRef;
  472. BfExpression* mInitializer;
  473. BfFieldDeclaration* mFieldDeclaration;
  474. // It may seem that fields and properties don't need a 'mNextWithSameName', but with extensions it's possible
  475. // to have two libraries which each add a field to a type with the same name
  476. BfFieldDef* mNextWithSameName;
  477. public:
  478. BfFieldDef()
  479. {
  480. mIdx = 0;
  481. mIsConst = false;
  482. mIsInline = false;
  483. mIsExtern = false;
  484. mIsVolatile = false;
  485. mTypeRef = NULL;
  486. mInitializer = NULL;
  487. mFieldDeclaration = NULL;
  488. mNextWithSameName = NULL;
  489. }
  490. bool IsUnnamedTupleField()
  491. {
  492. return (mName[0] >= '0') && (mName[0] <= '9');
  493. }
  494. bool IsEnumCaseEntry()
  495. {
  496. return (mFieldDeclaration != NULL) && (BfNodeIsA<BfEnumEntryDeclaration>(mFieldDeclaration));
  497. }
  498. bool IsNonConstStatic()
  499. {
  500. return mIsStatic && !mIsConst;
  501. }
  502. BfAstNode* GetRefNode()
  503. {
  504. if (mFieldDeclaration == NULL)
  505. return NULL;
  506. if (mFieldDeclaration->mNameNode != NULL)
  507. return mFieldDeclaration->mNameNode;
  508. return mFieldDeclaration;
  509. }
  510. };
  511. class BfPropertyDef : public BfFieldDef
  512. {
  513. public:
  514. Array<BfMethodDef*> mMethods;
  515. BfPropertyDef* mNextWithSameName;
  516. public:
  517. BfPropertyDef()
  518. {
  519. mNextWithSameName = NULL;
  520. }
  521. bool IsVirtual();
  522. bool HasExplicitInterface();
  523. bool IsExpressionBodied();
  524. BfAstNode* GetRefNode();
  525. };
  526. enum BfGenericParamFlags : uint16
  527. {
  528. BfGenericParamFlag_None = 0,
  529. BfGenericParamFlag_Class = 1,
  530. BfGenericParamFlag_Struct = 2,
  531. BfGenericParamFlag_StructPtr = 4,
  532. BfGenericParamFlag_Enum = 8,
  533. BfGenericParamFlag_Interface = 0x10,
  534. BfGenericParamFlag_New = 0x20,
  535. BfGenericParamFlag_Delete = 0x40,
  536. BfGenericParamFlag_Var = 0x80,
  537. BfGenericParamFlag_Const = 0x100,
  538. BfGenericParamFlag_Equals = 0x200,
  539. BfGenericParamFlag_Equals_Op = 0x400,
  540. BfGenericParamFlag_Equals_Type = 0x800,
  541. BfGenericParamFlag_Equals_IFace = 0x1000
  542. };
  543. class BfConstraintDef
  544. {
  545. public:
  546. BfGenericParamFlags mGenericParamFlags;
  547. Array<BfAstNode*> mConstraints;
  548. BfConstraintDef()
  549. {
  550. mGenericParamFlags = BfGenericParamFlag_None;
  551. }
  552. };
  553. class BfGenericParamDef : public BfConstraintDef
  554. {
  555. public:
  556. String mName;
  557. Array<BfIdentifierNode*> mNameNodes; // 0 is always the def name
  558. };
  559. class BfExternalConstraintDef : public BfConstraintDef
  560. {
  561. public:
  562. BfTypeReference* mTypeRef;
  563. };
  564. // CTOR is split into two for Objects - Ctor clears and sets up VData, Ctor_Body executes ctor body code
  565. enum BfMethodType : uint8
  566. {
  567. BfMethodType_Ignore,
  568. BfMethodType_Normal,
  569. BfMethodType_PropertyGetter,
  570. BfMethodType_PropertySetter,
  571. BfMethodType_CtorCalcAppend,
  572. BfMethodType_Ctor,
  573. BfMethodType_CtorNoBody,
  574. BfMethodType_CtorClear,
  575. BfMethodType_Init,
  576. BfMethodType_Dtor,
  577. BfMethodType_Operator,
  578. BfMethodType_Mixin,
  579. BfMethodType_Extension
  580. };
  581. enum BfCallingConvention : uint8
  582. {
  583. BfCallingConvention_Unspecified,
  584. BfCallingConvention_Cdecl,
  585. BfCallingConvention_Stdcall,
  586. BfCallingConvention_Fastcall,
  587. BfCallingConvention_CVarArgs,
  588. };
  589. #define BF_METHODNAME_MARKMEMBERS "GCMarkMembers"
  590. #define BF_METHODNAME_MARKMEMBERS_STATIC "GCMarkStaticMembers"
  591. #define BF_METHODNAME_FIND_TLS_MEMBERS "GCFindTLSMembers"
  592. #define BF_METHODNAME_DYNAMICCAST "DynamicCastToTypeId"
  593. #define BF_METHODNAME_DYNAMICCAST_INTERFACE "DynamicCastToInterface"
  594. #define BF_METHODNAME_CALCAPPEND "this$calcAppend"
  595. #define BF_METHODNAME_ENUM_HASFLAG "HasFlag"
  596. #define BF_METHODNAME_ENUM_GETUNDERLYING "get__Underlying"
  597. #define BF_METHODNAME_ENUM_GETUNDERLYINGREF "get__UnderlyingRef"
  598. #define BF_METHODNAME_EQUALS "Equals"
  599. #define BF_METHODNAME_INVOKE "Invoke"
  600. #define BF_METHODNAME_TO_STRING "ToString"
  601. #define BF_METHODNAME_DEFAULT_EQUALS "__Equals"
  602. #define BF_METHODNAME_DEFAULT_STRICT_EQUALS "__StrictEquals"
  603. enum BfOptimize : int8
  604. {
  605. BfOptimize_Default,
  606. BfOptimize_Unoptimized,
  607. BfOptimize_Optimized
  608. };
  609. enum BfImportKind : int8
  610. {
  611. BfImportKind_None,
  612. BfImportKind_Import_Unknown,
  613. BfImportKind_Import_Dynamic,
  614. BfImportKind_Import_Static,
  615. BfImportKind_Export
  616. };
  617. enum BfCommutableKind : int8
  618. {
  619. BfCommutableKind_None,
  620. BfCommutableKind_Operator,
  621. BfCommutableKind_Forward,
  622. BfCommutableKind_Reverse,
  623. };
  624. class BfMethodDef : public BfMemberDef
  625. {
  626. public:
  627. BfAstNode* mMethodDeclaration;
  628. BfAstNode* mBody;
  629. BfTypeReference* mExplicitInterface;
  630. BfTypeReference* mReturnTypeRef;
  631. Array<BfParameterDef*> mParams;
  632. Array<BfGenericParamDef*> mGenericParams;
  633. Array<BfExternalConstraintDef> mExternalConstraints;
  634. BfMethodDef* mNextWithSameName;
  635. Val128 mFullHash;
  636. int mIdx;
  637. int mPropertyIdx;
  638. BfMethodType mMethodType;
  639. bool mIsLocalMethod;
  640. bool mIsVirtual;
  641. bool mIsOverride;
  642. bool mIsAbstract;
  643. bool mIsConcrete;
  644. bool mIsPartial;
  645. bool mIsNew;
  646. bool mCodeChanged;
  647. bool mWantsBody;
  648. bool mCLink;
  649. bool mHasAppend;
  650. bool mAlwaysInline;
  651. bool mIsNoReturn;
  652. bool mIsMutating;
  653. bool mIsNoSplat;
  654. bool mIsNoReflect;
  655. bool mIsSkipCall;
  656. bool mIsConstEval;
  657. bool mIsOperator;
  658. bool mIsExtern;
  659. bool mIsNoDiscard;
  660. bool mHasExplicitThis;
  661. BfCommutableKind mCommutableKind;
  662. BfCheckedKind mCheckedKind;
  663. BfImportKind mImportKind;
  664. BfCallingConvention mCallingConvention;
  665. public:
  666. BfMethodDef()
  667. {
  668. mIdx = -1;
  669. mPropertyIdx = -1;
  670. mIsLocalMethod = false;
  671. mIsVirtual = false;
  672. mIsOverride = false;
  673. mIsAbstract = false;
  674. mIsConcrete = false;
  675. mIsStatic = false;
  676. mIsNew = false;
  677. mIsPartial = false;
  678. mCLink = false;
  679. mIsNoReturn = false;
  680. mIsMutating = false;
  681. mIsNoSplat = false;
  682. mIsNoReflect = false;
  683. mIsSkipCall = false;
  684. mIsConstEval = false;
  685. mIsOperator = false;
  686. mIsExtern = false;
  687. mIsNoDiscard = false;
  688. mHasExplicitThis = false;
  689. mBody = NULL;
  690. mExplicitInterface = NULL;
  691. mReturnTypeRef = NULL;
  692. mMethodDeclaration = NULL;
  693. mCodeChanged = false;
  694. mWantsBody = true;
  695. mCommutableKind = BfCommutableKind_None;
  696. mCheckedKind = BfCheckedKind_NotSet;
  697. mImportKind = BfImportKind_None;
  698. mMethodType = BfMethodType_Normal;
  699. mCallingConvention = BfCallingConvention_Unspecified;
  700. mHasAppend = false;
  701. mAlwaysInline = false;
  702. mNextWithSameName = NULL;
  703. }
  704. virtual ~BfMethodDef();
  705. static BfImportKind GetImportKindFromPath(const StringImpl& filePath);
  706. bool HasNoThisSplat() { return mIsMutating || mIsNoSplat; }
  707. void Reset();
  708. void FreeMembers();
  709. BfMethodDeclaration* GetMethodDeclaration();
  710. BfPropertyMethodDeclaration* GetPropertyMethodDeclaration();
  711. BfPropertyDeclaration* GetPropertyDeclaration();
  712. BfAstNode* GetRefNode();
  713. BfTokenNode* GetMutNode();
  714. bool HasBody();
  715. bool IsEmptyPartial();
  716. bool IsDefaultCtor();
  717. String ToString();
  718. int GetExplicitParamCount();
  719. };
  720. class BfOperatorDef : public BfMethodDef
  721. {
  722. public:
  723. BfOperatorDeclaration* mOperatorDeclaration;
  724. public:
  725. BfOperatorDef()
  726. {
  727. mOperatorDeclaration = NULL;
  728. }
  729. };
  730. struct BfTypeDefLookupContext
  731. {
  732. public:
  733. int mBestPri;
  734. BfTypeDef* mBestTypeDef;
  735. BfTypeDef* mAmbiguousTypeDef;
  736. public:
  737. BfTypeDefLookupContext()
  738. {
  739. mBestPri = (int)0x80000000;
  740. mBestTypeDef = NULL;
  741. mAmbiguousTypeDef = NULL;
  742. }
  743. bool HasValidMatch()
  744. {
  745. return (mBestPri >= 0) && (mBestTypeDef != NULL);
  746. }
  747. };
  748. struct BfMemberSetEntry
  749. {
  750. BfMemberDef* mMemberDef;
  751. BfMemberSetEntry(BfMemberDef* memberDef)
  752. {
  753. mMemberDef = memberDef;
  754. }
  755. bool operator==(const BfMemberSetEntry& other) const
  756. {
  757. return mMemberDef->mName == other.mMemberDef->mName;
  758. }
  759. bool operator==(const StringImpl& other) const
  760. {
  761. return mMemberDef->mName == other;
  762. }
  763. };
  764. // For partial classes, the first entry in the map will contain the combined data
  765. class BfTypeDef
  766. {
  767. public:
  768. enum DefState
  769. {
  770. DefState_New,
  771. DefState_Defined,
  772. DefState_CompositeWithPartials, // Temporary condition
  773. DefState_AwaitingNewVersion,
  774. DefState_Signature_Changed,
  775. DefState_InlinedInternals_Changed, // Code within methods, including inlined methods, changed
  776. DefState_Internals_Changed, // Only code within a non-inlined methods changed
  777. DefState_Deleted
  778. };
  779. public:
  780. BfTypeDef* mNextRevision;
  781. BfSystem* mSystem;
  782. BfProject* mProject;
  783. BfTypeDeclaration* mTypeDeclaration;
  784. BfSource* mSource;
  785. DefState mDefState;
  786. Val128 mSignatureHash; // Data, methods, etc
  787. Val128 mFullHash;
  788. Val128 mInlineHash;
  789. BfTypeDef* mOuterType;
  790. BfAtomComposite mNamespace;
  791. BfAtom* mName;
  792. BfAtom* mNameEx; // Contains extensions like `1 for param counts
  793. BfAtomComposite mFullName;
  794. BfAtomComposite mFullNameEx;
  795. BfProtection mProtection;
  796. Array<BfAtomComposite> mNamespaceSearch;
  797. Array<BfTypeReference*> mStaticSearch;
  798. Array<BfTypeReference*> mInternalAccessSet;
  799. Array<BfFieldDef*> mFields;
  800. Array<BfPropertyDef*> mProperties;
  801. Array<BfMethodDef*> mMethods;
  802. HashSet<BfMemberSetEntry> mMethodSet;
  803. HashSet<BfMemberSetEntry> mFieldSet;
  804. HashSet<BfMemberSetEntry> mPropertySet;
  805. Array<BfOperatorDef*> mOperators;
  806. BfMethodDef* mDtorDef;
  807. Array<BfGenericParamDef*> mGenericParamDefs;
  808. Array<BfExternalConstraintDef> mExternalConstraints;
  809. Array<BfTypeReference*> mBaseTypes;
  810. Array<BfTypeDef*> mNestedTypes;
  811. Array<BfDirectStrTypeReference*> mDirectAllocNodes;
  812. Array<BfTypeDef*> mPartials; // Only valid for mIsCombinedPartial
  813. int mHash;
  814. int mPartialIdx;
  815. int mNestDepth;
  816. int mDupDetectedRevision; // Error state
  817. BfTypeCode mTypeCode;
  818. bool mIsAlwaysInclude;
  819. bool mIsNoDiscard;
  820. bool mIsPartial;
  821. bool mIsExplicitPartial;
  822. bool mPartialUsed;
  823. bool mIsCombinedPartial;
  824. bool mIsDelegate;
  825. bool mIsFunction;
  826. bool mIsClosure;
  827. bool mIsAbstract;
  828. bool mIsConcrete;
  829. bool mIsStatic;
  830. bool mHasAppendCtor;
  831. bool mHasCtorNoBody;
  832. bool mHasExtensionMethods;
  833. bool mHasOverrideMethods;
  834. bool mIsOpaque;
  835. bool mIsNextRevision;
  836. public:
  837. BfTypeDef()
  838. {
  839. Init();
  840. }
  841. ~BfTypeDef();
  842. void Init()
  843. {
  844. mName = NULL;
  845. mNameEx = NULL;
  846. mSystem = NULL;
  847. mProject = NULL;
  848. mTypeCode = BfTypeCode_None;
  849. mIsAlwaysInclude = false;
  850. mIsNoDiscard = false;
  851. mIsExplicitPartial = false;
  852. mIsPartial = false;
  853. mIsCombinedPartial = false;
  854. mTypeDeclaration = NULL;
  855. mSource = NULL;
  856. mDefState = DefState_New;
  857. mHash = 0;
  858. mPartialIdx = -1;
  859. mIsAbstract = false;
  860. mIsConcrete = false;
  861. mIsDelegate = false;
  862. mIsFunction = false;
  863. mIsClosure = false;
  864. mIsStatic = false;
  865. mHasAppendCtor = false;
  866. mHasCtorNoBody = false;
  867. mHasExtensionMethods = false;
  868. mHasOverrideMethods = false;
  869. mIsOpaque = false;
  870. mPartialUsed = false;
  871. mIsNextRevision = false;
  872. mDupDetectedRevision = -1;
  873. mNestDepth = 0;
  874. mOuterType = NULL;
  875. mTypeDeclaration = NULL;
  876. mDtorDef = NULL;
  877. mNextRevision = NULL;
  878. mProtection = BfProtection_Public;
  879. }
  880. BfSource* GetLastSource();
  881. bool IsGlobalsContainer();
  882. void Reset();
  883. void FreeMembers();
  884. void PopulateMemberSets();
  885. void RemoveGenericParamDef(BfGenericParamDef* genericParamDef);
  886. int GetSelfGenericParamCount();
  887. String ToString();
  888. BfMethodDef* GetMethodByName(const StringImpl& name, int paramCount = -1);
  889. bool HasAutoProperty(BfPropertyDeclaration* propertyDeclaration);
  890. String GetAutoPropertyName(BfPropertyDeclaration* propertyDeclaration);
  891. BfAstNode* GetRefNode();
  892. BfTypeDef* GetLatest()
  893. {
  894. if (mNextRevision != NULL)
  895. return mNextRevision;
  896. return this;
  897. }
  898. void ReportMemory(MemReporter* memReporter);
  899. bool NameEquals(BfTypeDef* otherTypeDef);
  900. bool IsExtension()
  901. {
  902. return mTypeCode == BfTypeCode_Extension;
  903. }
  904. bool HasSource(BfSource* source);
  905. };
  906. struct BfTypeDefMapFuncs : public MultiHashSetFuncs
  907. {
  908. int GetHash(BfTypeDef* typeDef)
  909. {
  910. return GetHash(typeDef->mFullName);
  911. }
  912. int GetHash(const BfAtomComposite& name)
  913. {
  914. int hash = 0;
  915. for (int i = 0; i < name.mSize; i++)
  916. {
  917. auto atom = name.mParts[i];
  918. hash = ((hash ^ atom->mHash) << 5) - hash;
  919. }
  920. return (hash & 0x7FFFFFFF);
  921. }
  922. bool Matches(const BfAtomComposite& name, BfTypeDef* typeDef)
  923. {
  924. return name == typeDef->mFullName;
  925. }
  926. bool Matches(BfTypeDef* keyTypeDef, BfTypeDef* typeDef)
  927. {
  928. return keyTypeDef == typeDef;
  929. }
  930. };
  931. enum BfTargetType
  932. {
  933. BfTargetType_BeefConsoleApplication,
  934. BfTargetType_BeefWindowsApplication,
  935. BfTargetType_BeefLib,
  936. BfTargetType_BeefDynLib,
  937. BfTargetType_CustomBuild,
  938. BfTargetType_BeefTest,
  939. BfTargetType_C_ConsoleApplication,
  940. BfTargetType_C_WindowsApplication,
  941. BfTargetType_BeefApplication_StaticLib,
  942. BfTargetType_BeefApplication_DynamicLib
  943. };
  944. enum BfProjectFlags
  945. {
  946. BfProjectFlags_None = 0,
  947. BfProjectFlags_MergeFunctions = 1,
  948. BfProjectFlags_CombineLoads = 2,
  949. BfProjectFlags_VectorizeLoops = 4,
  950. BfProjectFlags_VectorizeSLP = 8,
  951. BfProjectFlags_SingleModule = 0x10,
  952. BfProjectFlags_AsmOutput = 0x20,
  953. BfProjectFlags_AsmOutput_ATT = 0x40,
  954. BfProjectFlags_AlwaysIncludeAll = 0x80,
  955. };
  956. class BfProject
  957. {
  958. public:
  959. enum DeleteStage
  960. {
  961. DeleteStage_None,
  962. DeleteStage_Queued,
  963. DeleteStage_AwaitingRefs,
  964. };
  965. public:
  966. BfSystem* mSystem;
  967. String mName;
  968. Array<BfProject*> mDependencies;
  969. BfTargetType mTargetType;
  970. BfCodeGenOptions mCodeGenOptions;
  971. bool mDisabled;
  972. bool mSingleModule;
  973. bool mAlwaysIncludeAll;
  974. DeleteStage mDeleteStage;
  975. int mIdx;
  976. String mStartupObject;
  977. Array<String> mPreprocessorMacros;
  978. Dictionary<BfAtomComposite, int> mNamespaces;
  979. HashSet<BfModule*> mUsedModules;
  980. HashSet<BfType*> mReferencedTypeData;
  981. Val128 mBuildConfigHash;
  982. Val128 mVDataConfigHash;
  983. bool mBuildConfigChanged;
  984. public:
  985. BfProject();
  986. ~BfProject();
  987. bool ContainsReference(BfProject* refProject);
  988. bool ReferencesOrReferencedBy(BfProject* refProject);
  989. bool IsTestProject();
  990. };
  991. //CDH TODO move these out to separate header if list gets big/unwieldy
  992. enum BfWarning
  993. {
  994. BfWarning_CS0108_MemberHidesInherited = 108,
  995. BfWarning_CS0114_MethodHidesInherited = 114,
  996. BfWarning_CS0162_UnreachableCode = 162,
  997. BfWarning_CS0168_VariableDeclaredButNeverUsed = 168,
  998. BfWarning_CS0472_ValueTypeNullCompare = 472,
  999. BfWarning_CS1030_PragmaWarning = 1030,
  1000. BfWarning_BF4201_Only7Hex = 4201,
  1001. BfWarning_BF4202_TooManyHexForInt = 4202,
  1002. BfWarning_BF4203_UnnecessaryDynamicCast = 4203,
  1003. BfWarning_BF4204_AddressOfReadOnly = 4204,
  1004. BfWarning_BF4205_StringInterpolationParam = 4205,
  1005. BfWarning_BF4206_OperatorCommutableUsage = 4206,
  1006. BfWarning_C4554_PossiblePrecedenceError = 4554
  1007. };
  1008. class BfErrorLocation
  1009. {
  1010. public:
  1011. String mFile;
  1012. int mLine;
  1013. int mColumn;
  1014. };
  1015. class BfErrorBase
  1016. {
  1017. public:
  1018. bool mIsWarning;
  1019. bool mIsDeferred;
  1020. BfSourceData* mSource;
  1021. int mSrcStart;
  1022. int mSrcEnd;
  1023. BfErrorLocation* mLocation;
  1024. public:
  1025. BfErrorBase()
  1026. {
  1027. mIsWarning = false;
  1028. mIsDeferred = false;
  1029. mSource = NULL;
  1030. mSrcStart = -1;
  1031. mSrcEnd = -1;
  1032. mLocation = NULL;
  1033. }
  1034. ~BfErrorBase();
  1035. void SetSource(BfPassInstance* passInstance, BfSourceData* source);
  1036. };
  1037. class BfMoreInfo : public BfErrorBase
  1038. {
  1039. public:
  1040. String mInfo;
  1041. };
  1042. class BfError : public BfErrorBase
  1043. {
  1044. public:
  1045. bool mIsAfter;
  1046. bool mIsPersistent;
  1047. bool mIsWhileSpecializing;
  1048. bool mIgnore;
  1049. BfProject* mProject;
  1050. String mError;
  1051. int mWarningNumber;
  1052. Array<BfMoreInfo*> mMoreInfo;
  1053. public:
  1054. BfError()
  1055. {
  1056. mIsAfter = false;
  1057. mIsPersistent = false;
  1058. mIsWhileSpecializing = false;
  1059. mIgnore = false;
  1060. mProject = NULL;
  1061. mWarningNumber = 0;
  1062. }
  1063. ~BfError()
  1064. {
  1065. for (auto moreInfo : mMoreInfo)
  1066. delete moreInfo;
  1067. }
  1068. int GetSrcStart()
  1069. {
  1070. return mSrcStart;
  1071. }
  1072. int GetSrcLength()
  1073. {
  1074. return mSrcEnd - mSrcStart;
  1075. }
  1076. int GetSrcEnd()
  1077. {
  1078. return mSrcEnd;
  1079. }
  1080. };
  1081. class BfSourceClassifier;
  1082. class BfAutoComplete;
  1083. enum BfFailFlags
  1084. {
  1085. BfFailFlag_None = 0,
  1086. BfFailFlag_ShowSpaceChars = 1
  1087. };
  1088. struct BfErrorEntry
  1089. {
  1090. public:
  1091. BfErrorBase* mError;
  1092. BfErrorEntry(BfErrorBase* error)
  1093. {
  1094. mError = error;
  1095. }
  1096. size_t GetHashCode() const;
  1097. bool operator==(const BfErrorEntry& other) const;
  1098. };
  1099. class BfPassInstance
  1100. {
  1101. public:
  1102. const int sMaxDisplayErrors = 100;
  1103. const int sMaxErrors = 1000;
  1104. BfSystem* mSystem;
  1105. bool mTrimMessagesToCursor;
  1106. int mFailedIdx;
  1107. Dictionary<BfSourceData*, String> mSourceFileNameMap;
  1108. HashSet<BfErrorEntry> mErrorSet;
  1109. Array<BfError*> mErrors;
  1110. int mIgnoreCount;
  1111. int mWarningCount;
  1112. int mDeferredErrorCount;
  1113. Deque<String> mOutStream;
  1114. bool mLastWasDisplayed;
  1115. bool mLastWasAdded;
  1116. uint8 mClassifierPassId;
  1117. BfParser* mFilterErrorsTo;
  1118. bool mHadSignatureChanges;
  1119. public:
  1120. BfPassInstance(BfSystem* bfSystem)
  1121. {
  1122. mTrimMessagesToCursor = false;
  1123. mFailedIdx = 0;
  1124. mSystem = bfSystem;
  1125. mLastWasDisplayed = false;
  1126. mLastWasAdded = false;
  1127. mClassifierPassId = 0;
  1128. mWarningCount = 0;
  1129. mDeferredErrorCount = 0;
  1130. mIgnoreCount = 0;
  1131. mFilterErrorsTo = NULL;
  1132. mHadSignatureChanges = false;
  1133. }
  1134. ~BfPassInstance();
  1135. void ClearErrors();
  1136. bool HasFailed();
  1137. bool HasMessages();
  1138. void OutputLine(const StringImpl& str);
  1139. bool PopOutString(String* outString);
  1140. bool WantsRangeRecorded(BfSourceData* bfSource, int srcIdx, int srcLen, bool isWarning, bool isDeferred = false);
  1141. bool WantsRangeDisplayed(BfSourceData* bfSource, int srcIdx, int srcLen, bool isWarning, bool isDeferred = false);
  1142. void TrimSourceRange(BfSourceData* source, int startIdx, int& srcLen); // Trim to a single line, in cases when we reference a large multi-line node
  1143. bool HasLastFailedAt(BfAstNode* astNode);
  1144. void MessageAt(const StringImpl& msgPrefix, const StringImpl& error, BfSourceData* bfSource, int srcIdx, int srcLen = 1, BfFailFlags flags = BfFailFlag_None);
  1145. void FixSrcStartAndEnd(BfSourceData* source, int& startIdx, int& endIdx);
  1146. BfError* WarnAt(int warningNumber, const StringImpl& warning, BfSourceData* bfSource, int srcIdx, int srcLen = 1);
  1147. BfError* Warn(int warningNumber, const StringImpl& warning);
  1148. BfError* Warn(int warningNumber, const StringImpl& warning, BfAstNode* refNode);
  1149. BfError* WarnAfter(int warningNumber, const StringImpl& warning, BfAstNode* refNode);
  1150. BfMoreInfo* MoreInfoAt(const StringImpl& info, BfSourceData* bfSource, int srcIdx, int srcLen, BfFailFlags flags = BfFailFlag_None);
  1151. BfMoreInfo* MoreInfo(const StringImpl& info);
  1152. BfMoreInfo* MoreInfo(const StringImpl& info, BfAstNode* refNode);
  1153. BfMoreInfo* MoreInfoAfter(const StringImpl& info, BfAstNode* refNode);
  1154. BfError* FailAt(const StringImpl& error, BfSourceData* bfSource, int srcIdx, int srcLen = 1, BfFailFlags flags = BfFailFlag_None);
  1155. BfError* FailAfterAt(const StringImpl& error, BfSourceData* bfSource, int srcIdx);
  1156. BfError* Fail(const StringImpl& error);
  1157. BfError* Fail(const StringImpl& error, BfAstNode* refNode);
  1158. BfError* FailAfter(const StringImpl& error, BfAstNode* refNode);
  1159. BfError* DeferFail(const StringImpl& error, BfAstNode* refNode);
  1160. void SilentFail();
  1161. void TryFlushDeferredError();
  1162. void WriteErrorSummary();
  1163. };
  1164. enum BfOptionFlags
  1165. {
  1166. BfOptionFlags_None = 0,
  1167. BfOptionFlags_RuntimeChecks = 1,
  1168. BfOptionFlags_InitLocalVariables = 2,
  1169. BfOptionFlags_EmitDynamicCastCheck = 4,
  1170. BfOptionFlags_EmitObjectAccessCheck = 8,
  1171. BfOptionFlags_ReflectAlwaysIncludeType = 0x10,
  1172. BfOptionFlags_ReflectAlwaysIncludeAll = 0x20,
  1173. BfOptionFlags_ReflectAssumeInstantiated = 0x40,
  1174. BfOptionFlags_ReflectBoxing = 0x80,
  1175. BfOptionFlags_ReflectStaticFields = 0x100,
  1176. BfOptionFlags_ReflectNonStaticFields = 0x200,
  1177. BfOptionFlags_ReflectStaticMethods = 0x400,
  1178. BfOptionFlags_ReflectNonStaticMethods = 0x800,
  1179. BfOptionFlags_ReflectConstructors = 0x1000,
  1180. BfOptionFlags_Reflect_MethodMask = BfOptionFlags_ReflectStaticMethods | BfOptionFlags_ReflectNonStaticMethods | BfOptionFlags_ReflectConstructors,
  1181. BfOptionFlags_Mask = 0xFFF
  1182. };
  1183. enum BfReflectKind
  1184. {
  1185. BfReflectKind_None = 0,
  1186. BfReflectKind_Type = 1,
  1187. BfReflectKind_NonStaticFields = 2,
  1188. BfReflectKind_StaticFields = 4,
  1189. BfReflectKind_DefaultConstructor = 8,
  1190. BfReflectKind_Constructors = 0x10,
  1191. BfReflectKind_StaticMethods = 0x20,
  1192. BfReflectKind_Methods = 0x40,
  1193. BfReflectKind_DynamicBoxing = 0x80,
  1194. BfReflectKind_User = 0x100,
  1195. BfReflectKind_All = 0x1FF,
  1196. BfReflectKind_ApplyToInnerTypes = 0x200
  1197. };
  1198. class BfTypeOptions
  1199. {
  1200. public:
  1201. struct MethodFilter
  1202. {
  1203. String mFilter;
  1204. BfOptionFlags mOrFlags;
  1205. BfOptionFlags mAndFlags;
  1206. };
  1207. public:
  1208. Array<String> mTypeFilters;
  1209. Array<String> mAttributeFilters;
  1210. Array<int> mMatchedIndices;
  1211. int mSIMDSetting;
  1212. int mOptimizationLevel;
  1213. int mEmitDebugInfo;
  1214. BfOptionFlags mAndFlags;
  1215. BfOptionFlags mOrFlags;
  1216. Array<MethodFilter> mReflectMethodFilters;
  1217. Array<MethodFilter> mReflectMethodAttributeFilters;
  1218. int mAllocStackTraceDepth;
  1219. public:
  1220. static int Apply(int val, int applyVal)
  1221. {
  1222. if (applyVal != -1)
  1223. return applyVal;
  1224. return val;
  1225. }
  1226. bool Apply(bool val, BfOptionFlags flags)
  1227. {
  1228. if (val)
  1229. return (mAndFlags & flags) != 0;
  1230. else
  1231. return (mOrFlags & flags) != 0;
  1232. }
  1233. bool HasReflectMethodFilters()
  1234. {
  1235. return !mReflectMethodFilters.IsEmpty() || !mReflectMethodAttributeFilters.IsEmpty();
  1236. }
  1237. };
  1238. enum BfFindTypeDefFlags
  1239. {
  1240. BfFindTypeDefFlag_None,
  1241. BfFindTypeDefFlag_AllowGlobal
  1242. };
  1243. class BfSystem
  1244. {
  1245. public:
  1246. int mPtrSize;
  1247. bool mIsResolveOnly;
  1248. CritSect mDataLock; // short-lived, hold only while active modifying data
  1249. // The following are protected by mDataLock:
  1250. Array<BfProject*> mProjects;
  1251. Array<BfProject*> mProjectDeleteQueue;
  1252. Array<BfParser*> mParsers;
  1253. Array<BfParser*> mParserDeleteQueue;
  1254. Array<BfTypeDef*> mTypeDefDeleteQueue;
  1255. Array<BfTypeOptions> mTypeOptions;
  1256. Array<BfTypeOptions> mMergedTypeOptions;
  1257. int mUpdateCnt;
  1258. bool mWorkspaceConfigChanged;
  1259. Val128 mWorkspaceConfigHash;
  1260. Array<BfCompiler*> mCompilers;
  1261. BfAtom* mGlobalsAtom;
  1262. BfAtom* mEmptyAtom;
  1263. BfAtom* mBfAtom;
  1264. CritSect mSystemLock; // long-lived, hold while compiling
  1265. int mYieldDisallowCount; // We can only yield lock when we are at 0
  1266. volatile int mCurSystemLockPri;
  1267. BfpThreadId mCurSystemLockThreadId;
  1268. volatile int mPendingSystemLockPri;
  1269. uint32 mYieldTickCount;
  1270. int mHighestYieldTime;
  1271. // The following are protected by mSystemLock - can only be accessed by the compiling thread
  1272. Dictionary<String, BfTypeDef*> mSystemTypeDefs;
  1273. BfTypeDefMap mTypeDefs;
  1274. bool mNeedsTypesHandledByCompiler;
  1275. BumpAllocator mAlloc;
  1276. int mAtomCreateIdx;
  1277. Dictionary<StringView, BfAtom*> mAtomMap;
  1278. Array<BfAtom*> mAtomGraveyard;
  1279. uint32 mAtomUpdateIdx;
  1280. int32 mTypeMapVersion; // Increment when we add any new types or namespaces
  1281. OwnedVector<BfMethodDef> mMethodGraveyard;
  1282. OwnedVector<BfFieldDef> mFieldGraveyard;
  1283. OwnedVector<BfDirectStrTypeReference> mDirectTypeRefs;
  1284. OwnedVector<BfRefTypeRef> mRefTypeRefs;
  1285. public:
  1286. BfTypeDef* mTypeVoid;
  1287. BfTypeDef* mTypeNullPtr;
  1288. BfTypeDef* mTypeSelf;
  1289. BfTypeDef* mTypeDot;
  1290. BfTypeDef* mTypeVar;
  1291. BfTypeDef* mTypeLet;
  1292. BfTypeDef* mTypeBool;
  1293. BfTypeDef* mTypeIntPtr;
  1294. BfTypeDef* mTypeUIntPtr;
  1295. BfTypeDef* mTypeIntUnknown;
  1296. BfTypeDef* mTypeUIntUnknown;
  1297. BfTypeDef* mTypeInt8;
  1298. BfTypeDef* mTypeUInt8;
  1299. BfTypeDef* mTypeInt16;
  1300. BfTypeDef* mTypeUInt16;
  1301. BfTypeDef* mTypeInt32;
  1302. BfTypeDef* mTypeUInt32;
  1303. BfTypeDef* mTypeInt64;
  1304. BfTypeDef* mTypeUInt64;
  1305. BfTypeDef* mTypeChar8;
  1306. BfTypeDef* mTypeChar16;
  1307. BfTypeDef* mTypeChar32;
  1308. BfTypeDef* mTypeSingle;
  1309. BfTypeDef* mTypeDouble;
  1310. BfDirectStrTypeReference* mDirectVoidTypeRef;
  1311. BfDirectStrTypeReference* mDirectBoolTypeRef;
  1312. BfDirectStrTypeReference* mDirectSelfTypeRef;
  1313. BfDirectStrTypeReference* mDirectSelfBaseTypeRef;
  1314. BfRefTypeRef* mDirectRefSelfBaseTypeRef;
  1315. BfDirectStrTypeReference* mDirectObjectTypeRef;
  1316. BfDirectStrTypeReference* mDirectStringTypeRef;
  1317. BfDirectStrTypeReference* mDirectIntTypeRef;
  1318. BfRefTypeRef* mDirectRefIntTypeRef;
  1319. BfDirectStrTypeReference* mDirectInt32TypeRef;
  1320. public:
  1321. BfSystem();
  1322. ~BfSystem();
  1323. BfAtom* GetAtom(const StringImpl& string);
  1324. BfAtom* FindAtom(const StringImpl& string); // Doesn't create a ref
  1325. BfAtom* FindAtom(const StringView& string); // Doesn't create a ref
  1326. void ReleaseAtom(BfAtom* atom);
  1327. void ProcessAtomGraveyard();
  1328. void RefAtomComposite(const BfAtomComposite& atomComposite);
  1329. void ReleaseAtomComposite(const BfAtomComposite& atomComposite);
  1330. void SanityCheckAtomComposite(const BfAtomComposite& atomComposite);
  1331. void TrackName(BfTypeDef* typeDef);
  1332. void UntrackName(BfTypeDef* typeDef);
  1333. bool ParseAtomComposite(const StringView& name, BfAtomComposite& composite, bool addRefs = false);
  1334. void CreateBasicTypes();
  1335. bool DoesLiteralFit(BfTypeCode typeCode, int64 value);
  1336. BfParser* CreateParser(BfProject* bfProject);
  1337. BfCompiler* CreateCompiler(bool isResolveOnly);
  1338. BfProject* GetProject(const StringImpl& projName);
  1339. BfTypeReference* GetTypeRefElement(BfTypeReference* typeRef);
  1340. BfTypeDef* FilterDeletedTypeDef(BfTypeDef* typeDef);
  1341. bool CheckTypeDefReference(BfTypeDef* typeDef, BfProject* project);
  1342. BfTypeDef* FindTypeDef(const BfAtomComposite& findName, int numGenericArgs = 0, BfProject* project = NULL, const Array<BfAtomComposite>& namespaceSearch = Array<BfAtomComposite>(), BfTypeDef** ambiguousTypeDef = NULL, BfFindTypeDefFlags flags = BfFindTypeDefFlag_None);
  1343. bool FindTypeDef(const BfAtomComposite& findName, int numGenericArgs, BfProject* project, const BfAtomComposite& checkNamespace, bool allowPrivate, BfTypeDefLookupContext* ctx);
  1344. BfTypeDef* FindTypeDef(const StringImpl& typeName, int numGenericArgs = 0, BfProject* project = NULL, const Array<BfAtomComposite>& namespaceSearch = Array<BfAtomComposite>(), BfTypeDef** ambiguousTypeDef = NULL, BfFindTypeDefFlags flags = BfFindTypeDefFlag_None);
  1345. BfTypeDef* FindTypeDef(const StringImpl& typeName, BfProject* project);
  1346. BfTypeDef* FindTypeDefEx(const StringImpl& typeName);
  1347. void FindFixitNamespaces(const StringImpl& typeName, int numGenericArgs, BfProject* project, std::set<String>& fixitNamespaces);
  1348. void RemoveTypeDef(BfTypeDef* typeDef);
  1349. //BfTypeDefMap::Iterator RemoveTypeDef(BfTypeDefMap::Iterator typeDefItr);
  1350. void AddNamespaceUsage(const BfAtomComposite& namespaceStr, BfProject* bfProject);
  1351. void RemoveNamespaceUsage(const BfAtomComposite& namespaceStr, BfProject* bfProject);
  1352. bool ContainsNamespace(const BfAtomComposite& namespaceStr, BfProject* bfProject);
  1353. void InjectNewRevision(BfTypeDef* typeDef);
  1354. void AddToCompositePartial(BfPassInstance* passInstance, BfTypeDef* compositeTypeDef, BfTypeDef* partialTypeDef);
  1355. void FinishCompositePartial(BfTypeDef* compositeTypeDef);
  1356. BfTypeDef* GetCombinedPartial(BfTypeDef* typeDef);
  1357. BfTypeDef* GetOuterTypeNonPartial(BfTypeDef* typeDef);
  1358. int GetGenericParamIdx(const Array<BfGenericParamDef*>& genericParams, const StringImpl& name);
  1359. int GetGenericParamIdx(const Array<BfGenericParamDef*>& genericParams, BfTypeReference* typeRef);
  1360. void StartYieldSection();
  1361. void CheckLockYield(); // Yields to a higher priority request
  1362. void SummarizeYieldSection();
  1363. void NotifyWillRequestLock(int priority);
  1364. void Lock(int priority);
  1365. void Unlock();
  1366. void AssertWeHaveLock();
  1367. void RemoveDeletedParsers();
  1368. void RemoveOldParsers();
  1369. void RemoveOldData();
  1370. void VerifyTypeDef(BfTypeDef* typeDef);
  1371. BfPassInstance* CreatePassInstance();
  1372. BfTypeOptions* GetTypeOptions(int optionsIdx);
  1373. bool HasTestProjects();
  1374. bool IsCompatibleCallingConvention(BfCallingConvention callConvA, BfCallingConvention callConvB);
  1375. };
  1376. class AutoDisallowYield
  1377. {
  1378. public:
  1379. BfSystem* mSystem;
  1380. bool mHeld;
  1381. public:
  1382. AutoDisallowYield(BfSystem* system)
  1383. {
  1384. mSystem = system;
  1385. mSystem->mYieldDisallowCount++;
  1386. mHeld = true;
  1387. }
  1388. ~AutoDisallowYield()
  1389. {
  1390. if (mHeld)
  1391. mSystem->mYieldDisallowCount--;
  1392. }
  1393. void Release()
  1394. {
  1395. BF_ASSERT(mHeld);
  1396. if (mHeld)
  1397. {
  1398. mHeld = false;
  1399. mSystem->mYieldDisallowCount--;
  1400. }
  1401. }
  1402. void Acquire()
  1403. {
  1404. BF_ASSERT(!mHeld);
  1405. if (!mHeld)
  1406. {
  1407. mHeld = true;
  1408. mSystem->mYieldDisallowCount++;
  1409. }
  1410. }
  1411. };
  1412. #ifdef _DEBUG
  1413. #ifdef BF_PLATFORM_WINDOWS
  1414. #define BF_WANTS_LOG
  1415. #define BF_WANTS_LOG_SYS
  1416. //#define BF_WANTS_LOG2
  1417. //#define BF_WANTS_LOG_CLANG
  1418. #define BF_WANTS_LOG_DBG
  1419. #define BF_WANTS_LOG_DBGEXPR
  1420. //#define BF_WANTS_LOG_CV
  1421. #endif
  1422. #else
  1423. //#define BF_WANTS_LOG
  1424. //#define BF_WANTS_LOG2
  1425. //#define BF_WANTS_LOG_CLANG
  1426. //#define BF_WANTS_LOG_DBGEXPR
  1427. //#define BF_WANTS_LOG_CV
  1428. //#define BF_WANTS_LOG_DBG
  1429. #endif
  1430. #ifdef BF_WANTS_LOG
  1431. #define BfLog(fmt, ...) DoBfLog(0, fmt, ##__VA_ARGS__)
  1432. #else
  1433. //#define BfLog(fmt) {} // Nothing
  1434. #define BfLog(fmt, ...) {} // Nothing
  1435. #endif
  1436. #ifdef BF_WANTS_LOG_SYS
  1437. #define BfLogSys(sys, fmt, ...) DoBfLog((sys)->mIsResolveOnly ? 1 : 2, fmt, ##__VA_ARGS__)
  1438. #define BfLogSysM(fmt, ...) DoBfLog(mSystem->mIsResolveOnly ? 1 : 2, fmt, ##__VA_ARGS__)
  1439. #else
  1440. #define BfLogSys(...) {} // Nothing
  1441. #define BfLogSysM(...) {} // Nothing
  1442. #endif
  1443. #ifdef BF_WANTS_LOG_CLANG
  1444. //#define BfLogClang(fmt) DoBfLog(fmt)
  1445. #define BfLogClang(fmt, ...) DoBfLog(0, fmt, ##__VA_ARGS__)
  1446. #else
  1447. #define BfLogClang(fmt, ...) {} // Nothing
  1448. #endif
  1449. #ifdef BF_WANTS_LOG_DBG
  1450. #define BfLogDbg(fmt, ...) DoBfLog(0, fmt, ##__VA_ARGS__)
  1451. #else
  1452. #define BfLogDbg(fmt, ...) {} // Nothing
  1453. #endif
  1454. #ifdef BF_WANTS_LOG_DBGEXPR
  1455. #define BfLogDbgExpr(fmt, ...) DoBfLog(0, fmt, ##__VA_ARGS__)
  1456. #else
  1457. #define BfLogDbgExpr(fmt, ...) {} // Nothing
  1458. #endif
  1459. #ifdef BF_WANTS_LOG2
  1460. #define BfLog2(fmt, ...) DoBfLog(0, fmt, ##__VA_ARGS__)
  1461. #else
  1462. #define BfLog2(fmt, ...) {} // Nothing
  1463. #endif
  1464. #ifdef BF_WANTS_LOG_CV
  1465. #define BfLogCv(fmt, ...) DoBfLog(0, fmt, ##__VA_ARGS__)
  1466. #else
  1467. #define BfLogCv(fmt, ...) {} // Nothing
  1468. #endif
  1469. void DoBfLog(int fileIdx, const char* fmt ...);
  1470. NS_BF_END
  1471. namespace std
  1472. {
  1473. template <>
  1474. struct hash<Beefy::BfAtomComposite>
  1475. {
  1476. size_t operator()(const Beefy::BfAtomComposite& composite) const
  1477. {
  1478. int curHash = 0;
  1479. for (int i = 0; i < (int)composite.mSize; i++)
  1480. curHash = ((curHash ^ (int)(intptr)composite.mParts[i]->mHash) << 5) - curHash;
  1481. return curHash;
  1482. }
  1483. };
  1484. template <>
  1485. struct hash<Beefy::BfMemberSetEntry>
  1486. {
  1487. size_t operator()(const Beefy::BfMemberSetEntry& entry) const
  1488. {
  1489. return std::hash<Beefy::String>()(entry.mMemberDef->mName);
  1490. }
  1491. };
  1492. }
  1493. namespace std
  1494. {
  1495. template<>
  1496. struct hash<Beefy::BfErrorEntry>
  1497. {
  1498. size_t operator()(const Beefy::BfErrorEntry& val) const
  1499. {
  1500. return val.GetHashCode();
  1501. }
  1502. };
  1503. }