BfSystem.cpp 99 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817
  1. //#include <direct.h>
  2. #include "BfSystem.h"
  3. #include "BfParser.h"
  4. #include "BfCompiler.h"
  5. #include "BfDefBuilder.h"
  6. #include "BeefySysLib/util/PerfTimer.h"
  7. #include "BeefySysLib/util/BeefPerf.h"
  8. #include "BeefySysLib/util/UTF8.h"
  9. #include "BfAutoComplete.h"
  10. #include "BfResolvePass.h"
  11. #include "MemReporter.h"
  12. #include "BfIRCodeGen.h"
  13. #include "BeefySysLib/util/AllocDebug.h"
  14. USING_NS_BF;
  15. using namespace llvm;
  16. #pragma warning(disable:4996)
  17. void Beefy::DoBfLog(int fileIdx, const char* fmt ...)
  18. {
  19. static int entryNum = 0;
  20. static bool onNewLine[10];
  21. entryNum++;
  22. static BfpFile* fp[10] = { NULL };
  23. static bool openedLog[10] = { false };
  24. if (!openedLog[fileIdx])
  25. {
  26. openedLog[fileIdx] = true;
  27. char exeName[512];
  28. int len = 512;
  29. BfpSystem_GetExecutablePath(exeName, &len, NULL);
  30. String dbgName = exeName;
  31. int dotPos = (int)dbgName.IndexOf('.');
  32. if (dotPos != -1)
  33. dbgName.RemoveToEnd(dotPos);
  34. dbgName += StrFormat("_%d.txt", fileIdx);
  35. fp[fileIdx] = BfpFile_Create(dbgName.c_str(), BfpFileCreateKind_CreateAlways, (BfpFileCreateFlags)(BfpFileCreateFlag_Write | BfpFileCreateFlag_NoBuffering | BfpFileCreateFlag_ShareRead), BfpFileAttribute_Normal, NULL);
  36. onNewLine[fileIdx] = true;
  37. }
  38. if (fp[fileIdx] == NULL)
  39. return;
  40. char lineStr[4096];
  41. int strOfs;
  42. int maxChars;
  43. if (onNewLine[fileIdx])
  44. {
  45. strOfs = sprintf(lineStr, "%d", entryNum) + 1;
  46. lineStr[strOfs - 1] = ' ';
  47. maxChars = 4095 - strOfs;
  48. }
  49. else
  50. {
  51. strOfs = 0;
  52. maxChars = 4095;
  53. }
  54. va_list argList;
  55. va_start(argList, fmt);
  56. #ifdef _WIN32
  57. int numChars = _vsnprintf(lineStr + strOfs, maxChars, fmt, argList);
  58. #else
  59. int numChars = vsnprintf(lineStr+ strOfs, maxChars, fmt, argList);
  60. #endif
  61. if (numChars <= maxChars)
  62. {
  63. if (strOfs + numChars > 0)
  64. {
  65. BfpFile_Write(fp[fileIdx], lineStr, strOfs + numChars, -1, NULL);
  66. if (lineStr[strOfs + numChars - 1] == '\n')
  67. onNewLine[fileIdx] = true;
  68. else
  69. onNewLine[fileIdx] = false;
  70. }
  71. else
  72. onNewLine[fileIdx] = false;
  73. return;
  74. }
  75. String aResult = vformat(fmt, argList);
  76. va_end(argList);
  77. if (onNewLine[fileIdx])
  78. {
  79. aResult = StrFormat("%d ", entryNum) + aResult;
  80. }
  81. if (aResult.EndsWith('\n'))
  82. onNewLine[fileIdx] = true;
  83. else
  84. onNewLine[fileIdx] = false;
  85. BfpFile_Write(fp[fileIdx], aResult.c_str(), aResult.length(), -1, NULL);
  86. }
  87. BfAtom::~BfAtom()
  88. {
  89. BF_ASSERT(mPrevNamesMap.IsEmpty());
  90. }
  91. void BfAtom::Ref()
  92. {
  93. mRefCount++;
  94. }
  95. // Val128 BfAtom::GetTypesHash()
  96. // {
  97. // if (mTypeData == NULL)
  98. // return 0;
  99. // if (mTypeData->mTypesHash.IsZero())
  100. // {
  101. // for (auto typeDef : mTypeData->mTypeDefs)
  102. // {
  103. // if (typeDef->mNextRevision != NULL)
  104. // {
  105. // HASH128_MIXIN(mTypeData->mTypesHash, typeDef->mNextRevision->mHash);
  106. // continue;
  107. // }
  108. //
  109. // // Use the typeDef's 'mHash' here - we don't want our hash to change when
  110. // // the internals of a typeDef changes, we just want it to change when
  111. // // we add or remove typeDefs of this given name
  112. // HASH128_MIXIN(mTypeData->mTypesHash, typeDef->mHash);
  113. // }
  114. // }
  115. // return mTypeData->mTypesHash;
  116. // }
  117. BfAtomComposite::BfAtomComposite()
  118. {
  119. mParts = NULL;
  120. mSize = 0;
  121. mAllocSize = 0;
  122. mOwns = false;
  123. }
  124. BfAtomComposite::BfAtomComposite(BfAtom* atom)
  125. {
  126. Set(&atom, 1, NULL, 0);
  127. }
  128. BfAtomComposite::BfAtomComposite(const BfAtomComposite& rhs)
  129. {
  130. mParts = NULL;
  131. mSize = 0;
  132. mAllocSize = 0;
  133. mOwns = false;
  134. if (rhs.mParts != NULL)
  135. Set(rhs.mParts, rhs.mSize, NULL, 0);
  136. }
  137. BfAtomComposite::BfAtomComposite(BfAtomComposite&& rhs)
  138. {
  139. if ((rhs.mOwns) || (rhs.mParts == NULL))
  140. {
  141. mParts = rhs.mParts;
  142. mSize = rhs.mSize;
  143. mAllocSize = rhs.mAllocSize;
  144. mOwns = rhs.mOwns;
  145. rhs.mParts = NULL;
  146. rhs.mSize = 0;
  147. rhs.mAllocSize = 0;
  148. rhs.mOwns = false;
  149. return;
  150. }
  151. mParts = NULL;
  152. mSize = 0;
  153. mAllocSize = 0;
  154. mOwns = false;
  155. if (rhs.mParts != NULL)
  156. Set(rhs.mParts, rhs.mSize, NULL, 0);
  157. }
  158. BfAtomComposite::BfAtomComposite(const BfAtomComposite& left, const BfAtomComposite& right)
  159. {
  160. mParts = NULL;
  161. mSize = 0;
  162. mAllocSize = 0;
  163. mOwns = false;
  164. Set(left.mParts, left.mSize, right.mParts, right.mSize);
  165. }
  166. BfAtomComposite::BfAtomComposite(const BfAtomComposite& left, BfAtom* right)
  167. {
  168. mParts = NULL;
  169. mSize = 0;
  170. mAllocSize = 0;
  171. mOwns = false;
  172. Set(left.mParts, left.mSize, &right, 1);
  173. }
  174. void BfAtomComposite::Set(const BfAtomComposite& left, const BfAtomComposite& right)
  175. {
  176. Set(left.mParts, left.mSize, right.mParts, right.mSize);
  177. }
  178. void BfAtomComposite::Set(BfAtom** atomsA, int countA, BfAtom** atomsB, int countB)
  179. {
  180. BfAtom** freeParts = NULL;
  181. if (countA + countB > mAllocSize)
  182. {
  183. if (mOwns) // Defer freeing incase we are referring to ourselves
  184. freeParts = mParts;
  185. mAllocSize = countA + countB;
  186. mParts = (BfAtom**)malloc(sizeof(BfAtom*) * mAllocSize);
  187. mOwns = true;
  188. }
  189. if (countA > 0)
  190. memcpy(mParts, atomsA, sizeof(BfAtom*) * countA);
  191. if (countB > 0)
  192. memcpy(mParts + countA, atomsB, sizeof(BfAtom*) * countB);
  193. mSize = countA + countB;
  194. if (freeParts != NULL)
  195. free(freeParts);
  196. }
  197. BfAtomComposite::~BfAtomComposite()
  198. {
  199. if (mOwns)
  200. free(mParts);
  201. }
  202. BfAtomComposite& BfAtomComposite::operator=(const BfAtomComposite& rhs)
  203. {
  204. Set(rhs.mParts, rhs.mSize, NULL, 0);
  205. return *this;
  206. }
  207. bool BfAtomComposite::operator==(const BfAtomComposite& other) const
  208. {
  209. if (mSize != other.mSize)
  210. return false;
  211. for (int i = 0; i < other.mSize; i++)
  212. if (mParts[i] != other.mParts[i])
  213. return false;
  214. return true;
  215. }
  216. bool BfAtomComposite::operator!=(const BfAtomComposite& other) const
  217. {
  218. return !(*this == other);
  219. }
  220. bool BfAtomComposite::IsValid() const
  221. {
  222. for (int i = 0; i < mSize; i++)
  223. if (mParts[i] == NULL)
  224. return false;
  225. return true;
  226. }
  227. bool BfAtomComposite::IsEmpty() const
  228. {
  229. return mSize == 0;
  230. }
  231. int BfAtomComposite::GetPartsCount() const
  232. {
  233. return mSize;
  234. }
  235. String BfAtomComposite::ToString() const
  236. {
  237. if (mSize == 0)
  238. return "";
  239. if (mSize == 1)
  240. return String(mParts[0]->mString);
  241. String retStr;
  242. for (int i = 0; i < mSize; i++)
  243. {
  244. if (i > 0)
  245. retStr += ".";
  246. retStr += mParts[i]->mString;
  247. }
  248. return retStr;
  249. }
  250. void BfAtomComposite::ToString(StringImpl& str) const
  251. {
  252. for (int i = 0; i < mSize; i++)
  253. {
  254. if (i > 0)
  255. str += ".";
  256. str += mParts[i]->mString;
  257. }
  258. }
  259. bool BfAtomComposite::StartsWith(const BfAtomComposite& other) const
  260. {
  261. if (mSize < other.mSize)
  262. return false;
  263. for (int i = 0; i < other.mSize; i++)
  264. if (mParts[i] != other.mParts[i])
  265. return false;
  266. return true;
  267. }
  268. bool BfAtomComposite::EndsWith(const BfAtomComposite& other) const
  269. {
  270. int ofs = mSize - other.mSize;
  271. if (ofs < 0)
  272. return false;
  273. for (int i = 0; i < other.mSize; i++)
  274. if (mParts[i + ofs] != other.mParts[i])
  275. return false;
  276. return true;
  277. }
  278. BfAtomComposite BfAtomComposite::GetSub(int start, int len) const
  279. {
  280. BfAtomComposite atomComposite;
  281. atomComposite.Set(mParts + start, len, NULL, 0);
  282. return atomComposite;
  283. }
  284. void BfAtomComposite::Reference(const BfAtomComposite & other)
  285. {
  286. if (!mOwns)
  287. {
  288. mParts = other.mParts;
  289. mSize = other.mSize;
  290. return;
  291. }
  292. Set(other.mParts, other.mSize, NULL, 0);
  293. }
  294. // Val128 BfAtomComposite::GetTypesHash()
  295. // {
  296. // Val128 hash;
  297. // for (int i = 0; i < mSize; i++)
  298. // {
  299. // auto atom = mParts[i];
  300. // if (atom->mRefCount == 0)
  301. // return 0; // 0 is our "error condition" when we're looking at a graveyard'ed atom
  302. // Val128 hashPart = atom->GetTypesHash();
  303. // if (hash.IsZero())
  304. // hash = hashPart;
  305. // else
  306. // HASH128_MIXIN(hash, hashPart);
  307. // }
  308. // return hash;
  309. // }
  310. uint32 BfAtomComposite::GetAtomUpdateIdx()
  311. {
  312. uint32 updateIdx = 0;
  313. for (int i = 0; i < mSize; i++)
  314. {
  315. auto atom = mParts[i];
  316. if (atom->mRefCount == 0)
  317. return 0; // 0 is our "error condition" when we're looking at a graveyard'ed atom
  318. updateIdx = BF_MAX(updateIdx, atom->mAtomUpdateIdx);
  319. }
  320. return updateIdx;
  321. }
  322. BfSizedAtomComposite::BfSizedAtomComposite()
  323. {
  324. mAllocSize = BF_ARRAY_COUNT(mInitialAlloc);
  325. mParts = mInitialAlloc;
  326. }
  327. BfSizedAtomComposite::~BfSizedAtomComposite()
  328. {
  329. if (mParts == mInitialAlloc)
  330. mParts = NULL;
  331. }
  332. //////////////////////////////////////////////////////////////////////////
  333. bool BfPropertyDef::HasExplicitInterface()
  334. {
  335. for (auto methodDef : mMethods)
  336. {
  337. if (methodDef->mExplicitInterface != NULL)
  338. return true;
  339. }
  340. return false;
  341. }
  342. BfAstNode * BfPropertyDef::GetRefNode()
  343. {
  344. BfPropertyDeclaration* propDecl = (BfPropertyDeclaration*)mFieldDeclaration;
  345. if ((propDecl != NULL) && (propDecl->mNameNode != NULL))
  346. return propDecl->mNameNode;
  347. return propDecl;
  348. }
  349. ///
  350. BfAstNode* BfMethodDef::GetRefNode()
  351. {
  352. if (mMethodType == BfMethodType_Operator)
  353. {
  354. BfOperatorDef* operatorDef = (BfOperatorDef*)this;
  355. if (operatorDef->mOperatorDeclaration->mOpTypeToken != NULL)
  356. return operatorDef->mOperatorDeclaration->mOpTypeToken;
  357. return operatorDef->mOperatorDeclaration->mOperatorToken;
  358. }
  359. if (auto methodDeclaration = GetMethodDeclaration())
  360. {
  361. if (auto ctorDecl = BfNodeDynCast<BfConstructorDeclaration>(methodDeclaration))
  362. return ctorDecl->mThisToken;
  363. if (methodDeclaration->mNameNode != NULL)
  364. return methodDeclaration->mNameNode;
  365. return methodDeclaration;
  366. }
  367. if (auto methodDeclaration = GetPropertyMethodDeclaration())
  368. {
  369. return methodDeclaration->mNameNode;
  370. }
  371. if (mDeclaringType != NULL)
  372. return mDeclaringType->GetRefNode();
  373. return NULL;
  374. }
  375. BfTokenNode* BfMethodDef::GetMutNode()
  376. {
  377. if (auto methodDeclaration = GetMethodDeclaration())
  378. return methodDeclaration->mMutSpecifier;
  379. if (auto propertyMethodDeclaration = GetMethodDeclaration())
  380. return propertyMethodDeclaration->mMutSpecifier;
  381. return NULL;
  382. }
  383. bool BfMethodDef::HasBody()
  384. {
  385. if (auto methodDeclaration = GetMethodDeclaration())
  386. return methodDeclaration->mBody != NULL;
  387. if (auto methodDeclaration = GetPropertyMethodDeclaration())
  388. {
  389. auto body = methodDeclaration->mBody;
  390. return (body != NULL) && (!BfNodeIsA<BfTokenNode>(body));
  391. }
  392. return false;
  393. }
  394. BfMethodDef::~BfMethodDef()
  395. {
  396. FreeMembers();
  397. }
  398. void BfMethodDef::Reset()
  399. {
  400. FreeMembers();
  401. }
  402. void BfMethodDef::FreeMembers()
  403. {
  404. for (auto param : mParams)
  405. delete param;
  406. mParams.Clear();
  407. for (auto genericParam : mGenericParams)
  408. delete genericParam;
  409. mGenericParams.Clear();
  410. }
  411. BfMethodDeclaration* BfMethodDef::GetMethodDeclaration()
  412. {
  413. return BfNodeDynCast<BfMethodDeclaration>(mMethodDeclaration);
  414. }
  415. BfPropertyMethodDeclaration* BfMethodDef::GetPropertyMethodDeclaration()
  416. {
  417. return BfNodeDynCast<BfPropertyMethodDeclaration>(mMethodDeclaration);
  418. }
  419. BfPropertyDeclaration* BfMethodDef::GetPropertyDeclaration()
  420. {
  421. auto propertyMethodDeclaration = BfNodeDynCast<BfPropertyMethodDeclaration>(mMethodDeclaration);
  422. if (propertyMethodDeclaration == NULL)
  423. return NULL;
  424. return propertyMethodDeclaration->mPropertyDeclaration;
  425. }
  426. bool BfMethodDef::IsEmptyPartial()
  427. {
  428. return mIsPartial && (mBody == NULL);
  429. }
  430. bool BfMethodDef::IsDefaultCtor()
  431. {
  432. return ((mMethodType == BfMethodType_Ctor) || (mMethodType == BfMethodType_CtorNoBody)) && (mParams.IsEmpty());
  433. }
  434. String BfMethodDef::ToString()
  435. {
  436. String methodText;
  437. if (mName.empty())
  438. {
  439. if (auto operatorDecl = BfNodeDynCast<BfOperatorDeclaration>(mMethodDeclaration))
  440. {
  441. methodText += "operator";
  442. if (operatorDecl->mIsConvOperator)
  443. {
  444. methodText += " ";
  445. GetMethodDeclaration()->mReturnType->ToString(methodText);
  446. }
  447. else if (operatorDecl->mOpTypeToken != NULL)
  448. operatorDecl->mOpTypeToken->ToString(methodText);
  449. }
  450. }
  451. else if (mMethodType == BfMethodType_Ctor)
  452. methodText += "this";
  453. else if (mMethodType == BfMethodType_Dtor)
  454. methodText += "~this";
  455. else
  456. methodText += mName;
  457. if (mMethodType == BfMethodType_Mixin)
  458. methodText += "!";
  459. if (mGenericParams.size() != 0)
  460. {
  461. methodText += "<";
  462. for (int genericParamIdx = 0; genericParamIdx < (int)mGenericParams.size(); genericParamIdx++)
  463. {
  464. if (genericParamIdx != 0)
  465. methodText += ", ";
  466. methodText += mGenericParams[genericParamIdx]->mName;
  467. }
  468. methodText += ">";
  469. }
  470. int visParamIdx = 0;
  471. methodText += "(";
  472. for (int paramIdx = 0; paramIdx < (int)mParams.size(); paramIdx++)
  473. {
  474. BfParameterDef* paramDef = mParams[paramIdx];
  475. if ((paramDef->mParamKind == BfParamKind_AppendIdx) || (paramDef->mParamKind == BfParamKind_ImplicitCapture))
  476. continue;
  477. if (visParamIdx > 0)
  478. methodText += ", ";
  479. if (paramDef->mParamKind == BfParamKind_Params)
  480. methodText += "params ";
  481. paramDef->mTypeRef->ToString(methodText);
  482. methodText += " ";
  483. methodText += paramDef->mName;
  484. if ((paramDef->mParamDeclaration != NULL) && (paramDef->mParamDeclaration->mInitializer != NULL))
  485. {
  486. methodText += " = " + paramDef->mParamDeclaration->mInitializer->ToString();
  487. }
  488. visParamIdx++;
  489. }
  490. methodText += ")";
  491. return methodText;
  492. }
  493. ///
  494. void BfTypeDef::Reset()
  495. {
  496. FreeMembers();
  497. Init();
  498. }
  499. void BfTypeDef::FreeMembers()
  500. {
  501. if (!mIsCombinedPartial)
  502. mSystem->RemoveNamespaceUsage(mNamespace, mProject);
  503. if (mName != NULL)
  504. {
  505. if (mName != mSystem->mEmptyAtom)
  506. {
  507. if (!mIsNextRevision)
  508. mSystem->UntrackName(this);
  509. mSystem->ReleaseAtom(mName);
  510. }
  511. mName = NULL;
  512. }
  513. if (mNameEx != NULL)
  514. {
  515. mSystem->ReleaseAtom(mNameEx);
  516. mNameEx = NULL;
  517. }
  518. for (auto genericParam : mGenericParamDefs)
  519. {
  520. // auto genericParamCopy = *genericParam;
  521. // BF_ASSERT(genericParam->mOwner != NULL);
  522. //
  523. // if (genericParam->mOwner == this)
  524. delete genericParam;
  525. }
  526. mGenericParamDefs.Clear();
  527. for (auto field : mFields)
  528. delete field;
  529. mFields.Clear();
  530. for (auto prop : mProperties)
  531. delete prop;
  532. mProperties.Clear();
  533. for (auto method : mMethods)
  534. delete method;
  535. mMethods.Clear();
  536. mNestedTypes.Clear();
  537. // mOperators are also in mMethods so we don't need to delete those specifically
  538. mOperators.Clear();
  539. for (auto& searchName : mNamespaceSearch)
  540. mSystem->ReleaseAtomComposite(searchName);
  541. mNamespaceSearch.Clear();
  542. mStaticSearch.Clear();
  543. for (auto allocNode : mDirectAllocNodes)
  544. delete allocNode;
  545. mDirectAllocNodes.Clear();
  546. mIsNextRevision = false;
  547. }
  548. void BfTypeDef::PopulateMemberSets()
  549. {
  550. if ((!mMethodSet.IsEmpty()) || (!mFieldSet.IsEmpty()) || (!mPropertySet.IsEmpty()))
  551. return;
  552. for (auto methodDef : mMethods)
  553. {
  554. BF_ASSERT(methodDef->mNextWithSameName == NULL);
  555. BfMemberSetEntry* entry;
  556. if (!mMethodSet.TryAdd(methodDef, &entry))
  557. {
  558. methodDef->mNextWithSameName = (BfMethodDef*)entry->mMemberDef;
  559. entry->mMemberDef = methodDef;
  560. }
  561. }
  562. for (auto fieldDef : mFields)
  563. {
  564. BF_ASSERT(fieldDef->mNextWithSameName == NULL);
  565. BfMemberSetEntry* entry;
  566. if (!mFieldSet.TryAdd(fieldDef, &entry))
  567. {
  568. fieldDef->mNextWithSameName = (BfFieldDef*)entry->mMemberDef;
  569. entry->mMemberDef = fieldDef;
  570. }
  571. }
  572. for (auto propDef : mProperties)
  573. {
  574. BF_ASSERT(propDef->mNextWithSameName == NULL);
  575. BfMemberSetEntry* entry;
  576. if (!mPropertySet.TryAdd(propDef, &entry))
  577. {
  578. propDef->mNextWithSameName = (BfPropertyDef*)entry->mMemberDef;
  579. entry->mMemberDef = propDef;
  580. }
  581. }
  582. }
  583. BfTypeDef::~BfTypeDef()
  584. {
  585. BfLogSysM("BfTypeDef::~BfTypeDef %08X\n", this);
  586. if (mNextRevision != NULL)
  587. delete mNextRevision;
  588. FreeMembers();
  589. if (mSource != NULL)
  590. {
  591. mSource->mRefCount--;
  592. BF_ASSERT(mSource->mRefCount >= 0);
  593. }
  594. }
  595. BfSource* BfTypeDef::GetLastSource()
  596. {
  597. if (mNextRevision != NULL)
  598. return mNextRevision->mSource;
  599. return mSource;
  600. }
  601. bool BfTypeDef::IsGlobalsContainer()
  602. {
  603. return (mIsStatic) && (mName == mSystem->mGlobalsAtom);
  604. }
  605. void BfTypeDef::RemoveGenericParamDef(BfGenericParamDef* genericParamDef)
  606. {
  607. BF_FATAL("Not used anymore");
  608. if (mGenericParamDefs.size() == 0)
  609. return;
  610. for (auto innerType : mNestedTypes)
  611. innerType->RemoveGenericParamDef(genericParamDef);
  612. if (mGenericParamDefs[0] == genericParamDef)
  613. {
  614. mGenericParamDefs.erase(mGenericParamDefs.begin());
  615. //if (genericParamDef->mOwner == this)
  616. delete genericParamDef;
  617. }
  618. }
  619. int BfTypeDef::GetSelfGenericParamCount()
  620. {
  621. if (mOuterType != NULL)
  622. return (int)mGenericParamDefs.size() - (int)mOuterType->mGenericParamDefs.size();
  623. return (int)mGenericParamDefs.size();
  624. }
  625. BfMethodDef* BfTypeDef::GetMethodByName(const StringImpl& name, int paramCount)
  626. {
  627. for (auto method : mMethods)
  628. {
  629. if ((name == method->mName) && ((paramCount == -1) || (paramCount == (int)method->mParams.size())))
  630. return method;
  631. }
  632. return NULL;
  633. }
  634. String BfTypeDef::ToString()
  635. {
  636. String typeName(mName->ToString());
  637. auto checkOuterTypeDef = mOuterType;
  638. while (checkOuterTypeDef != NULL)
  639. {
  640. typeName = checkOuterTypeDef->mName->ToString() + "." + typeName;
  641. checkOuterTypeDef = checkOuterTypeDef->mOuterType;
  642. }
  643. if (mGenericParamDefs.size() != 0)
  644. {
  645. typeName += "<";
  646. for (int genericParamIdx = 0; genericParamIdx < (int)mGenericParamDefs.size(); genericParamIdx++)
  647. {
  648. if (genericParamIdx > 0)
  649. typeName += ", ";
  650. typeName += mGenericParamDefs[genericParamIdx]->mName;
  651. }
  652. typeName += ">";
  653. }
  654. return typeName;
  655. }
  656. bool BfTypeDef::HasAutoProperty(BfPropertyDeclaration* propertyDeclaration)
  657. {
  658. if (mTypeCode == BfTypeCode_Interface)
  659. return false;
  660. if (propertyDeclaration->mTypeRef == NULL)
  661. return false;
  662. if ((propertyDeclaration->mVirtualSpecifier != NULL) && (propertyDeclaration->mVirtualSpecifier->GetToken() == BfToken_Abstract))
  663. return false;
  664. if (propertyDeclaration->mExternSpecifier != NULL)
  665. return false;
  666. for (auto methodDeclaration : propertyDeclaration->mMethods)
  667. {
  668. if (BfNodeDynCast<BfTokenNode>(methodDeclaration->mBody) != NULL)
  669. return true;
  670. }
  671. return false;
  672. }
  673. String BfTypeDef::GetAutoPropertyName(BfPropertyDeclaration* propertyDeclaration)
  674. {
  675. String name = "prop__";
  676. if (propertyDeclaration->IsA<BfIndexerDeclaration>())
  677. name += "indexer__";
  678. else if (propertyDeclaration->mNameNode != NULL)
  679. name += propertyDeclaration->mNameNode->ToString();
  680. return name;
  681. }
  682. BfAstNode* BfTypeDef::GetRefNode()
  683. {
  684. if ((mTypeDeclaration != NULL) && (mTypeDeclaration->mNameNode != NULL))
  685. return mTypeDeclaration->mNameNode;
  686. return mTypeDeclaration;
  687. }
  688. void BfTypeDef::ReportMemory(MemReporter* memReporter)
  689. {
  690. memReporter->Add(sizeof(BfTypeDef));
  691. memReporter->AddVec(mNamespaceSearch, false);
  692. memReporter->AddVec(mStaticSearch, false);
  693. memReporter->AddVecPtr("Fields", mFields, false);
  694. memReporter->AddVecPtr("Properties", mProperties, false);
  695. memReporter->BeginSection("Methods");
  696. memReporter->AddVecPtr(mMethods, false);
  697. for (auto methodDef : mMethods)
  698. {
  699. memReporter->AddVecPtr("Params", methodDef->mParams, false);
  700. memReporter->AddVecPtr(methodDef->mGenericParams, false);
  701. }
  702. memReporter->EndSection();
  703. memReporter->AddVecPtr(mOperators, false);
  704. memReporter->AddVecPtr(mGenericParamDefs, false);
  705. memReporter->AddHashSet(mMethodSet, false);
  706. memReporter->AddHashSet(mFieldSet, false);
  707. memReporter->AddHashSet(mPropertySet, false);
  708. memReporter->AddVec(mBaseTypes, false);
  709. memReporter->AddVec(mNestedTypes, false);
  710. memReporter->AddVec(mDirectAllocNodes, false);
  711. }
  712. bool BfTypeDef::NameEquals(BfTypeDef* otherTypeDef)
  713. {
  714. // We can't just check mFullnames, because a namespace of "A" with a type named "B.C" would match
  715. // a namespace of "A.B" with a type named "C"
  716. if (mNamespace.mSize != otherTypeDef->mNamespace.mSize)
  717. return false;
  718. return mFullName == otherTypeDef->mFullName;
  719. }
  720. bool BfTypeDef::HasSource(BfSource* source)
  721. {
  722. if (mNextRevision != NULL)
  723. return mNextRevision->HasSource(source);
  724. if (mSource == source)
  725. return true;
  726. for (auto partial : mPartials)
  727. if (partial->mSource == source)
  728. return true;
  729. return false;
  730. }
  731. //////////////////////////////////////////////////////////////////////////
  732. BfProject::BfProject()
  733. {
  734. mDisabled = false;
  735. mSingleModule = false;
  736. mTargetType = BfTargetType_BeefConsoleApplication;
  737. mBuildConfigChanged = false;
  738. mSingleModule = false;
  739. mAlwaysIncludeAll = false;
  740. mSystem = NULL;
  741. mIdx = -1;
  742. }
  743. BfProject::~BfProject()
  744. {
  745. BF_ASSERT(mNamespaces.size() == 0);
  746. BfLogSysM("Deleting project %p %s\n", this, mName.c_str());
  747. }
  748. bool BfProject::ContainsReference(BfProject* refProject)
  749. {
  750. if (refProject->mDisabled)
  751. return false;
  752. if (refProject == this)
  753. return true;
  754. for (int i = 0; i < (int)mDependencies.size(); i++)
  755. if (mDependencies[i] == refProject)
  756. return true;
  757. return false;
  758. }
  759. bool BfProject::ReferencesOrReferencedBy(BfProject* refProject)
  760. {
  761. return ContainsReference(refProject) || refProject->ContainsReference(this);
  762. }
  763. bool BfProject::IsTestProject()
  764. {
  765. return mTargetType == BfTargetType_BeefTest;
  766. }
  767. //////////////////////////////////////////////////////////////////////////
  768. BfErrorBase::~BfErrorBase()
  769. {
  770. }
  771. void BfErrorBase::SetSource(BfPassInstance* passInstance, BfSourceData* source)
  772. {
  773. mSource = source;
  774. if (mSource != NULL)
  775. {
  776. auto parserData = mSource->ToParserData();
  777. if (parserData != NULL)
  778. {
  779. passInstance->mSourceFileNameMap.TryAdd(mSource, parserData->mFileName);
  780. }
  781. }
  782. }
  783. //////////////////////////////////////////////////////////////////////////
  784. size_t BfErrorEntry::GetHashCode() const
  785. {
  786. HashContext hashCtx;
  787. hashCtx.Mixin(mError->mSrcStart);
  788. hashCtx.Mixin(mError->mSrcEnd);
  789. hashCtx.Mixin(mError->mSource);
  790. hashCtx.Mixin(mError->mIsWarning);
  791. hashCtx.Mixin(mError->mIsDeferred);
  792. return (size_t)hashCtx.Finish64();
  793. }
  794. bool BfErrorEntry::operator==(const BfErrorEntry& other) const
  795. {
  796. return (mError->mSrcStart == other.mError->mSrcStart) &&
  797. (mError->mSrcEnd == other.mError->mSrcEnd) &&
  798. (mError->mSource == other.mError->mSource) &&
  799. (mError->mIsWarning == other.mError->mIsWarning) &&
  800. (mError->mIsDeferred == other.mError->mIsDeferred);
  801. }
  802. //////////////////////////////////////////////////////////////////////////
  803. BfPassInstance::~BfPassInstance()
  804. {
  805. for (auto bfError : mErrors)
  806. delete bfError;
  807. }
  808. void BfPassInstance::ClearErrors()
  809. {
  810. mFailedIdx = 0;
  811. for (auto bfError : mErrors)
  812. delete bfError;
  813. mErrors.Clear();
  814. mOutStream.Clear();
  815. mLastWasDisplayed = false;
  816. mLastWasAdded = false;
  817. mIgnoreCount = 0;
  818. mWarningCount = 0;
  819. mDeferredErrorCount = 0;
  820. }
  821. bool BfPassInstance::HasFailed()
  822. {
  823. return mFailedIdx != 0;
  824. }
  825. bool BfPassInstance::HasMessages()
  826. {
  827. return !mErrors.IsEmpty();
  828. }
  829. void BfPassInstance::OutputLine(const StringImpl& str)
  830. {
  831. //OutputDebugStrF("%s\n", str.c_str());
  832. mOutStream.push_back(str);
  833. }
  834. bool BfPassInstance::PopOutString(String* outString)
  835. {
  836. if (mOutStream.size() == 0)
  837. return false;
  838. *outString = mOutStream.front();
  839. mOutStream.RemoveAt(0);
  840. return true;
  841. }
  842. bool BfPassInstance::WantsRangeRecorded(BfSourceData* bfSource, int srcIdx, int srcLen, bool isWarning, bool isDeferred)
  843. {
  844. if ((mFilterErrorsTo != NULL) && (bfSource != mFilterErrorsTo->mSourceData))
  845. return false;
  846. if (bfSource == NULL)
  847. return true;
  848. if (!mErrors.IsEmpty())
  849. {
  850. // If the last error had a range that was a subset of this one, then just keep the first error
  851. // This helps reduce cascading errors to their root cause
  852. auto lastError = mErrors.back();
  853. if ((lastError->mSource == bfSource) && (isWarning == lastError->mIsWarning) && (isDeferred == lastError->mIsDeferred) &&
  854. (lastError->mSrcStart >= srcIdx) && (lastError->mSrcEnd <= srcIdx + srcLen))
  855. return false;
  856. }
  857. // Don't record errors that have already occurred at this location
  858. BfErrorBase checkError;
  859. checkError.mIsWarning = isWarning;
  860. checkError.mIsDeferred = isDeferred;
  861. checkError.mSource = bfSource;
  862. checkError.mSrcStart = srcIdx;
  863. checkError.mSrcEnd = srcIdx + srcLen;
  864. if (mErrorSet.Contains(BfErrorEntry(&checkError)))
  865. return false;
  866. int prevCount = (int)mErrors.size();
  867. if (!isWarning)
  868. prevCount -= mWarningCount;
  869. if (!isDeferred)
  870. prevCount -= mDeferredErrorCount;
  871. if (prevCount > sMaxErrors)
  872. return false;
  873. return true;
  874. }
  875. bool BfPassInstance::WantsRangeDisplayed(BfSourceData* bfSource, int srcIdx, int srcLen, bool isWarning, bool isDeferred)
  876. {
  877. int prevDispCount = (int)mErrors.size();
  878. if (!isWarning)
  879. prevDispCount -= mWarningCount;
  880. if (!isDeferred)
  881. prevDispCount -= mDeferredErrorCount;
  882. if (prevDispCount > sMaxDisplayErrors)
  883. return false;
  884. auto bfParser = (bfSource == NULL) ? NULL : bfSource->ToParser();
  885. if (bfParser == NULL)
  886. return true;
  887. if (bfParser->mCursorIdx == -1)
  888. return !mTrimMessagesToCursor;
  889. if ((bfParser->mCursorIdx >= srcIdx) && (bfParser->mCursorIdx < srcIdx + srcLen))
  890. return true;
  891. return false;
  892. }
  893. void BfPassInstance::TrimSourceRange(BfSourceData* source, int startIdx, int& srcLen)
  894. {
  895. int prevEnd = startIdx + srcLen;
  896. int newEnd = startIdx;
  897. // End at a newline once we've found some non-whitespace characters
  898. bool foundNonWS = false;
  899. while (newEnd < prevEnd)
  900. {
  901. char c = source->mSrc[newEnd];
  902. if ((c == '\r') || (c == '\n'))
  903. {
  904. if (foundNonWS)
  905. break;
  906. }
  907. if ((!foundNonWS) && (!::iswspace((uint8)c)))
  908. {
  909. foundNonWS = true;
  910. }
  911. newEnd++;
  912. }
  913. srcLen = newEnd - startIdx;
  914. }
  915. bool BfPassInstance::HasLastFailedAt(BfAstNode* astNode)
  916. {
  917. if (mErrors.size() == 0)
  918. return false;
  919. auto lastError = mErrors.back();
  920. return (astNode != NULL) && (lastError->mSrcStart == astNode->GetSrcStart());
  921. }
  922. static void VisibleAdvance(const char* str, int strLength, int& idx)
  923. {
  924. while (true)
  925. {
  926. char c = str[idx];
  927. if ((uint8)c < 0xC0)
  928. {
  929. idx++;
  930. break;
  931. }
  932. int cLen = 0;
  933. uint32 c32 = u8_toucs(str + idx, strLength - idx, &cLen);
  934. idx += cLen;
  935. if (!UTF8IsCombiningMark(c32))
  936. break;
  937. }
  938. }
  939. void BfPassInstance::MessageAt(const StringImpl& msgPrefix, const StringImpl& error, BfSourceData* bfSource, int srcIdx, int srcLen, BfFailFlags flags)
  940. {
  941. BP_ZONE("BfPassInstance::MessageAt");
  942. auto bfParser = bfSource->ToParserData();
  943. if (bfParser == NULL)
  944. {
  945. OutputLine(error);
  946. return;
  947. }
  948. if (srcIdx == 0x7FFFFFFF)
  949. {
  950. OutputLine(error);
  951. return;
  952. }
  953. bool atEnd = false;
  954. if (srcIdx >= bfParser->mSrcLength)
  955. {
  956. srcIdx = bfParser->mSrcLength - 1;
  957. atEnd = true;
  958. }
  959. if (srcIdx < 0)
  960. {
  961. String lineStr = StrFormat("%s %s in %s", msgPrefix.c_str(), error.c_str(), bfParser->mFileName.c_str());
  962. OutputLine(lineStr);
  963. lineStr = msgPrefix + " \"" + String(bfParser->mSrc + srcIdx, srcLen) + "\"";
  964. OutputLine(lineStr);
  965. return;
  966. }
  967. int origSrcIdx = srcIdx;
  968. if (bfParser->mSrc[srcIdx] == '\n')
  969. srcIdx--;
  970. int lineNum = 0;
  971. int lineStart = 0;
  972. for (int i = 0; i < srcIdx; i++)
  973. {
  974. if (bfParser->mSrc[i] == '\n')
  975. {
  976. lineStart = i + 1;
  977. lineNum++;
  978. }
  979. }
  980. int lineChar = origSrcIdx - lineStart;
  981. bool endsWithPunctuation = false;
  982. int lastChar = error[(int)error.length() - 1];
  983. String formatStr;
  984. if ((lastChar == '.') || (lastChar == '?') || (lastChar == '!'))
  985. formatStr = "%s %s Line %d:%d in %s";
  986. else
  987. formatStr = "%s %s at line %d:%d in %s";
  988. OutputLine(StrFormat(formatStr.c_str(), msgPrefix.c_str(), error.c_str(), lineNum + 1, lineChar + 1, bfParser->mFileName.c_str()));
  989. StringT<256> lineStr = msgPrefix;
  990. lineStr.Append(' ');
  991. int spaceCount = 0;
  992. int tabCount = 0;
  993. bool showSpaces = (flags & BfFailFlag_ShowSpaceChars) != 0;
  994. auto _FlushSpacing = [&]
  995. {
  996. if (spaceCount > 1)
  997. lineStr += StrFormat("<%d SPACES>", spaceCount);
  998. else if (spaceCount == 1)
  999. lineStr.Append("<SPACE>");
  1000. spaceCount = 0;
  1001. if (tabCount > 1)
  1002. lineStr += StrFormat("<%d TABS>", tabCount);
  1003. else if (tabCount == 1)
  1004. lineStr.Append("<TAB>");
  1005. tabCount = 0;
  1006. };
  1007. for (int i = 0; i < 255; i++)
  1008. {
  1009. char c = bfParser->mSrc[lineStart + i];
  1010. if ((c == '\0') || (c == '\n') || (c == '\r'))
  1011. {
  1012. break;
  1013. }
  1014. else if (c == '\t')
  1015. {
  1016. if (showSpaces)
  1017. {
  1018. if (spaceCount > 0)
  1019. _FlushSpacing();
  1020. tabCount++;
  1021. //lineStr.Append("\xe2\x86\x92"); // Arrow \u2192
  1022. }
  1023. else
  1024. lineStr.Append(' ');
  1025. }
  1026. else if (c == ' ')
  1027. {
  1028. if (showSpaces)
  1029. {
  1030. if (tabCount > 0)
  1031. _FlushSpacing();
  1032. spaceCount++;
  1033. //lineStr.Append("\xc2\xb7"); // Dot \u00B7
  1034. }
  1035. else
  1036. lineStr.Append(' ');
  1037. }
  1038. else
  1039. {
  1040. _FlushSpacing();
  1041. showSpaces = false;
  1042. lineStr.Append(c);
  1043. }
  1044. }
  1045. _FlushSpacing();
  1046. OutputLine(lineStr);
  1047. /*char lineStr[256] = { 0 };
  1048. for (int i = 0; i < 255; i++)
  1049. {
  1050. char c = bfParser->mSrc[lineStart + i];
  1051. if ((c == '\0') || (c == '\n') || (c == '\r'))
  1052. {
  1053. lineStr[i] = 0;
  1054. break;
  1055. }
  1056. else if (c == '\t')
  1057. lineStr[i] = ' ';
  1058. else
  1059. lineStr[i] = c;
  1060. }
  1061. OutputLine(lineStr);*/
  1062. // Don't show '^^^^^^^^^' under the entire line
  1063. bool isFullUnderline = true;
  1064. for (int i = lineStart; i < srcIdx; i++)
  1065. {
  1066. char c = bfParser->mSrc[i];
  1067. if (!::isspace((uint8)c))
  1068. isFullUnderline = false;
  1069. }
  1070. if (isFullUnderline)
  1071. {
  1072. isFullUnderline = true;
  1073. for (int i = srcIdx; i < srcIdx + srcLen; VisibleAdvance(bfParser->mSrc, bfParser->mSrcLength, i))
  1074. {
  1075. char c = bfParser->mSrc[i];
  1076. if (c == '\n')
  1077. {
  1078. isFullUnderline = true;
  1079. break;
  1080. }
  1081. }
  1082. }
  1083. if (!isFullUnderline)
  1084. {
  1085. String pointerStr = msgPrefix;
  1086. pointerStr.Append(' ');
  1087. for (int i = lineStart; i < origSrcIdx; VisibleAdvance(bfParser->mSrc, bfParser->mSrcLength, i))
  1088. pointerStr += " ";
  1089. for (int i = srcIdx; i < srcIdx + srcLen; VisibleAdvance(bfParser->mSrc, bfParser->mSrcLength, i))
  1090. {
  1091. char c = bfParser->mSrc[i];
  1092. pointerStr += "^";
  1093. if (c == '\n')
  1094. break;
  1095. }
  1096. OutputLine(pointerStr);
  1097. }
  1098. }
  1099. BfError* BfPassInstance::FailAt(const StringImpl& error, BfSourceData* bfSource, int srcIdx, int srcLen, BfFailFlags flags)
  1100. {
  1101. BP_ZONE("BfPassInstance::FailAt");
  1102. mLastWasAdded = false;
  1103. mFailedIdx++;
  1104. if ((int) mErrors.size() >= sMaxErrors)
  1105. return NULL;
  1106. if (!WantsRangeRecorded(bfSource, srcIdx, srcLen, false))
  1107. return NULL;
  1108. TrimSourceRange(bfSource, srcIdx, srcLen);
  1109. BfError* errorVal = new BfError();
  1110. errorVal->mIsWarning = false;
  1111. errorVal->SetSource(this, bfSource);
  1112. errorVal->mIsAfter = false;
  1113. errorVal->mError = error;
  1114. errorVal->mSrcStart = srcIdx;
  1115. errorVal->mSrcEnd = srcIdx + srcLen;
  1116. //int checkEnd = srcIdx + srcLen;
  1117. for (int i = srcIdx; i < srcIdx + srcLen; i++)
  1118. {
  1119. char c = bfSource->mSrc[i];
  1120. if ((c == '\r') || (c == '\n'))
  1121. break;
  1122. errorVal->mSrcEnd = i + 1;
  1123. }
  1124. //errorVal->mSrcEnd = srcIdx + srcLen;
  1125. FixSrcStartAndEnd(bfSource, errorVal->mSrcStart, errorVal->mSrcEnd);
  1126. mErrorSet.Add(BfErrorEntry(errorVal));
  1127. mErrors.push_back(errorVal);
  1128. mLastWasAdded = true;
  1129. mLastWasDisplayed = WantsRangeDisplayed(bfSource, srcIdx, srcLen, false);
  1130. if (mLastWasDisplayed)
  1131. {
  1132. String errorStart = "ERROR";
  1133. /*if ((int)mErrors.size() > 1)
  1134. errorStart += StrFormat(" #%d", mErrors.size());*/
  1135. MessageAt(":error", errorStart + ": " + error, bfSource, srcIdx, srcLen, flags);
  1136. }
  1137. return errorVal;
  1138. }
  1139. void BfPassInstance::FixSrcStartAndEnd(BfSourceData* bfSource, int& startIdx, int& endIdx)
  1140. {
  1141. auto bfParser = bfSource->ToParserData();
  1142. if (bfParser == NULL)
  1143. return;
  1144. int spanLength = 0;
  1145. UTF8GetGraphemeClusterSpan(bfParser->mSrc, bfParser->mSrcLength, startIdx, startIdx, spanLength);
  1146. endIdx = BF_MAX(endIdx, startIdx + spanLength);
  1147. }
  1148. BfError* BfPassInstance::FailAfterAt(const StringImpl& error, BfSourceData* bfSource, int srcIdx)
  1149. {
  1150. BP_ZONE("BfPassInstance::FailAfterAt");
  1151. mFailedIdx++;
  1152. if ((int)mErrors.size() >= sMaxErrors)
  1153. return NULL;
  1154. auto bfParser = bfSource->ToParserData();
  1155. if (!WantsRangeRecorded(bfParser, srcIdx, 1, false))
  1156. return NULL;
  1157. // Go to start of UTF8 chunk
  1158. // int startIdx = srcIdx;
  1159. // int spanLenth = 0;
  1160. // UTF8GetGraphemeClusterSpan(bfParser->mSrc, bfParser->mOrigSrcLength, srcIdx, startIdx, spanLenth);
  1161. BfError* errorVal = new BfError();
  1162. errorVal->mIsWarning = false;
  1163. errorVal->SetSource(this, bfSource);
  1164. errorVal->mIsAfter = true;
  1165. errorVal->mError = error;
  1166. errorVal->mSrcStart = srcIdx;
  1167. errorVal->mSrcEnd = srcIdx + 1;
  1168. FixSrcStartAndEnd(bfSource, errorVal->mSrcStart, errorVal->mSrcEnd);
  1169. mErrorSet.Add(BfErrorEntry(errorVal));
  1170. mErrors.push_back(errorVal);
  1171. mLastWasDisplayed = WantsRangeDisplayed(bfParser, srcIdx - 1, 2, false);
  1172. if (mLastWasDisplayed)
  1173. {
  1174. String errorStart = "ERROR";
  1175. /*if ((int)mErrors.size() > 1)
  1176. errorStart += StrFormat(" #%d", mErrors.size());*/
  1177. MessageAt(":error", errorStart + ": " + error, bfParser, srcIdx + 1, 1);
  1178. }
  1179. return errorVal;
  1180. }
  1181. BfError* BfPassInstance::Fail(const StringImpl& error)
  1182. {
  1183. mFailedIdx++;
  1184. if ((int) mErrors.size() >= sMaxErrors)
  1185. return NULL;
  1186. BfError* errorVal = new BfError();
  1187. errorVal->mIsWarning = false;
  1188. errorVal->mSource = NULL;
  1189. errorVal->mIsAfter = false;
  1190. errorVal->mError = error;
  1191. errorVal->mSrcStart = 0;
  1192. errorVal->mSrcEnd = 0;
  1193. mErrors.push_back(errorVal);
  1194. mLastWasDisplayed = (int)mErrors.size() - mWarningCount - mDeferredErrorCount <= sMaxDisplayErrors;
  1195. if (mLastWasDisplayed)
  1196. {
  1197. String errorStart = "ERROR";
  1198. /*if ((int)mErrors.size() > 1)
  1199. errorStart += StrFormat(" #%d", mErrors.size());*/
  1200. OutputLine(errorStart + ": " + error);
  1201. }
  1202. return mErrors.back();
  1203. }
  1204. BfError* BfPassInstance::Fail(const StringImpl& error, BfAstNode* refNode)
  1205. {
  1206. BP_ZONE("BfPassInstance::Fail");
  1207. mFailedIdx++;
  1208. if ((refNode == NULL) || (refNode->IsTemporary()))
  1209. return Fail(error);
  1210. else if (refNode->IsA<BfBlock>())
  1211. return FailAt(error, refNode->GetSourceData(), refNode->GetSrcStart(), 1);
  1212. else
  1213. return FailAt(error, refNode->GetSourceData(), refNode->GetSrcStart(), refNode->GetSrcLength());
  1214. }
  1215. BfError* BfPassInstance::FailAfter(const StringImpl& error, BfAstNode* refNode)
  1216. {
  1217. BP_ZONE("BfPassInstance::FailAfter");
  1218. mFailedIdx++;
  1219. if ((refNode == NULL) || (refNode->IsTemporary()))
  1220. return Fail(error);
  1221. /*if (refNode->mNext != NULL)
  1222. {
  1223. for (int checkIdx = refNode->mSrcEnd; checkIdx < refNode->mNext->mSrcStart; checkIdx++)
  1224. {
  1225. if (refNode->mSource->mSrc[checkIdx] == '\n')
  1226. {
  1227. // Don't show a 'fail after' if it's on a new line
  1228. return FailAfterAt(error, refNode->mSource, refNode->mSrcEnd - 1);
  1229. }
  1230. }
  1231. return FailAt(error, refNode->mSource, refNode->mNext->mSrcStart);
  1232. }
  1233. else*/
  1234. return FailAfterAt(error, refNode->GetSourceData(), refNode->GetSrcEnd() - 1);
  1235. }
  1236. BfError* BfPassInstance::DeferFail(const StringImpl& error, BfAstNode* refNode)
  1237. {
  1238. mLastWasAdded = false;
  1239. mFailedIdx++;
  1240. if ((int)mErrors.size() >= sMaxErrors)
  1241. return NULL;
  1242. if (refNode == NULL)
  1243. {
  1244. return Fail(error);
  1245. }
  1246. if (!WantsRangeRecorded(refNode->GetSourceData(), refNode->GetSrcStart(), refNode->GetSrcLength(), false, true))
  1247. return NULL;
  1248. ++mDeferredErrorCount;
  1249. BfError* errorVal = new BfError();
  1250. errorVal->mIsWarning = false;
  1251. errorVal->mIsDeferred = true;
  1252. errorVal->SetSource(this, refNode->GetSourceData());
  1253. errorVal->mIsAfter = false;
  1254. errorVal->mError = error;
  1255. errorVal->mSrcStart = refNode->GetSrcStart();
  1256. errorVal->mSrcEnd = refNode->GetSrcEnd();
  1257. mErrors.push_back(errorVal);
  1258. mErrorSet.Add(BfErrorEntry(errorVal));
  1259. mLastWasAdded = true;
  1260. BF_ASSERT(!refNode->IsTemporary());
  1261. auto parser = errorVal->mSource->ToParserData();
  1262. mLastWasDisplayed = false;
  1263. return errorVal;
  1264. }
  1265. void BfPassInstance::SilentFail()
  1266. {
  1267. mFailedIdx++;
  1268. }
  1269. BfError* BfPassInstance::WarnAt(int warningNumber, const StringImpl& warning, BfSourceData* bfSource, int srcIdx, int srcLen)
  1270. {
  1271. mLastWasAdded = false;
  1272. if ((int) mErrors.size() >= sMaxErrors)
  1273. return NULL;
  1274. auto bfParser = bfSource->ToParserData();
  1275. if ((bfParser != NULL) && (warningNumber > 0) && (!bfParser->IsWarningEnabledAtSrcIndex(warningNumber, srcIdx)))
  1276. return NULL;
  1277. if (!WantsRangeRecorded(bfParser, srcIdx, srcLen, true))
  1278. return NULL;
  1279. TrimSourceRange(bfSource, srcIdx, srcLen);
  1280. BfError* errorVal = new BfError();
  1281. errorVal->mIsWarning = true;
  1282. errorVal->mWarningNumber = warningNumber;
  1283. errorVal->SetSource(this, bfSource);
  1284. errorVal->mIsAfter = false;
  1285. errorVal->mError = warning;
  1286. errorVal->mSrcStart = srcIdx;
  1287. errorVal->mSrcEnd = srcIdx + srcLen;
  1288. FixSrcStartAndEnd(bfSource, errorVal->mSrcStart, errorVal->mSrcEnd);
  1289. mErrorSet.Add(BfErrorEntry(errorVal));
  1290. mErrors.push_back(errorVal);
  1291. ++mWarningCount;
  1292. mLastWasAdded = true;
  1293. mLastWasDisplayed = WantsRangeDisplayed(bfParser, srcIdx, srcLen, true);
  1294. if (mLastWasDisplayed)
  1295. {
  1296. String errorStart = "WARNING";
  1297. if ((int)mErrors.size() > 1)
  1298. errorStart += StrFormat("(%d)", mErrors.size());
  1299. if (warningNumber > 0)
  1300. errorStart += StrFormat(": CS%04d", warningNumber);
  1301. MessageAt(":warn", errorStart + ": " + warning, bfParser, srcIdx);
  1302. }
  1303. return errorVal;
  1304. }
  1305. BfError* BfPassInstance::Warn(int warningNumber, const StringImpl& warning)
  1306. {
  1307. mLastWasAdded = false;
  1308. mLastWasDisplayed = (int)mErrors.size() <= sMaxDisplayErrors;
  1309. if (!mLastWasDisplayed)
  1310. return NULL;
  1311. (void)warningNumber;//CDH TODO is warningNumber meaningful here w/o context? n/a for now
  1312. OutputLine((":warn WARNING: " + warning).c_str());
  1313. return NULL;
  1314. }
  1315. BfError* BfPassInstance::Warn(int warningNumber, const StringImpl& warning, BfAstNode* refNode)
  1316. {
  1317. BP_ZONE("BfPassInstance::Warn");
  1318. mLastWasAdded = false;
  1319. mLastWasDisplayed = (int)mErrors.size() <= sMaxErrors;
  1320. if (!mLastWasDisplayed)
  1321. return NULL;
  1322. auto parser = refNode->GetSourceData()->ToParserData();
  1323. if (parser != NULL)
  1324. {
  1325. if (parser->IsUnwarnedAt(refNode))
  1326. {
  1327. mLastWasDisplayed = false;
  1328. return NULL;
  1329. }
  1330. }
  1331. if (refNode != NULL)
  1332. return WarnAt(warningNumber, warning, refNode->GetSourceData(), refNode->GetSrcStart(), refNode->GetSrcLength());
  1333. else
  1334. return Warn(warningNumber, warning);
  1335. }
  1336. BfError* BfPassInstance::WarnAfter(int warningNumber, const StringImpl& warning, BfAstNode* refNode)
  1337. {
  1338. auto parser = refNode->GetSourceData()->ToParserData();
  1339. if (parser != NULL)
  1340. {
  1341. if (parser->IsUnwarnedAt(refNode))
  1342. {
  1343. mLastWasDisplayed = false;
  1344. return NULL;
  1345. }
  1346. }
  1347. return WarnAt(warningNumber, warning, refNode->GetSourceData(), refNode->GetSrcEnd());
  1348. }
  1349. BfError* BfPassInstance::MoreInfoAt(const StringImpl& info, BfSourceData* bfSource, int srcIdx, int srcLen, BfFailFlags flags)
  1350. {
  1351. String msgPrefix;
  1352. if (!mLastWasDisplayed)
  1353. {
  1354. if (mLastWasAdded)
  1355. {
  1356. auto lastError = mErrors.back();
  1357. BfMoreInfo* moreInfo = new BfMoreInfo();
  1358. moreInfo->mInfo = info;
  1359. moreInfo->SetSource(this, bfSource);
  1360. moreInfo->mSrcStart = srcIdx;
  1361. moreInfo->mSrcEnd = srcIdx + srcLen;
  1362. if (lastError->mIsWarning)
  1363. msgPrefix = ":warn";
  1364. else
  1365. msgPrefix = ":error";
  1366. lastError->mMoreInfo.push_back(moreInfo);
  1367. }
  1368. return NULL;
  1369. }
  1370. MessageAt(msgPrefix, " > " + info, bfSource, srcIdx, srcLen, flags);
  1371. return NULL;
  1372. }
  1373. BfError* BfPassInstance::MoreInfo(const StringImpl& info)
  1374. {
  1375. String outText;
  1376. if (!mLastWasDisplayed)
  1377. {
  1378. if (mLastWasAdded)
  1379. {
  1380. auto lastError = mErrors.back();
  1381. BfMoreInfo* moreInfo = new BfMoreInfo();
  1382. moreInfo->mInfo = info;
  1383. moreInfo->mSource = NULL;
  1384. moreInfo->mSrcStart = -1;
  1385. moreInfo->mSrcEnd = -1;
  1386. if (lastError->mIsWarning)
  1387. outText = ":warn ";
  1388. else
  1389. outText = ":error ";
  1390. lastError->mMoreInfo.push_back(moreInfo);
  1391. }
  1392. return NULL;
  1393. }
  1394. outText += info;
  1395. OutputLine(outText);
  1396. return NULL;
  1397. }
  1398. BfError* BfPassInstance::MoreInfo(const StringImpl& info, BfAstNode* refNode)
  1399. {
  1400. if (refNode == NULL)
  1401. return MoreInfo(info);
  1402. else
  1403. return MoreInfoAt(info, refNode->GetSourceData(), refNode->GetSrcStart(), refNode->GetSrcLength());
  1404. }
  1405. BfError* BfPassInstance::MoreInfoAfter(const StringImpl& info, BfAstNode* refNode)
  1406. {
  1407. return MoreInfoAt(info, refNode->GetSourceData(), refNode->GetSrcEnd(), 1);
  1408. }
  1409. void BfPassInstance::TryFlushDeferredError()
  1410. {
  1411. // This can happen in the case of an internal compiler error, where we believe we've satisfied
  1412. // generic constraints but we generate an error on the specialization but not the unspecialized version
  1413. bool hasDisplayedError = false;
  1414. for (int pass = 0; pass < 2; pass++)
  1415. {
  1416. for (auto& error : mErrors)
  1417. {
  1418. if (!error->mIsWarning)
  1419. {
  1420. if (!error->mIsDeferred)
  1421. hasDisplayedError = true;
  1422. else if (pass == 1)
  1423. {
  1424. MessageAt(":error", "ERROR: " + error->mError, error->mSource, error->mSrcStart, error->mSrcEnd - error->mSrcStart);
  1425. for (auto moreInfo : error->mMoreInfo)
  1426. {
  1427. if (moreInfo->mSource != NULL)
  1428. MessageAt(":error", " > " + moreInfo->mInfo, moreInfo->mSource, moreInfo->mSrcStart, moreInfo->mSrcEnd - moreInfo->mSrcStart);
  1429. else
  1430. OutputLine(":error" + moreInfo->mInfo);
  1431. }
  1432. }
  1433. }
  1434. }
  1435. if ((pass == 0) && (hasDisplayedError))
  1436. break;
  1437. }
  1438. }
  1439. void BfPassInstance::WriteErrorSummary()
  1440. {
  1441. if (mErrors.size() > 0)
  1442. {
  1443. String msg = StrFormat(":med Errors: %d.", mErrors.size() - mWarningCount - mIgnoreCount);
  1444. if (mWarningCount > 0)
  1445. msg += StrFormat(" Warnings: %d.", mWarningCount);
  1446. if ((int)mErrors.size() > sMaxDisplayErrors)
  1447. msg += StrFormat(" Only the first %d are displayed.", sMaxDisplayErrors);
  1448. OutputLine(msg);
  1449. }
  1450. }
  1451. //////////////////////////////////////////////////////////////////////////
  1452. void BfReportMemory();
  1453. BfSystem::BfSystem()
  1454. {
  1455. BP_ZONE("BfSystem::BfSystem");
  1456. mUpdateCnt = 0;
  1457. if (gPerfManager == NULL)
  1458. gPerfManager = new PerfManager();
  1459. //gPerfManager->StartRecording();
  1460. mAtomUpdateIdx = 0;
  1461. mAtomCreateIdx = 0;
  1462. mTypeMapVersion = 1;
  1463. CreateBasicTypes();
  1464. mPtrSize = 4;
  1465. mCurSystemLockPri = -1;
  1466. mYieldDisallowCount = 0;
  1467. mPendingSystemLockPri = -1;
  1468. mCurSystemLockThreadId = 0;
  1469. mYieldTickCount = 0;
  1470. mHighestYieldTime = 0;
  1471. mNeedsTypesHandledByCompiler = false;
  1472. mWorkspaceConfigChanged = false;
  1473. mIsResolveOnly = false;
  1474. mEmptyAtom = GetAtom("");
  1475. mBfAtom = GetAtom("bf");
  1476. mGlobalsAtom = GetAtom("@");
  1477. mTypeDot = NULL;
  1478. if (gBfParserCache == NULL)
  1479. gBfParserCache = new BfParserCache();
  1480. gBfParserCache->mRefCount++;
  1481. BfAstTypeInfo::Init();
  1482. mDirectVoidTypeRef = mDirectTypeRefs.Alloc();
  1483. mDirectVoidTypeRef->Init("void");
  1484. mDirectBoolTypeRef = mDirectTypeRefs.Alloc();
  1485. mDirectBoolTypeRef->Init("bool");
  1486. mDirectSelfTypeRef = mDirectTypeRefs.Alloc();
  1487. mDirectSelfTypeRef->Init("Self");
  1488. mDirectSelfBaseTypeRef = mDirectTypeRefs.Alloc();
  1489. mDirectSelfBaseTypeRef->Init("SelfBase");
  1490. mDirectRefSelfBaseTypeRef = mRefTypeRefs.Alloc();
  1491. mDirectRefSelfBaseTypeRef->mElementType = mDirectSelfBaseTypeRef;
  1492. mDirectRefSelfBaseTypeRef->mRefToken = NULL;
  1493. mDirectObjectTypeRef = mDirectTypeRefs.Alloc();
  1494. mDirectObjectTypeRef->Init("System.Object");
  1495. mDirectStringTypeRef = mDirectTypeRefs.Alloc();
  1496. mDirectStringTypeRef->Init("System.String");
  1497. mDirectIntTypeRef = mDirectTypeRefs.Alloc();
  1498. mDirectIntTypeRef->Init("int");
  1499. mDirectRefIntTypeRef = mRefTypeRefs.Alloc();
  1500. mDirectRefIntTypeRef->mElementType = mDirectIntTypeRef;
  1501. mDirectRefIntTypeRef->mRefToken = NULL;
  1502. mDirectInt32TypeRef = mDirectTypeRefs.Alloc();
  1503. mDirectInt32TypeRef->Init("int32");
  1504. }
  1505. BfSystem::~BfSystem()
  1506. {
  1507. BP_ZONE("BfSystem::~BfSystem");
  1508. BfLogSys(this, "Deleting BfSystem...\n");
  1509. BfReportMemory();
  1510. //gPerfManager->StopRecording();
  1511. //gPerfManager->DbgPrint();
  1512. for (auto& typeItr : mSystemTypeDefs)
  1513. delete typeItr.mValue;
  1514. for (auto typeDef : mTypeDefs)
  1515. delete typeDef;
  1516. mTypeDefs.Clear();
  1517. for (auto typeDef : mTypeDefDeleteQueue)
  1518. delete typeDef;
  1519. {
  1520. BP_ZONE("Deleting parsers");
  1521. for (auto parser : mParsers)
  1522. {
  1523. delete parser;
  1524. }
  1525. }
  1526. for (auto project : mProjects)
  1527. delete project;
  1528. for (auto project : mProjectDeleteQueue)
  1529. delete project;
  1530. ReleaseAtom(mGlobalsAtom);
  1531. ReleaseAtom(mBfAtom);
  1532. ReleaseAtom(mEmptyAtom);
  1533. ProcessAtomGraveyard();
  1534. BF_ASSERT(mAtomMap.size() == 0);
  1535. gBfParserCache->mRefCount--;
  1536. if (gBfParserCache->mRefCount == 0)
  1537. {
  1538. delete gBfParserCache;
  1539. gBfParserCache = NULL;
  1540. }
  1541. BfLogSys(this, "After ~BfSystem\n");
  1542. BfReportMemory();
  1543. }
  1544. #define SYSTEM_TYPE(typeVar, name, typeCode) \
  1545. typeVar = typeDef = new BfTypeDef(); \
  1546. typeDef->mSystem = this; \
  1547. typeDef->mName = GetAtom(name); \
  1548. typeDef->mName->mIsSystemType = true; \
  1549. TrackName(typeDef); \
  1550. typeDef->mTypeCode = typeCode; \
  1551. typeDef->mHash = typeCode + 1000; \
  1552. mSystemTypeDefs[name] = typeDef;
  1553. BfAtom* BfSystem::GetAtom(const StringImpl& string)
  1554. {
  1555. StringView* stringPtr = NULL;
  1556. BfAtom* atom = NULL;
  1557. BfAtom** atomPtr = NULL;
  1558. if (mAtomMap.TryAdd(string, &stringPtr, &atomPtr))
  1559. {
  1560. atom = new BfAtom();
  1561. *atomPtr = atom;
  1562. stringPtr->mPtr = strdup(string.c_str());
  1563. #ifdef _DEBUG
  1564. for (int i = 0; i < (int)string.length(); i++)
  1565. {
  1566. BF_ASSERT(string[i] != '.'); // Should be a composite
  1567. }
  1568. #endif
  1569. mAtomCreateIdx++;
  1570. atom->mIsSystemType = false;
  1571. atom->mAtomUpdateIdx = ++mAtomUpdateIdx;
  1572. atom->mString = *stringPtr;
  1573. atom->mRefCount = 1;
  1574. atom->mHash = 0;
  1575. for (char c : string)
  1576. atom->mHash = ((atom->mHash ^ c) << 5) - atom->mHash;
  1577. BfLogSys(this, "Atom Allocated %p %s\n", atom, string.c_str());
  1578. return atom;
  1579. }
  1580. else
  1581. atom = *atomPtr;
  1582. atom->Ref();
  1583. return atom;
  1584. }
  1585. BfAtom* BfSystem::FindAtom(const StringImpl& string)
  1586. {
  1587. BfAtom** atomPtr = NULL;
  1588. if (mAtomMap.TryGetValueWith(string, &atomPtr))
  1589. return *atomPtr;
  1590. return NULL;
  1591. }
  1592. BfAtom* BfSystem::FindAtom(const StringView& string)
  1593. {
  1594. BfAtom** atomPtr = NULL;
  1595. if (mAtomMap.TryGetValue(string, &atomPtr))
  1596. return *atomPtr;
  1597. return NULL;
  1598. }
  1599. void BfSystem::ReleaseAtom(BfAtom* atom)
  1600. {
  1601. if (--atom->mRefCount == 0)
  1602. {
  1603. mAtomGraveyard.push_back(atom);
  1604. return;
  1605. }
  1606. BF_ASSERT(atom->mRefCount > 0);
  1607. // Sanity check
  1608. BF_ASSERT(atom->mRefCount < 1000000);
  1609. }
  1610. void BfSystem::ProcessAtomGraveyard()
  1611. {
  1612. // We need this set, as it's possible to have multiple of the same entry in the graveyard
  1613. // if we ref and then deref again
  1614. HashSet<BfAtom*> deletedAtoms;
  1615. for (auto atom : mAtomGraveyard)
  1616. {
  1617. if (deletedAtoms.Contains(atom))
  1618. continue;
  1619. BF_ASSERT(atom->mRefCount >= 0);
  1620. if (atom->mRefCount == 0)
  1621. {
  1622. deletedAtoms.Add(atom);
  1623. auto itr = mAtomMap.Remove(atom->mString);
  1624. delete atom->mString.mPtr;
  1625. delete atom;
  1626. }
  1627. }
  1628. mAtomGraveyard.Clear();
  1629. }
  1630. bool BfSystem::ParseAtomComposite(const StringView& name, BfAtomComposite& composite, bool addRefs)
  1631. {
  1632. bool isValid = true;
  1633. SizedArray<BfAtom*, 6> parts;
  1634. BF_ASSERT(composite.mSize == 0);
  1635. int lastDot = -1;
  1636. for (int i = 0; i <= (int)name.mLength; i++)
  1637. {
  1638. if ((i == (int)name.mLength) || (name[i] == '.'))
  1639. {
  1640. BfAtom* atom;
  1641. if (addRefs)
  1642. atom = GetAtom(String(name.mPtr + lastDot + 1, i - lastDot - 1));
  1643. else
  1644. atom = FindAtom(StringView(name.mPtr + lastDot + 1, i - lastDot - 1));
  1645. if (atom == NULL)
  1646. isValid = false;
  1647. parts.push_back(atom);
  1648. lastDot = i;
  1649. }
  1650. }
  1651. if (!parts.IsEmpty())
  1652. composite.Set(&parts[0], (int)parts.size(), NULL, 0);
  1653. return isValid;
  1654. }
  1655. void BfSystem::RefAtomComposite(const BfAtomComposite& atomComposite)
  1656. {
  1657. for (int i = 0; i < atomComposite.mSize; i++)
  1658. {
  1659. auto part = atomComposite.mParts[i];
  1660. if (part != NULL)
  1661. part->Ref();
  1662. }
  1663. }
  1664. void BfSystem::ReleaseAtomComposite(const BfAtomComposite& atomComposite)
  1665. {
  1666. for (int i = 0; i < atomComposite.mSize; i++)
  1667. {
  1668. auto part = atomComposite.mParts[i];
  1669. if (part != NULL)
  1670. ReleaseAtom(part);
  1671. }
  1672. }
  1673. void BfSystem::SanityCheckAtomComposite(const BfAtomComposite& atomComposite)
  1674. {
  1675. for (int i = 0; i < atomComposite.mSize; i++)
  1676. {
  1677. auto part = atomComposite.mParts[i];
  1678. BF_ASSERT(part != NULL);
  1679. BF_ASSERT(part->mRefCount > 0);
  1680. BF_ASSERT(part->mRefCount < 1000000);
  1681. }
  1682. }
  1683. void BfSystem::TrackName(BfTypeDef* typeDef)
  1684. {
  1685. for (int i = 0; i < (int)typeDef->mFullName.mSize - 1; i++)
  1686. {
  1687. auto prevAtom = typeDef->mFullName.mParts[i];
  1688. auto atom = typeDef->mFullName.mParts[i + 1];
  1689. int* countPtr;
  1690. if (atom->mPrevNamesMap.TryAdd(prevAtom, NULL, &countPtr))
  1691. {
  1692. *countPtr = 1;
  1693. }
  1694. else
  1695. {
  1696. (*countPtr)++;
  1697. }
  1698. }
  1699. }
  1700. void BfSystem::UntrackName(BfTypeDef* typeDef)
  1701. {
  1702. BfAtom* nameAtom = typeDef->mName;
  1703. if (nameAtom != mEmptyAtom)
  1704. {
  1705. nameAtom->mAtomUpdateIdx = ++mAtomUpdateIdx;
  1706. }
  1707. if (!typeDef->mIsCombinedPartial)
  1708. {
  1709. for (int i = 0; i < (int)typeDef->mFullName.mSize - 1; i++)
  1710. {
  1711. auto prevAtom = typeDef->mFullName.mParts[i];
  1712. auto atom = typeDef->mFullName.mParts[i + 1];
  1713. auto itr = atom->mPrevNamesMap.Find(prevAtom);
  1714. if (itr != atom->mPrevNamesMap.end())
  1715. {
  1716. int& count = itr->mValue;
  1717. if (--count == 0)
  1718. {
  1719. atom->mPrevNamesMap.Remove(itr);
  1720. }
  1721. }
  1722. else
  1723. {
  1724. BF_DBG_FATAL("Unable to untrack name");
  1725. }
  1726. }
  1727. }
  1728. }
  1729. void BfSystem::CreateBasicTypes()
  1730. {
  1731. BfTypeDef* typeDef;
  1732. SYSTEM_TYPE(mTypeVoid, "void", BfTypeCode_None);
  1733. SYSTEM_TYPE(mTypeNullPtr, "null", BfTypeCode_NullPtr);
  1734. SYSTEM_TYPE(mTypeSelf, "Self", BfTypeCode_Self);
  1735. SYSTEM_TYPE(mTypeVar, "var", BfTypeCode_Var);
  1736. SYSTEM_TYPE(mTypeLet, "let", BfTypeCode_Let);
  1737. SYSTEM_TYPE(mTypeBool, "bool", BfTypeCode_Boolean);
  1738. SYSTEM_TYPE(mTypeInt8, "int8", BfTypeCode_Int8);
  1739. SYSTEM_TYPE(mTypeUInt8, "uint8", BfTypeCode_UInt8);
  1740. SYSTEM_TYPE(mTypeInt16, "int16", BfTypeCode_Int16);
  1741. SYSTEM_TYPE(mTypeUInt16, "uint16", BfTypeCode_UInt16);
  1742. SYSTEM_TYPE(mTypeInt32, "int32", BfTypeCode_Int32);
  1743. SYSTEM_TYPE(mTypeUInt32, "uint32", BfTypeCode_UInt32);
  1744. SYSTEM_TYPE(mTypeInt64, "int64", BfTypeCode_Int64);
  1745. SYSTEM_TYPE(mTypeUInt64, "uint64", BfTypeCode_UInt64);
  1746. SYSTEM_TYPE(mTypeIntPtr, "int", BfTypeCode_IntPtr);
  1747. SYSTEM_TYPE(mTypeUIntPtr, "uint", BfTypeCode_UIntPtr);
  1748. SYSTEM_TYPE(mTypeIntUnknown, "int literal", BfTypeCode_IntUnknown);
  1749. SYSTEM_TYPE(mTypeUIntUnknown, "uint literal", BfTypeCode_UIntUnknown);
  1750. SYSTEM_TYPE(mTypeChar8, "char8", BfTypeCode_Char8);
  1751. SYSTEM_TYPE(mTypeChar16, "char16", BfTypeCode_Char16);
  1752. SYSTEM_TYPE(mTypeChar32, "char32", BfTypeCode_Char32);
  1753. SYSTEM_TYPE(mTypeSingle, "float", BfTypeCode_Single);
  1754. SYSTEM_TYPE(mTypeDouble, "double", BfTypeCode_Double);
  1755. }
  1756. bool BfSystem::DoesLiteralFit(BfTypeCode typeCode, int64 value)
  1757. {
  1758. if (typeCode == BfTypeCode_IntPtr)
  1759. typeCode = (mPtrSize == 4) ? BfTypeCode_Int32 : BfTypeCode_Int64;
  1760. if (typeCode == BfTypeCode_UIntPtr)
  1761. typeCode = (mPtrSize == 4) ? BfTypeCode_UInt32 : BfTypeCode_UInt64;
  1762. switch (typeCode)
  1763. {
  1764. case BfTypeCode_Int8:
  1765. return (value >= -0x80) && (value < 0x80);
  1766. case BfTypeCode_Int16:
  1767. return (value >= -0x8000) && (value < 0x8000);
  1768. case BfTypeCode_Int32:
  1769. return (value >= -0x80000000LL) && (value < 0x80000000LL);
  1770. case BfTypeCode_Int64:
  1771. return true;
  1772. case BfTypeCode_UInt8:
  1773. return (value >= 0) && (value < 0x100);
  1774. case BfTypeCode_UInt16:
  1775. return (value >= 0) && (value < 0x10000);
  1776. case BfTypeCode_UInt32:
  1777. return (value >= 0) && (value < 0x100000000LL);
  1778. case BfTypeCode_UInt64:
  1779. return (value >= 0);
  1780. default: break;
  1781. }
  1782. return false;
  1783. }
  1784. BfParser* BfSystem::CreateParser(BfProject* bfProject)
  1785. {
  1786. AutoCrit crit(mDataLock);
  1787. auto parser = new BfParser(this, bfProject);
  1788. mParsers.push_back(parser);
  1789. BfLogSys(this, "CreateParser: %p\n", parser);
  1790. return parser;
  1791. }
  1792. BfCompiler* BfSystem::CreateCompiler(bool isResolveOnly)
  1793. {
  1794. auto compiler = new BfCompiler(this, isResolveOnly);
  1795. mCompilers.push_back(compiler);
  1796. if (mIsResolveOnly)
  1797. BF_ASSERT(isResolveOnly);
  1798. if (isResolveOnly)
  1799. mIsResolveOnly = true;
  1800. return compiler;
  1801. }
  1802. BfProject* BfSystem::GetProject(const StringImpl& projName)
  1803. {
  1804. for (auto project : mProjects)
  1805. if (project->mName == projName)
  1806. return project;
  1807. return NULL;
  1808. }
  1809. BfTypeReference* BfSystem::GetTypeRefElement(BfTypeReference* typeRef)
  1810. {
  1811. if (auto elementedType = BfNodeDynCast<BfElementedTypeRef>(typeRef))
  1812. return GetTypeRefElement(elementedType->mElementType);
  1813. return (BfTypeReference*)typeRef;
  1814. }
  1815. void BfSystem::AddNamespaceUsage(const BfAtomComposite& namespaceStr, BfProject* bfProject)
  1816. {
  1817. if (namespaceStr.IsEmpty())
  1818. return;
  1819. if (namespaceStr.GetPartsCount() > 1)
  1820. {
  1821. BfAtomComposite subComposite;
  1822. subComposite.Set(namespaceStr.mParts, namespaceStr.mSize - 1, NULL, 0);
  1823. AddNamespaceUsage(subComposite, bfProject);
  1824. }
  1825. int* valuePtr = NULL;
  1826. if (bfProject->mNamespaces.TryAdd(namespaceStr, NULL, &valuePtr))
  1827. {
  1828. BfLogSys(this, "BfSystem::AddNamespaceUsage created %s in project: %p\n", namespaceStr.ToString().c_str(), bfProject);
  1829. *valuePtr = 1;
  1830. mTypeMapVersion++;
  1831. }
  1832. else
  1833. (*valuePtr)++;
  1834. }
  1835. void BfSystem::RemoveNamespaceUsage(const BfAtomComposite& namespaceStr, BfProject* bfProject)
  1836. {
  1837. if (namespaceStr.IsEmpty())
  1838. return;
  1839. if (namespaceStr.GetPartsCount() > 1)
  1840. {
  1841. BfAtomComposite subComposite;
  1842. subComposite.Set(namespaceStr.mParts, namespaceStr.mSize - 1, NULL, 0);
  1843. RemoveNamespaceUsage(subComposite, bfProject);
  1844. }
  1845. int* valuePtr = NULL;
  1846. bfProject->mNamespaces.TryGetValue(namespaceStr, &valuePtr);
  1847. BF_ASSERT(valuePtr != NULL);
  1848. (*valuePtr)--;
  1849. if (*valuePtr == 0)
  1850. {
  1851. BfLogSys(this, "BfSystem::RemoveNamespaceUsage removed %s in project: %p\n", namespaceStr.ToString().c_str(), bfProject);
  1852. bfProject->mNamespaces.Remove(namespaceStr);
  1853. mTypeMapVersion++;
  1854. }
  1855. }
  1856. bool BfSystem::ContainsNamespace(const BfAtomComposite& namespaceStr, BfProject* bfProject)
  1857. {
  1858. if (bfProject == NULL)
  1859. {
  1860. for (auto checkProject : mProjects)
  1861. {
  1862. if (checkProject->mNamespaces.ContainsKey(namespaceStr))
  1863. return true;
  1864. }
  1865. return false;
  1866. }
  1867. if (bfProject->mNamespaces.ContainsKey(namespaceStr))
  1868. return true;
  1869. for (auto depProject : bfProject->mDependencies)
  1870. if (depProject->mNamespaces.ContainsKey(namespaceStr))
  1871. return true;
  1872. return false;
  1873. }
  1874. BfTypeDef* BfSystem::FilterDeletedTypeDef(BfTypeDef* typeDef)
  1875. {
  1876. if ((typeDef != NULL) && (typeDef->mDefState == BfTypeDef::DefState_Deleted))
  1877. return NULL;
  1878. return typeDef;
  1879. }
  1880. bool BfSystem::CheckTypeDefReference(BfTypeDef* typeDef, BfProject* project)
  1881. {
  1882. if (project == NULL)
  1883. return !typeDef->mProject->mDisabled;
  1884. if (typeDef->mProject == NULL)
  1885. return true;
  1886. return project->ContainsReference(typeDef->mProject);
  1887. }
  1888. BfTypeDef* BfSystem::FindTypeDef(const BfAtomComposite& findName, int numGenericArgs, BfProject* project, const Array<BfAtomComposite>& namespaceSearch, BfTypeDef** ambiguousTypeDef)
  1889. {
  1890. if (findName.GetPartsCount() == 1)
  1891. {
  1892. BfTypeDef** typeDefPtr = NULL;
  1893. if (mSystemTypeDefs.TryGetValueWith(findName.mParts[0]->mString, &typeDefPtr))
  1894. return FilterDeletedTypeDef(*typeDefPtr);
  1895. }
  1896. // This searched globals, but we were already doing that down below at the LAST step. Right?
  1897. BfTypeDef* foundTypeDef = NULL;
  1898. BfAtomComposite qualifiedFindName;
  1899. int foundPri = (int)0x80000000;
  1900. for (int namespaceIdx = 0; namespaceIdx <= (int) namespaceSearch.size(); namespaceIdx++)
  1901. {
  1902. int curNamespacePri = 0;
  1903. if (namespaceIdx < (int)namespaceSearch.size())
  1904. {
  1905. auto& namespaceDeclaration = namespaceSearch[namespaceIdx];
  1906. qualifiedFindName.Set(namespaceDeclaration, findName);
  1907. }
  1908. else
  1909. {
  1910. qualifiedFindName = findName;
  1911. }
  1912. auto itr = mTypeDefs.TryGet(qualifiedFindName);
  1913. while (itr)
  1914. {
  1915. BfTypeDef* typeDef = *itr;
  1916. if ((typeDef->mIsPartial) || (typeDef->IsGlobalsContainer()))
  1917. {
  1918. itr.MoveToNextHashMatch();
  1919. continue;
  1920. }
  1921. if ((typeDef->mFullName == qualifiedFindName) && (CheckTypeDefReference(typeDef, project)))
  1922. {
  1923. int curPri = curNamespacePri;
  1924. if (typeDef->mGenericParamDefs.size() != numGenericArgs)
  1925. {
  1926. // Still allow SOME match even if we put in the wrong number of generic args
  1927. curPri -= 10000;
  1928. }
  1929. if ((curPri > foundPri) || (foundTypeDef == NULL))
  1930. {
  1931. foundTypeDef = typeDef;
  1932. if (ambiguousTypeDef != NULL)
  1933. *ambiguousTypeDef = NULL;
  1934. foundPri = curPri;
  1935. }
  1936. else if (curPri == foundPri)
  1937. {
  1938. if ((ambiguousTypeDef != NULL) && (!typeDef->mIsPartial))
  1939. *ambiguousTypeDef = typeDef;
  1940. }
  1941. }
  1942. itr.MoveToNextHashMatch();
  1943. }
  1944. }
  1945. // Didn't match the correct number of generic params, but let the compiler complain
  1946. return FilterDeletedTypeDef(foundTypeDef);
  1947. }
  1948. bool BfSystem::FindTypeDef(const BfAtomComposite& findName, int numGenericArgs, BfProject* project, const BfAtomComposite& checkNamespace, bool allowPrivate, BfTypeDefLookupContext* ctx)
  1949. {
  1950. BfAtomComposite const* qualifiedFindNamePtr;
  1951. BfAtomComposite qualifiedFindName;
  1952. BfAtom* tempData[16];
  1953. if (checkNamespace.IsEmpty())
  1954. {
  1955. if ((findName.mSize == 1) && (findName.mParts[0]->mIsSystemType))
  1956. {
  1957. BfTypeDef** typeDefPtr = NULL;
  1958. if (mSystemTypeDefs.TryGetValueWith(findName.mParts[0]->mString, &typeDefPtr))
  1959. {
  1960. ctx->mBestPri = 0x7FFFFFFF;
  1961. ctx->mBestTypeDef = FilterDeletedTypeDef(*typeDefPtr);
  1962. }
  1963. return true;
  1964. }
  1965. qualifiedFindNamePtr = &findName;
  1966. }
  1967. else
  1968. {
  1969. qualifiedFindName.mAllocSize = 16;
  1970. qualifiedFindName.mParts = tempData;
  1971. qualifiedFindName.Set(checkNamespace, findName);
  1972. qualifiedFindNamePtr = &qualifiedFindName;
  1973. }
  1974. BfProtection minProtection = allowPrivate ? BfProtection_Private : BfProtection_Protected;
  1975. bool hadMatch = false;
  1976. auto itr = mTypeDefs.TryGet(*qualifiedFindNamePtr);
  1977. while (itr)
  1978. {
  1979. BfTypeDef* typeDef = *itr;
  1980. if ((typeDef->mIsPartial) ||
  1981. (typeDef->mDefState == BfTypeDef::DefState_Deleted))
  1982. {
  1983. itr.MoveToNextHashMatch();
  1984. continue;
  1985. }
  1986. if ((typeDef->mFullName == *qualifiedFindNamePtr) && (CheckTypeDefReference(typeDef, project)))
  1987. {
  1988. int curPri = 0;
  1989. if (typeDef->mProtection < minProtection)
  1990. curPri -= 1;
  1991. if (typeDef->IsGlobalsContainer())
  1992. curPri -= 2;
  1993. if (typeDef->mGenericParamDefs.size() != numGenericArgs)
  1994. {
  1995. // Still allow SOME match even if we put in the wrong number of generic args
  1996. curPri -= 4;
  1997. }
  1998. if ((curPri > ctx->mBestPri) || (ctx->mBestTypeDef == NULL))
  1999. {
  2000. ctx->mBestTypeDef = typeDef;
  2001. ctx->mAmbiguousTypeDef = NULL;
  2002. ctx->mBestPri = curPri;
  2003. hadMatch = true;
  2004. }
  2005. else if (curPri == ctx->mBestPri)
  2006. {
  2007. ctx->mAmbiguousTypeDef = typeDef;
  2008. }
  2009. }
  2010. itr.MoveToNextHashMatch();
  2011. }
  2012. if (qualifiedFindName.mParts == tempData)
  2013. qualifiedFindName.mParts = NULL;
  2014. return hadMatch;
  2015. }
  2016. BfTypeDef* BfSystem::FindTypeDef(const StringImpl& typeName, int numGenericArgs, BfProject* project, const Array<BfAtomComposite>& namespaceSearch, BfTypeDef** ambiguousTypeDef)
  2017. {
  2018. BfAtomComposite qualifiedFindName;
  2019. BfAtom* tempData[16];
  2020. qualifiedFindName.mAllocSize = 16;
  2021. qualifiedFindName.mParts = tempData;
  2022. BfTypeDef* result = NULL;
  2023. if (ParseAtomComposite(typeName, qualifiedFindName))
  2024. result = FindTypeDef(qualifiedFindName, numGenericArgs, project, namespaceSearch, ambiguousTypeDef);
  2025. if (qualifiedFindName.mParts == tempData)
  2026. qualifiedFindName.mParts = NULL;
  2027. return result;
  2028. }
  2029. BfTypeDef * BfSystem::FindTypeDef(const StringImpl& typeName, BfProject* project)
  2030. {
  2031. String findName;
  2032. int firstChevIdx = -1;
  2033. int chevDepth = 0;
  2034. int numGenericArgs = 0;
  2035. for (int i = 0; i < (int)typeName.length(); i++)
  2036. {
  2037. char c = typeName[i];
  2038. if (c == '<')
  2039. {
  2040. if (firstChevIdx == -1)
  2041. firstChevIdx = i;
  2042. chevDepth++;
  2043. }
  2044. else if (c == '>')
  2045. {
  2046. chevDepth--;
  2047. }
  2048. else if (c == ',')
  2049. {
  2050. if (chevDepth == 1)
  2051. numGenericArgs++;
  2052. }
  2053. }
  2054. if (firstChevIdx != -1)
  2055. findName = typeName.Substring(0, firstChevIdx);
  2056. else
  2057. findName = typeName;
  2058. return FindTypeDef(typeName, numGenericArgs, project);
  2059. }
  2060. BfTypeDef* BfSystem::FindTypeDefEx(const StringImpl& fullTypeName)
  2061. {
  2062. int colonPos = (int)fullTypeName.IndexOf(':');
  2063. if (colonPos == -1)
  2064. return NULL;
  2065. auto project = GetProject(fullTypeName.Substring(0, colonPos));
  2066. if (project == NULL)
  2067. return NULL;
  2068. int numGenericArgs = 0;
  2069. String typeName = fullTypeName.Substring(colonPos + 1);
  2070. int tildePos = (int)typeName.IndexOf('`');
  2071. if (tildePos != -1)
  2072. {
  2073. numGenericArgs = atoi(typeName.c_str() + tildePos + 1);
  2074. typeName.RemoveToEnd(tildePos);
  2075. }
  2076. return FindTypeDef(typeName, numGenericArgs, project);
  2077. }
  2078. void BfSystem::FindFixitNamespaces(const StringImpl& typeName, int numGenericArgs, BfProject* project, std::set<String>& fixitNamespaces)
  2079. {
  2080. BfAtomComposite findName;
  2081. if (!ParseAtomComposite(typeName, findName))
  2082. return;
  2083. // The algorithm assumes the first (or only) part of the BfAtomComposite is a type name, and finds a type with that matching
  2084. // name and then adds its namespace to the fixitNamespaces
  2085. for (auto typeDef : mTypeDefs)
  2086. {
  2087. if ((typeDef->mName == findName.mParts[0]) &&
  2088. (CheckTypeDefReference(typeDef, project)) &&
  2089. ((numGenericArgs == -1) || (typeDef->mGenericParamDefs.size() == numGenericArgs)))
  2090. {
  2091. String outerName;
  2092. if (typeDef->mOuterType != NULL)
  2093. {
  2094. outerName += "static ";
  2095. outerName += typeDef->mOuterType->mFullName.ToString();
  2096. }
  2097. else
  2098. outerName = typeDef->mNamespace.ToString();
  2099. fixitNamespaces.insert(outerName);
  2100. }
  2101. }
  2102. }
  2103. void BfSystem::RemoveTypeDef(BfTypeDef* typeDef)
  2104. {
  2105. BF_ASSERT(typeDef->mDefState == BfTypeDef::DefState_Deleted);
  2106. // mTypeDef is already locked by the system lock
  2107. mTypeDefs.Remove(typeDef);
  2108. AutoCrit autoCrit(mDataLock);
  2109. mTypeDefDeleteQueue.push_back(typeDef);
  2110. mTypeMapVersion++;
  2111. }
  2112. void BfSystem::InjectNewRevision(BfTypeDef* typeDef)
  2113. {
  2114. BfLogSys(this, "InjectNewRevision from %p (decl:%p) into %p (decl:%p)\n", typeDef->mNextRevision, typeDef->mNextRevision->mTypeDeclaration, typeDef, typeDef->mTypeDeclaration);
  2115. bool setDeclaringType = !typeDef->mIsCombinedPartial;
  2116. auto nextTypeDef = typeDef->mNextRevision;
  2117. for (auto prevProperty : typeDef->mProperties)
  2118. delete prevProperty;
  2119. typeDef->mProperties = nextTypeDef->mProperties;
  2120. if (setDeclaringType)
  2121. for (auto prop : typeDef->mProperties)
  2122. prop->mDeclaringType = typeDef;
  2123. nextTypeDef->mProperties.Clear();
  2124. if ((typeDef->mDefState != BfTypeDef::DefState_Signature_Changed) &&
  2125. (typeDef->mDefState != BfTypeDef::DefState_New))
  2126. {
  2127. BF_ASSERT(typeDef->mMethods.size() == nextTypeDef->mMethods.size());
  2128. for (auto prop : typeDef->mProperties)
  2129. {
  2130. for (int methodIdx = 0; methodIdx < (int)prop->mMethods.size(); methodIdx++)
  2131. prop->mMethods[methodIdx] = typeDef->mMethods[prop->mMethods[methodIdx]->mIdx];
  2132. }
  2133. for (int opIdx = 0; opIdx < (int)typeDef->mOperators.size(); opIdx++)
  2134. {
  2135. typeDef->mOperators[opIdx] = (BfOperatorDef*)typeDef->mMethods[typeDef->mOperators[opIdx]->mIdx];
  2136. }
  2137. // Remap methods in-place to previous revision's method list
  2138. for (int methodIdx = 0; methodIdx < (int)typeDef->mMethods.size(); methodIdx++)
  2139. {
  2140. auto methodDef = typeDef->mMethods[methodIdx];
  2141. auto nextMethodDef = nextTypeDef->mMethods[methodIdx];
  2142. bool codeChanged = nextMethodDef->mFullHash != methodDef->mFullHash;
  2143. for (auto genericParam : methodDef->mGenericParams)
  2144. delete genericParam;
  2145. for (auto param : methodDef->mParams)
  2146. delete param;
  2147. if (nextMethodDef->mMethodType == BfMethodType_Operator)
  2148. {
  2149. auto operatorDef = (BfOperatorDef*)methodDef;
  2150. auto nextOperatorDef = (BfOperatorDef*)nextMethodDef;
  2151. *operatorDef = *nextOperatorDef;
  2152. if (setDeclaringType)
  2153. operatorDef->mDeclaringType = typeDef;
  2154. }
  2155. else
  2156. {
  2157. *methodDef = *nextMethodDef;
  2158. if (setDeclaringType)
  2159. methodDef->mDeclaringType = typeDef;
  2160. }
  2161. if (codeChanged)
  2162. methodDef->mCodeChanged = true;
  2163. nextMethodDef->mParams.Clear();
  2164. nextMethodDef->mGenericParams.Clear();
  2165. }
  2166. // Leave typeDef->mDtorDef
  2167. }
  2168. else
  2169. {
  2170. typeDef->mOperators = nextTypeDef->mOperators;
  2171. nextTypeDef->mOperators.Clear();
  2172. for (auto prevMethod : typeDef->mMethods)
  2173. {
  2174. delete prevMethod;
  2175. }
  2176. typeDef->mMethods = nextTypeDef->mMethods;
  2177. if (setDeclaringType)
  2178. for (auto method : typeDef->mMethods)
  2179. method->mDeclaringType = typeDef;
  2180. nextTypeDef->mMethods.Clear();
  2181. typeDef->mDtorDef = nextTypeDef->mDtorDef;
  2182. }
  2183. for (auto fieldDef : typeDef->mFields)
  2184. fieldDef->mNextWithSameName = NULL;
  2185. for (auto propDef : typeDef->mProperties)
  2186. propDef->mNextWithSameName = NULL;
  2187. for (auto methodDef : typeDef->mMethods)
  2188. methodDef->mNextWithSameName = NULL;
  2189. if (typeDef->mSource != NULL)
  2190. typeDef->mSource->mRefCount--;
  2191. typeDef->mSource = nextTypeDef->mSource;
  2192. typeDef->mSource->mRefCount++;
  2193. typeDef->mPartialIdx = nextTypeDef->mPartialIdx;
  2194. typeDef->mTypeDeclaration = nextTypeDef->mTypeDeclaration;
  2195. typeDef->mHash = nextTypeDef->mHash;
  2196. typeDef->mSignatureHash = nextTypeDef->mSignatureHash;
  2197. typeDef->mFullHash = nextTypeDef->mFullHash;
  2198. typeDef->mInlineHash = nextTypeDef->mInlineHash;
  2199. typeDef->mNestDepth = nextTypeDef->mNestDepth;
  2200. typeDef->mOuterType = nextTypeDef->mOuterType;
  2201. //typeDef->mOuterType = nextTypeDef->mOuterType;
  2202. typeDef->mNamespace = nextTypeDef->mNamespace;
  2203. BF_ASSERT(typeDef->mName == nextTypeDef->mName);
  2204. //typeDef->mName = nextTypeDef->mName;
  2205. BF_ASSERT(typeDef->mNameEx == nextTypeDef->mNameEx);
  2206. //typeDef->mNameEx = nextTypeDef->mNameEx;
  2207. //typeDef->mFullName = nextTypeDef->mFullName;
  2208. typeDef->mProtection = nextTypeDef->mProtection;
  2209. if ((typeDef->mTypeCode != BfTypeCode_Extension) && (!typeDef->mIsCombinedPartial))
  2210. BF_ASSERT(nextTypeDef->mTypeCode != BfTypeCode_Extension);
  2211. typeDef->mTypeCode = nextTypeDef->mTypeCode;
  2212. typeDef->mIsAlwaysInclude = nextTypeDef->mIsAlwaysInclude;
  2213. typeDef->mIsNoDiscard = nextTypeDef->mIsNoDiscard;
  2214. typeDef->mIsPartial = nextTypeDef->mIsPartial;
  2215. typeDef->mIsExplicitPartial = nextTypeDef->mIsExplicitPartial;
  2216. //mPartialUsed
  2217. typeDef->mIsCombinedPartial = nextTypeDef->mIsCombinedPartial;
  2218. typeDef->mIsDelegate = nextTypeDef->mIsDelegate;
  2219. typeDef->mIsFunction = nextTypeDef->mIsFunction;
  2220. typeDef->mIsClosure = nextTypeDef->mIsClosure;
  2221. typeDef->mIsAbstract = nextTypeDef->mIsAbstract;
  2222. typeDef->mIsConcrete = nextTypeDef->mIsConcrete;
  2223. typeDef->mIsStatic = nextTypeDef->mIsStatic;
  2224. typeDef->mHasAppendCtor = nextTypeDef->mHasAppendCtor;
  2225. typeDef->mHasOverrideMethods = nextTypeDef->mHasOverrideMethods;
  2226. typeDef->mIsOpaque = nextTypeDef->mIsOpaque;
  2227. typeDef->mDupDetectedRevision = nextTypeDef->mDupDetectedRevision;
  2228. for (auto prevDirectNodes : typeDef->mDirectAllocNodes)
  2229. delete prevDirectNodes;
  2230. typeDef->mDirectAllocNodes = nextTypeDef->mDirectAllocNodes;
  2231. nextTypeDef->mDirectAllocNodes.Clear();
  2232. for (auto name : typeDef->mNamespaceSearch)
  2233. ReleaseAtomComposite(name);
  2234. typeDef->mNamespaceSearch = nextTypeDef->mNamespaceSearch;
  2235. for (auto name : typeDef->mNamespaceSearch)
  2236. RefAtomComposite(name);
  2237. typeDef->mStaticSearch = nextTypeDef->mStaticSearch;
  2238. for (auto prevField : typeDef->mFields)
  2239. {
  2240. delete prevField;
  2241. }
  2242. typeDef->mFields = nextTypeDef->mFields;
  2243. if (setDeclaringType)
  2244. for (auto field : typeDef->mFields)
  2245. field->mDeclaringType = typeDef;
  2246. nextTypeDef->mFields.Clear();
  2247. for (auto genericParam : typeDef->mGenericParamDefs)
  2248. delete genericParam;
  2249. typeDef->mGenericParamDefs.Clear();
  2250. typeDef->mGenericParamDefs = nextTypeDef->mGenericParamDefs;
  2251. nextTypeDef->mGenericParamDefs.Clear();
  2252. typeDef->mBaseTypes = nextTypeDef->mBaseTypes;
  2253. typeDef->mNestedTypes = nextTypeDef->mNestedTypes;
  2254. // If we are a partial then the mOuterType gets set to the combined partial so don't do that here
  2255. if (!typeDef->mIsPartial)
  2256. {
  2257. for (auto nestedType : typeDef->mNestedTypes)
  2258. {
  2259. BF_ASSERT(nestedType->mNestDepth == typeDef->mNestDepth + 1);
  2260. nestedType->mOuterType = typeDef;
  2261. }
  2262. }
  2263. typeDef->mPartials = nextTypeDef->mPartials;
  2264. typeDef->mMethodSet.Clear();
  2265. typeDef->mFieldSet.Clear();
  2266. typeDef->mPropertySet.Clear();
  2267. delete nextTypeDef;
  2268. typeDef->mNextRevision = NULL;
  2269. typeDef->mDefState = BfTypeDef::DefState_Defined;
  2270. VerifyTypeDef(typeDef);
  2271. }
  2272. void BfSystem::AddToCompositePartial(BfPassInstance* passInstance, BfTypeDef* compositeTypeDef, BfTypeDef* partialTypeDef)
  2273. {
  2274. VerifyTypeDef(compositeTypeDef);
  2275. VerifyTypeDef(partialTypeDef);
  2276. bool isFirst = false;
  2277. auto typeDef = compositeTypeDef->mNextRevision;
  2278. if (typeDef == NULL)
  2279. {
  2280. typeDef = new BfTypeDef();
  2281. compositeTypeDef->mNextRevision = typeDef;
  2282. typeDef->mIsCombinedPartial = true;
  2283. typeDef->mTypeDeclaration = partialTypeDef->mTypeDeclaration;
  2284. typeDef->mSource = partialTypeDef->mSource;
  2285. typeDef->mSource->mRefCount++;
  2286. typeDef->mSystem = partialTypeDef->mSystem;
  2287. typeDef->mTypeCode = partialTypeDef->mTypeCode;
  2288. typeDef->mNestDepth = partialTypeDef->mNestDepth;
  2289. typeDef->mOuterType = partialTypeDef->mOuterType;
  2290. typeDef->mNamespace = partialTypeDef->mNamespace;
  2291. typeDef->mName = partialTypeDef->mName;
  2292. typeDef->mName->Ref();
  2293. TrackName(typeDef);
  2294. typeDef->mNameEx = partialTypeDef->mNameEx;
  2295. typeDef->mNameEx->Ref();
  2296. typeDef->mFullName = partialTypeDef->mFullName;
  2297. typeDef->mFullNameEx = partialTypeDef->mFullNameEx;
  2298. typeDef->mProtection = partialTypeDef->mProtection;
  2299. typeDef->mIsDelegate = partialTypeDef->mIsDelegate;
  2300. typeDef->mIsAbstract = partialTypeDef->mIsAbstract;
  2301. typeDef->mIsConcrete = partialTypeDef->mIsConcrete;
  2302. typeDef->mIsStatic = partialTypeDef->mIsStatic;
  2303. typeDef->mHasAppendCtor = partialTypeDef->mHasAppendCtor;
  2304. typeDef->mHasOverrideMethods = partialTypeDef->mHasOverrideMethods;
  2305. for (auto generic : partialTypeDef->mGenericParamDefs)
  2306. {
  2307. BfGenericParamDef* newGeneric = new BfGenericParamDef();
  2308. *newGeneric = *generic;
  2309. typeDef->mGenericParamDefs.push_back(newGeneric);
  2310. }
  2311. typeDef->mBaseTypes = partialTypeDef->mBaseTypes;
  2312. isFirst = true;
  2313. VerifyTypeDef(typeDef);
  2314. }
  2315. else
  2316. {
  2317. VerifyTypeDef(typeDef);
  2318. //TODO: Assert protection and junk all matches
  2319. if (partialTypeDef->mTypeCode != BfTypeCode_Extension)
  2320. {
  2321. typeDef->mTypeCode = partialTypeDef->mTypeCode;
  2322. typeDef->mTypeDeclaration = partialTypeDef->mTypeDeclaration;
  2323. }
  2324. }
  2325. // Merge attributes together
  2326. typeDef->mIsAbstract |= partialTypeDef->mIsAbstract;
  2327. typeDef->mIsConcrete |= partialTypeDef->mIsConcrete;
  2328. typeDef->mIsStatic |= partialTypeDef->mIsStatic;
  2329. typeDef->mHasAppendCtor |= partialTypeDef->mHasAppendCtor;
  2330. typeDef->mHasOverrideMethods |= partialTypeDef->mHasOverrideMethods;
  2331. typeDef->mProtection = BF_MIN(typeDef->mProtection, partialTypeDef->mProtection);
  2332. for (auto innerType : partialTypeDef->mNestedTypes)
  2333. {
  2334. typeDef->mNestedTypes.push_back(innerType);
  2335. }
  2336. //TODO: We had the CLEAR here, but it caused an issue because when we have to rebuild the composite then
  2337. // we don't actually have the nested types from the original typeDef if they original typedef wasn't rebuilt
  2338. //partialTypeDef->mNestedTypes.Clear(); // Only reference from main typedef
  2339. for (auto field : partialTypeDef->mFields)
  2340. {
  2341. BfFieldDef* newField = new BfFieldDef();
  2342. *newField = *field;
  2343. newField->mIdx = (int)typeDef->mFields.size();
  2344. typeDef->mFields.push_back(newField);
  2345. }
  2346. typeDef->mFieldSet.Clear();
  2347. bool hadNoDeclMethod = false;
  2348. int startMethodIdx = (int)typeDef->mMethods.size();
  2349. for (auto method : partialTypeDef->mMethods)
  2350. {
  2351. bool ignoreNewMethod = false;
  2352. if (typeDef->mTypeCode == BfTypeCode_Interface)
  2353. {
  2354. if (method->mMethodDeclaration == NULL)
  2355. continue;
  2356. if (auto methodDeclaration = method->GetMethodDeclaration())
  2357. {
  2358. if (methodDeclaration->mProtectionSpecifier == NULL)
  2359. method->mProtection = BfProtection_Public;
  2360. }
  2361. }
  2362. BfMethodDef* newMethod = NULL;
  2363. if (method->mMethodType == BfMethodType_Operator)
  2364. {
  2365. BfOperatorDef* newOperator = new BfOperatorDef();
  2366. *newOperator = *(BfOperatorDef*)method;
  2367. newMethod = newOperator;
  2368. typeDef->mOperators.push_back(newOperator);
  2369. }
  2370. else
  2371. {
  2372. newMethod = new BfMethodDef();
  2373. *newMethod = *method;
  2374. }
  2375. newMethod->mIdx = (int)typeDef->mMethods.size();
  2376. for (int paramIdx = 0; paramIdx < (int)newMethod->mParams.size(); paramIdx++)
  2377. {
  2378. BfParameterDef* param = newMethod->mParams[paramIdx];
  2379. BfParameterDef* newParam = new BfParameterDef();
  2380. *newParam = *param;
  2381. newMethod->mParams[paramIdx] = newParam;
  2382. }
  2383. for (int genericIdx = 0; genericIdx < (int)newMethod->mGenericParams.size(); genericIdx++)
  2384. {
  2385. BfGenericParamDef* generic = newMethod->mGenericParams[genericIdx];
  2386. BfGenericParamDef* newGeneric = new BfGenericParamDef();
  2387. *newGeneric = *generic;
  2388. newMethod->mGenericParams[genericIdx] = newGeneric;
  2389. }
  2390. if (ignoreNewMethod)
  2391. newMethod->mMethodType = BfMethodType_Ignore;
  2392. typeDef->mMethods.push_back(newMethod);
  2393. }
  2394. typeDef->mMethodSet.Clear();
  2395. for (auto prop : partialTypeDef->mProperties)
  2396. {
  2397. BfPropertyDef* newProp = new BfPropertyDef();
  2398. *newProp = *prop;
  2399. for (int methodIdx = 0; methodIdx < (int)newProp->mMethods.size(); methodIdx++)
  2400. newProp->mMethods[methodIdx] = typeDef->mMethods[startMethodIdx + newProp->mMethods[methodIdx]->mIdx];
  2401. typeDef->mProperties.push_back(newProp);
  2402. }
  2403. typeDef->mPropertySet.Clear();
  2404. if (partialTypeDef->mDtorDef != NULL)
  2405. {
  2406. if (typeDef->mDtorDef != NULL)
  2407. {
  2408. //passInstance->Fail("Destructor already defined", partialTypeDef->mDtorDef->mMethodDeclaration->mNameNode);
  2409. //TODO:
  2410. }
  2411. else
  2412. typeDef->mDtorDef = partialTypeDef->mDtorDef;
  2413. }
  2414. BF_ASSERT(partialTypeDef->mPartials.empty());
  2415. partialTypeDef->mPartialIdx = (int)typeDef->mPartials.size();
  2416. typeDef->mPartials.push_back(partialTypeDef);
  2417. VerifyTypeDef(typeDef);
  2418. typeDef->mHash = partialTypeDef->mHash;
  2419. typeDef->mSignatureHash = Hash128(&partialTypeDef->mSignatureHash, sizeof(Val128), typeDef->mSignatureHash);
  2420. typeDef->mFullHash = Hash128(&partialTypeDef->mFullHash, sizeof(Val128), typeDef->mFullHash);
  2421. typeDef->mInlineHash = Hash128(&partialTypeDef->mInlineHash, sizeof(Val128), typeDef->mInlineHash);
  2422. VerifyTypeDef(compositeTypeDef);
  2423. VerifyTypeDef(typeDef);
  2424. }
  2425. void BfSystem::FinishCompositePartial(BfTypeDef* compositeTypeDef)
  2426. {
  2427. VerifyTypeDef(compositeTypeDef);
  2428. auto nextRevision = compositeTypeDef->mNextRevision;
  2429. struct _HasMethods
  2430. {
  2431. int mCtor;
  2432. int mCtorPublic;
  2433. int mDtor;
  2434. int mMark;
  2435. };
  2436. _HasMethods allHasMethods[2][2] = { 0 };
  2437. auto primaryDef = nextRevision->mPartials[0];
  2438. //Dictionary<BfProject*, int> projectCount;
  2439. bool hasCtorNoBody = false;
  2440. bool primaryHasFieldInitializers = false;
  2441. bool anyHasFieldInitializers = false;
  2442. // For methods that require chaining, make sure the primary def has a definition
  2443. for (auto partialTypeDef : nextRevision->mPartials)
  2444. {
  2445. bool isExtension = partialTypeDef->mTypeDeclaration != nextRevision->mTypeDeclaration;
  2446. for (auto methodDef : partialTypeDef->mMethods)
  2447. {
  2448. auto& hasMethods = allHasMethods[isExtension ? 1 : 0][methodDef->mIsStatic ? 1 : 0];
  2449. if (methodDef->mMethodType == BfMethodType_Ctor)
  2450. {
  2451. hasMethods.mCtor++;
  2452. if (methodDef->mProtection == BfProtection_Public)
  2453. hasMethods.mCtorPublic++;
  2454. if ((methodDef->mParams.size() == 0) && (!methodDef->mIsStatic) && (methodDef->mBody == NULL))
  2455. {
  2456. hasCtorNoBody = true;
  2457. }
  2458. }
  2459. else if (methodDef->mMethodType == BfMethodType_Dtor)
  2460. hasMethods.mDtor++;
  2461. else if (methodDef->mMethodType == BfMethodType_Normal)
  2462. {
  2463. if ((methodDef->mName == BF_METHODNAME_MARKMEMBERS) || (methodDef->mName == BF_METHODNAME_MARKMEMBERS_STATIC))
  2464. hasMethods.mMark++;
  2465. }
  2466. }
  2467. bool hasFieldInitializers = false;
  2468. for (auto fieldDef : partialTypeDef->mFields)
  2469. {
  2470. if ((!fieldDef->mIsStatic) && (fieldDef->mFieldDeclaration->mInitializer != NULL))
  2471. hasFieldInitializers = true;
  2472. }
  2473. if (hasFieldInitializers)
  2474. {
  2475. anyHasFieldInitializers = true;
  2476. if (!isExtension)
  2477. primaryHasFieldInitializers = true;
  2478. auto methodDef = BfDefBuilder::AddMethod(nextRevision, BfMethodType_CtorNoBody, BfProtection_Protected, false, "");
  2479. methodDef->mDeclaringType = partialTypeDef;
  2480. methodDef->mIsMutating = true;
  2481. }
  2482. }
  2483. if ((anyHasFieldInitializers) && (!primaryHasFieldInitializers))
  2484. {
  2485. auto methodDef = BfDefBuilder::AddMethod(nextRevision, BfMethodType_CtorNoBody, BfProtection_Protected, false, "");
  2486. methodDef->mDeclaringType = primaryDef;
  2487. methodDef->mIsMutating = true;
  2488. }
  2489. if ((allHasMethods[0][0].mCtor == 0) && (allHasMethods[1][0].mCtor > 1))
  2490. {
  2491. auto methodDef = BfDefBuilder::AddMethod(nextRevision, BfMethodType_Ctor, (allHasMethods[1][0].mCtorPublic > 0) ? BfProtection_Public : BfProtection_Protected, false, "");
  2492. methodDef->mDeclaringType = primaryDef;
  2493. methodDef->mIsMutating = true;
  2494. }
  2495. // if (!hasCtorNoBody)
  2496. // {
  2497. // auto methodDef = BfDefBuilder::AddMethod(nextRevision, BfMethodType_CtorNoBody, BfProtection_Protected, false, "");
  2498. // methodDef->mDeclaringType = primaryDef;
  2499. // methodDef->mIsMutating = true;
  2500. // }
  2501. if ((allHasMethods[0][1].mCtor == 0) && (allHasMethods[1][1].mCtor > 1))
  2502. {
  2503. auto methodDef = BfDefBuilder::AddMethod(nextRevision, BfMethodType_Ctor, BfProtection_Public, true, "");
  2504. methodDef->mDeclaringType = primaryDef;
  2505. }
  2506. if ((allHasMethods[0][0].mDtor == 0) && (allHasMethods[1][0].mDtor > 1))
  2507. {
  2508. auto methodDef = BfDefBuilder::AddMethod(nextRevision, BfMethodType_Dtor, BfProtection_Public, false, "");
  2509. methodDef->mDeclaringType = primaryDef;
  2510. }
  2511. if ((allHasMethods[0][1].mDtor == 0) && (allHasMethods[1][1].mDtor > 1))
  2512. {
  2513. auto methodDef = BfDefBuilder::AddMethod(nextRevision, BfMethodType_Dtor, BfProtection_Public, true, "");
  2514. methodDef->mDeclaringType = primaryDef;
  2515. }
  2516. if ((allHasMethods[0][0].mMark == 0) && (allHasMethods[1][0].mMark > 1))
  2517. {
  2518. auto methodDef = BfDefBuilder::AddMethod(nextRevision, BfMethodType_Normal, BfProtection_Public, false, BF_METHODNAME_MARKMEMBERS);
  2519. methodDef->mDeclaringType = primaryDef;
  2520. methodDef->mIsVirtual = true;
  2521. methodDef->mIsOverride = true;
  2522. }
  2523. if ((allHasMethods[0][1].mMark == 0) && (allHasMethods[1][1].mMark > 1))
  2524. {
  2525. auto methodDef = BfDefBuilder::AddMethod(nextRevision, BfMethodType_Normal, BfProtection_Public, true, BF_METHODNAME_MARKMEMBERS_STATIC);
  2526. methodDef->mDeclaringType = primaryDef;
  2527. }
  2528. // If this fails, it's probably because there were no actual composite pieces to put into it
  2529. BF_ASSERT(nextRevision != NULL);
  2530. if ((nextRevision->mDefState == BfTypeDef::DefState_Signature_Changed) || (compositeTypeDef->mSignatureHash != nextRevision->mSignatureHash))
  2531. compositeTypeDef->mDefState = BfTypeDef::DefState_Signature_Changed;
  2532. else if ((nextRevision->mDefState == BfTypeDef::DefState_InlinedInternals_Changed) || (compositeTypeDef->mInlineHash != nextRevision->mInlineHash))
  2533. compositeTypeDef->mDefState = BfTypeDef::DefState_InlinedInternals_Changed;
  2534. else if ((nextRevision->mDefState == BfTypeDef::DefState_Internals_Changed) || (compositeTypeDef->mFullHash != nextRevision->mFullHash))
  2535. compositeTypeDef->mDefState = BfTypeDef::DefState_Internals_Changed;
  2536. //InjectNewRevision(compositeTypeDef);
  2537. VerifyTypeDef(compositeTypeDef);
  2538. VerifyTypeDef(nextRevision);
  2539. }
  2540. BfTypeDef* BfSystem::GetCombinedPartial(BfTypeDef* typeDef)
  2541. {
  2542. if ((!typeDef->mIsPartial) || (typeDef->mIsCombinedPartial))
  2543. return typeDef;
  2544. auto itr = mTypeDefs.TryGet(typeDef->mFullName);
  2545. do
  2546. {
  2547. BF_ASSERT(typeDef->mIsPartial);
  2548. typeDef = *itr;
  2549. itr.MoveToNextHashMatch();
  2550. } while (!typeDef->mIsCombinedPartial);
  2551. return typeDef;
  2552. }
  2553. BfTypeDef* BfSystem::GetOuterTypeNonPartial(BfTypeDef* typeDef)
  2554. {
  2555. auto checkType = typeDef->mOuterType;
  2556. if ((checkType == NULL) || (!checkType->mIsPartial))
  2557. return checkType;
  2558. return GetCombinedPartial(checkType);
  2559. }
  2560. int BfSystem::GetGenericParamIdx(const Array<BfGenericParamDef*>& genericParams, const StringImpl& name)
  2561. {
  2562. for (int i = 0; i < (int)genericParams.size(); i++)
  2563. if (genericParams[i]->mName == name)
  2564. return i;
  2565. return -1;
  2566. }
  2567. int BfSystem::GetGenericParamIdx(const Array<BfGenericParamDef*>& genericParams, BfTypeReference* typeRef)
  2568. {
  2569. if (!typeRef->IsA<BfNamedTypeReference>())
  2570. return -1;
  2571. return GetGenericParamIdx(genericParams, typeRef->ToString());
  2572. }
  2573. void BfSystem::StartYieldSection()
  2574. {
  2575. mYieldTickCount = BFTickCount();
  2576. mHighestYieldTime = 0;
  2577. }
  2578. void BfSystem::SummarizeYieldSection()
  2579. {
  2580. OutputDebugStrF("Highest yield time: %d\n", mHighestYieldTime);
  2581. }
  2582. void BfSystem::CheckLockYield()
  2583. {
  2584. if (mYieldDisallowCount != 0)
  2585. return;
  2586. //uint32 curTime = BFTickCount();
  2587. //int yieldTime = (int)(curTime - mYieldTickCount);
  2588. //mHighestYieldTime = BF_MAX(yieldTime, mHighestYieldTime);
  2589. //mYieldTickCount = curTime;
  2590. if (mPendingSystemLockPri > mCurSystemLockPri)
  2591. {
  2592. BF_ASSERT(mCurSystemLockThreadId == BfpThread_GetCurrentId());
  2593. int mySystemLockPri = mCurSystemLockPri;
  2594. BF_ASSERT(mSystemLock.mLockCount == 1);
  2595. mSystemLock.Unlock();
  2596. // Wait for the other thread to actually acquire the lock. This only spins between the time
  2597. // we get a NotifyWillRequestLock and when that thread actually does the Lock
  2598. while (mPendingSystemLockPri != -1)
  2599. {
  2600. BfpThread_Yield();
  2601. }
  2602. Lock(mySystemLockPri);
  2603. mCurSystemLockThreadId = BfpThread_GetCurrentId();
  2604. }
  2605. }
  2606. void BfSystem::NotifyWillRequestLock(int priority)
  2607. {
  2608. mPendingSystemLockPri = priority;
  2609. }
  2610. void BfSystem::Lock(int priority)
  2611. {
  2612. #ifdef _DEBUG
  2613. if (priority > 0)
  2614. {
  2615. if (!mSystemLock.TryLock(10))
  2616. mSystemLock.Lock();
  2617. }
  2618. else
  2619. mSystemLock.Lock();
  2620. #else
  2621. mSystemLock.Lock();
  2622. #endif
  2623. BF_ASSERT(mSystemLock.mLockCount == 1);
  2624. if (mPendingSystemLockPri == priority)
  2625. mPendingSystemLockPri = -1;
  2626. mCurSystemLockPri = priority;
  2627. mCurSystemLockThreadId = BfpThread_GetCurrentId();
  2628. }
  2629. void BfSystem::Unlock()
  2630. {
  2631. BF_ASSERT(mYieldDisallowCount == 0);
  2632. mCurSystemLockPri = -1;
  2633. mSystemLock.Unlock();
  2634. BF_ASSERT(mSystemLock.mLockCount >= 0);
  2635. }
  2636. void BfSystem::AssertWeHaveLock()
  2637. {
  2638. //mSystemLock.mCritSect
  2639. }
  2640. void BfSystem::RemoveDeletedParsers()
  2641. {
  2642. while (true)
  2643. {
  2644. BfParser* bfParser = NULL;
  2645. {
  2646. AutoCrit crit(mDataLock);
  2647. if (mParserDeleteQueue.size() == 0)
  2648. break;
  2649. bfParser = mParserDeleteQueue.back();
  2650. mParserDeleteQueue.pop_back();
  2651. /*auto itr = std::find(mParsers.begin(), mParsers.end(), bfParser);
  2652. BF_ASSERT(itr != mParsers.end());
  2653. mParsers.erase(itr);*/
  2654. bool wasRemoved = mParsers.Remove(bfParser);
  2655. BF_ASSERT(wasRemoved);
  2656. }
  2657. BfLogSys(this, "Removing Queued Parser: %p\n", bfParser);
  2658. if (bfParser != NULL)
  2659. delete bfParser;
  2660. CheckLockYield();
  2661. }
  2662. }
  2663. void BfSystem::RemoveOldParsers()
  2664. {
  2665. mDataLock.Lock();
  2666. // We can't be allowed to delete old parsers if the new typedefs haven't been
  2667. // injected yet by the compiler
  2668. if (mNeedsTypesHandledByCompiler)
  2669. {
  2670. mDataLock.Unlock();
  2671. return;
  2672. }
  2673. RemoveDeletedParsers();
  2674. for (int i = 0; i < (int)mParsers.size(); i++)
  2675. {
  2676. auto bfParser = mParsers[i];
  2677. bool wantsDelete = false;
  2678. if (bfParser->mRefCount == 0)
  2679. {
  2680. if ((bfParser->mNextRevision != NULL) || (bfParser->mAwaitingDelete))
  2681. {
  2682. if (bfParser->mNextRevision != NULL)
  2683. bfParser->mNextRevision->mPrevRevision = bfParser->mPrevRevision;
  2684. if (bfParser->mPrevRevision != NULL)
  2685. bfParser->mPrevRevision->mNextRevision = bfParser->mNextRevision;
  2686. BfLogSys(this, "Deleting Old Parser: %p New Parser: %p\n", bfParser, bfParser->mNextRevision);
  2687. mDataLock.Unlock();
  2688. delete bfParser;
  2689. mDataLock.Lock();
  2690. mParsers.erase(mParsers.begin() + i);
  2691. i--;
  2692. }
  2693. }
  2694. }
  2695. mDataLock.Unlock();
  2696. }
  2697. void BfSystem::RemoveOldData()
  2698. {
  2699. {
  2700. AutoCrit autoCrit(mDataLock);
  2701. for (auto typeDef : mTypeDefDeleteQueue)
  2702. delete typeDef;
  2703. mTypeDefDeleteQueue.Clear();
  2704. for (auto project : mProjectDeleteQueue)
  2705. delete project;
  2706. mProjectDeleteQueue.Clear();
  2707. }
  2708. RemoveOldParsers();
  2709. }
  2710. void BfSystem::VerifyTypeDef(BfTypeDef* typeDef)
  2711. {
  2712. auto _FindTypeDef = [&](BfTypeReference* typeRef)
  2713. {
  2714. if (auto directStrTypeRef = BfNodeDynCast<BfDirectStrTypeReference>(typeRef))
  2715. {
  2716. bool found = false;
  2717. for (auto directRef : typeDef->mDirectAllocNodes)
  2718. if (directRef == directStrTypeRef)
  2719. found = true;
  2720. for (auto partialTypeDef : typeDef->mPartials)
  2721. {
  2722. for (auto directRef : partialTypeDef->mDirectAllocNodes)
  2723. if (directRef == directStrTypeRef)
  2724. found = true;
  2725. }
  2726. for (auto directRef : mDirectTypeRefs)
  2727. if (directRef == directStrTypeRef)
  2728. found = true;
  2729. BF_ASSERT(found);
  2730. }
  2731. };
  2732. for (auto methodDef : typeDef->mMethods)
  2733. {
  2734. _FindTypeDef(methodDef->mReturnTypeRef);
  2735. for (auto paramDef : methodDef->mParams)
  2736. {
  2737. _FindTypeDef(paramDef->mTypeRef);
  2738. }
  2739. }
  2740. }
  2741. BfTypeOptions* BfSystem::GetTypeOptions(int optionsIdx)
  2742. {
  2743. BF_ASSERT(optionsIdx != -2);
  2744. if (optionsIdx < 0)
  2745. return NULL;
  2746. if (optionsIdx < mTypeOptions.size())
  2747. return &mTypeOptions[optionsIdx];
  2748. return &mMergedTypeOptions[optionsIdx - mTypeOptions.size()];
  2749. }
  2750. bool BfSystem::HasTestProjects()
  2751. {
  2752. for (auto project : mProjects)
  2753. if (project->mTargetType == BfTargetType_BeefTest)
  2754. return true;
  2755. return false;
  2756. }
  2757. bool BfSystem::IsCompatibleCallingConvention(BfCallingConvention callConvA, BfCallingConvention callConvB)
  2758. {
  2759. if (mPtrSize == 8)
  2760. return true; // There's only one 64-bit calling convention
  2761. if (callConvA == BfCallingConvention_Unspecified)
  2762. callConvA = BfCallingConvention_Cdecl;
  2763. if (callConvB == BfCallingConvention_Unspecified)
  2764. callConvB = BfCallingConvention_Cdecl;
  2765. return callConvA == callConvB;
  2766. }
  2767. //////////////////////////////////////////////////////////////////////////
  2768. BF_EXPORT BfSystem* BF_CALLTYPE BfSystem_Create()
  2769. {
  2770. auto bfSystem = new BfSystem();
  2771. return bfSystem;
  2772. }
  2773. void BfReportMemory();
  2774. BF_EXPORT void BF_CALLTYPE BfSystem_Delete(BfSystem* bfSystem)
  2775. {
  2776. //OutputDebugStrF("Before Deleting BfSystem ");
  2777. //BfReportMemory();
  2778. delete bfSystem;
  2779. //OutputDebugStrF("After Deleting BfSystem ");
  2780. //BfReportMemory();
  2781. }
  2782. BF_EXPORT void BF_CALLTYPE BfSystem_CheckLock(BfSystem* bfSystem)
  2783. {
  2784. BF_ASSERT(bfSystem->mSystemLock.mLockCount == 0);
  2785. }
  2786. BF_EXPORT void BF_CALLTYPE BfResolvePassData_Delete(BfResolvePassData* resolvePassData)
  2787. {
  2788. delete resolvePassData->mAutoComplete;
  2789. for (auto tempType : resolvePassData->mAutoCompleteTempTypes)
  2790. delete tempType;
  2791. delete resolvePassData;
  2792. }
  2793. BF_EXPORT void BF_CALLTYPE BfResolvePassData_SetLocalId(BfResolvePassData* resolvePassData, int localId)
  2794. {
  2795. resolvePassData->mSymbolReferenceLocalIdx = localId;
  2796. resolvePassData->mGetSymbolReferenceKind = BfGetSymbolReferenceKind_Local;
  2797. }
  2798. BF_EXPORT void BF_CALLTYPE BfResolvePassData_SetTypeGenericParamIdx(BfResolvePassData* resolvePassData, int typeGenericParamIdx)
  2799. {
  2800. resolvePassData->mSymbolTypeGenericParamIdx = typeGenericParamIdx;
  2801. resolvePassData->mGetSymbolReferenceKind = BfGetSymbolReferenceKind_TypeGenericParam;
  2802. }
  2803. BF_EXPORT void BF_CALLTYPE BfResolvePassData_SetMethodGenericParamIdx(BfResolvePassData* resolvePassData, int methodGenericParamIdx)
  2804. {
  2805. resolvePassData->mSymbolMethodGenericParamIdx = methodGenericParamIdx;
  2806. resolvePassData->mGetSymbolReferenceKind = BfGetSymbolReferenceKind_MethodGenericParam;
  2807. }
  2808. BF_EXPORT void BF_CALLTYPE BfResolvePassData_SetSymbolReferenceTypeDef(BfResolvePassData* resolvePassData, const char* replaceTypeDef)
  2809. {
  2810. resolvePassData->mQueuedReplaceTypeDef = replaceTypeDef;
  2811. resolvePassData->mGetSymbolReferenceKind = BfGetSymbolReferenceKind_Type;
  2812. }
  2813. BF_EXPORT void BF_CALLTYPE BfResolvePassData_SetSymbolReferenceFieldIdx(BfResolvePassData* resolvePassData, int fieldIdx)
  2814. {
  2815. resolvePassData->mSymbolReferenceFieldIdx = fieldIdx;
  2816. resolvePassData->mGetSymbolReferenceKind = BfGetSymbolReferenceKind_Field;
  2817. }
  2818. BF_EXPORT void BF_CALLTYPE BfResolvePassData_SetSymbolReferenceMethodIdx(BfResolvePassData* resolvePassData, int methodIdx)
  2819. {
  2820. resolvePassData->mSymbolReferenceMethodIdx = methodIdx;
  2821. resolvePassData->mGetSymbolReferenceKind = BfGetSymbolReferenceKind_Method;
  2822. }
  2823. BF_EXPORT void BF_CALLTYPE BfResolvePassData_SetSymbolReferencePropertyIdx(BfResolvePassData* resolvePassData, int propertyIdx)
  2824. {
  2825. resolvePassData->mSymbolReferencePropertyIdx = propertyIdx;
  2826. resolvePassData->mGetSymbolReferenceKind = BfGetSymbolReferenceKind_Property;
  2827. }
  2828. BF_EXPORT void BfResolvePassData_SetDocumentationRequest(BfResolvePassData* resolvePassData, char* entryName)
  2829. {
  2830. resolvePassData->mAutoComplete->mDocumentationEntryName = entryName;
  2831. }
  2832. BF_EXPORT BfParser* BF_CALLTYPE BfSystem_CreateParser(BfSystem* bfSystem, BfProject* bfProject)
  2833. {
  2834. return bfSystem->CreateParser(bfProject);
  2835. }
  2836. BF_EXPORT void BF_CALLTYPE BfSystem_DeleteParser(BfSystem* bfSystem, BfParser* bfParser)
  2837. {
  2838. BfLogSys(bfSystem, "BfSystem_DeleteParser: %p\n", bfParser);
  2839. AutoCrit crit(bfSystem->mDataLock);
  2840. bfParser->mAwaitingDelete = true;
  2841. if (bfParser->mNextRevision == NULL)
  2842. {
  2843. for (auto typeDef : bfParser->mTypeDefs)
  2844. {
  2845. BfLogSys(bfSystem, "BfSystem_DeleteParser deleting typeDef %p\n", typeDef);
  2846. typeDef->mDefState = BfTypeDef::DefState_Deleted;
  2847. }
  2848. }
  2849. //bfSystem->mParserDeleteQueue.push_back(bfParser);
  2850. }
  2851. BF_EXPORT BfCompiler* BF_CALLTYPE BfSystem_CreateCompiler(BfSystem* bfSystem, bool isResolveOnly)
  2852. {
  2853. return bfSystem->CreateCompiler(isResolveOnly);
  2854. }
  2855. BF_EXPORT const char* BF_CALLTYPE BfPassInstance_PopOutString(BfPassInstance* bfPassInstance)
  2856. {
  2857. String& outString = *gTLStrReturn.Get();
  2858. if (!bfPassInstance->PopOutString(&outString))
  2859. return NULL;
  2860. return outString.c_str();
  2861. }
  2862. BF_EXPORT void BF_CALLTYPE BfPassInstance_SetClassifierPassId(BfPassInstance* bfPassInstance, uint8 classifierPassId)
  2863. {
  2864. bfPassInstance->mClassifierPassId = classifierPassId;
  2865. }
  2866. BF_EXPORT int BF_CALLTYPE BfPassInstance_GetErrorCount(BfPassInstance* bfPassInstance)
  2867. {
  2868. return (int)bfPassInstance->mErrors.size();
  2869. }
  2870. BF_EXPORT const char* BF_CALLTYPE BfPassInstance_GetErrorData(BfPassInstance* bfPassInstance, int errorIdx, bool& outIsWarning, bool& outIsAfter, bool& outIsDeferred, bool& outIsWhileSpecializing, bool& outIsPersistent, int& outSrcStart, int& outSrcEnd, int& outMoreInfoCount)
  2871. {
  2872. BfError* bfError = bfPassInstance->mErrors[errorIdx];
  2873. outIsWarning = bfError->mIsWarning;
  2874. outIsAfter = bfError->mIsAfter;
  2875. outIsDeferred = bfError->mIsDeferred;
  2876. outIsWhileSpecializing = bfError->mIsWhileSpecializing;
  2877. outIsPersistent = bfError->mIsPersistent;
  2878. outSrcStart = bfError->mSrcStart;
  2879. outSrcEnd = bfError->mSrcEnd;
  2880. outMoreInfoCount = (int)bfError->mMoreInfo.size();
  2881. return bfError->mError.c_str();
  2882. }
  2883. BF_EXPORT const char* BfPassInstance_Error_GetMoreInfoData(BfPassInstance* bfPassInstance, int errorIdx, int moreInfoIdx, char*& fileName, int& srcStart, int& srcEnd)
  2884. {
  2885. BfError* rootError = bfPassInstance->mErrors[errorIdx];
  2886. BfMoreInfo* moreInfo = rootError->mMoreInfo[moreInfoIdx];
  2887. if (moreInfo->mSource != NULL)
  2888. {
  2889. String* srcFileName;
  2890. if (bfPassInstance->mSourceFileNameMap.TryGetValue(moreInfo->mSource, &srcFileName))
  2891. {
  2892. fileName = (char*)srcFileName->c_str();
  2893. }
  2894. }
  2895. srcStart = moreInfo->mSrcStart;
  2896. srcEnd = moreInfo->mSrcEnd;
  2897. return moreInfo->mInfo.c_str();
  2898. }
  2899. BF_EXPORT bool BF_CALLTYPE BfPassInstance_HadSignatureChanges(BfPassInstance* bfPassInstance)
  2900. {
  2901. return bfPassInstance->mHadSignatureChanges;
  2902. }
  2903. BF_EXPORT void BF_CALLTYPE BfPassInstance_Delete(BfPassInstance* bfPassInstance)
  2904. {
  2905. delete bfPassInstance;
  2906. }
  2907. BF_EXPORT BfPassInstance* BF_CALLTYPE BfSystem_CreatePassInstance(BfSystem* bfSystem)
  2908. {
  2909. return new BfPassInstance(bfSystem);
  2910. }
  2911. BF_EXPORT void BF_CALLTYPE BfSystem_RemoveDeletedParsers(BfSystem* bfSystem)
  2912. {
  2913. bfSystem->RemoveDeletedParsers();
  2914. }
  2915. BF_EXPORT void BF_CALLTYPE BfSystem_RemoveOldParsers(BfSystem* bfSystem)
  2916. {
  2917. bfSystem->RemoveOldParsers();
  2918. }
  2919. BF_EXPORT void BF_CALLTYPE BfSystem_RemoveOldData(BfSystem* bfSystem)
  2920. {
  2921. bfSystem->RemoveOldData();
  2922. }
  2923. BF_EXPORT void BF_CALLTYPE BfSystem_NotifyWillRequestLock(BfSystem* bfSystem, int priority)
  2924. {
  2925. bfSystem->NotifyWillRequestLock(priority);
  2926. }
  2927. BF_EXPORT void BF_CALLTYPE BfSystem_Lock(BfSystem* bfSystem, int priority)
  2928. {
  2929. bfSystem->Lock(priority);
  2930. }
  2931. BF_EXPORT void BF_CALLTYPE BfSystem_Unlock(BfSystem* bfSystem)
  2932. {
  2933. bfSystem->Unlock();
  2934. }
  2935. BF_EXPORT void BF_CALLTYPE BfSystem_Update(BfSystem* bfSystem)
  2936. {
  2937. bfSystem->mUpdateCnt++;
  2938. if (bfSystem->mUpdateCnt % 60 == 0)
  2939. {
  2940. if (bfSystem->mParserDeleteQueue.size() != 0)
  2941. {
  2942. #ifdef _DEBUG
  2943. //OutputDebugStrF("mParserDeleteQueue = %d\n", (int)bfSystem->mParserDeleteQueue.size());
  2944. #endif
  2945. }
  2946. }
  2947. }
  2948. BF_EXPORT void BF_CALLTYPE BfSystem_ReportMemory(BfSystem* bfSystem)
  2949. {
  2950. AutoCrit crit(bfSystem->mDataLock);
  2951. MemReporter memReporter;
  2952. for (auto compiler : bfSystem->mCompilers)
  2953. {
  2954. AutoMemReporter autoMemReporter(&memReporter, "Compiler");
  2955. compiler->ReportMemory(&memReporter);
  2956. }
  2957. for (auto typeDef : bfSystem->mTypeDefs)
  2958. {
  2959. AutoMemReporter autoMemReporter(&memReporter, "TypeDef");
  2960. typeDef->ReportMemory(&memReporter);
  2961. }
  2962. for (auto parser : bfSystem->mParsers)
  2963. {
  2964. AutoMemReporter autoMemReporter(&memReporter, "Parsers");
  2965. parser->ReportMemory(&memReporter);
  2966. }
  2967. memReporter.Report();
  2968. }
  2969. BF_EXPORT void BF_CALLTYPE BfSystem_StartTiming()
  2970. {
  2971. gPerfManager->StartRecording();
  2972. }
  2973. BF_EXPORT void BF_CALLTYPE BfSystem_PerfZoneStart(const char* name)
  2974. {
  2975. gPerfManager->ZoneStart(name);
  2976. }
  2977. BF_EXPORT void BF_CALLTYPE BfSystem_PerfZoneEnd()
  2978. {
  2979. gPerfManager->ZoneEnd();
  2980. }
  2981. BF_EXPORT void BF_CALLTYPE BfSystem_StopTiming()
  2982. {
  2983. gPerfManager->StopRecording();
  2984. }
  2985. BF_EXPORT void BF_CALLTYPE BfSystem_DbgPrintTimings()
  2986. {
  2987. gPerfManager->DbgPrint();
  2988. }
  2989. BF_EXPORT const char* BF_CALLTYPE BfSystem_GetNamespaceSearch(BfSystem* bfSystem, const char* typeName, BfProject* project)
  2990. {
  2991. auto typeDef = bfSystem->FindTypeDef(typeName, project);
  2992. if (typeDef == NULL)
  2993. return NULL;
  2994. String& outString = *gTLStrReturn.Get();
  2995. outString.clear();
  2996. for (auto namespaceEntry : typeDef->mNamespaceSearch)
  2997. {
  2998. if (!outString.empty())
  2999. outString += "\n";
  3000. outString += namespaceEntry.ToString();
  3001. }
  3002. return outString.c_str();
  3003. }
  3004. BF_EXPORT BfProject* BF_CALLTYPE BfSystem_CreateProject(BfSystem* bfSystem, const char* projectName)
  3005. {
  3006. AutoCrit autoCrit(bfSystem->mDataLock);
  3007. BfProject* bfProject = new BfProject();
  3008. bfProject->mName = projectName;
  3009. bfProject->mSystem = bfSystem;
  3010. bfProject->mIdx = (int)bfSystem->mProjects.size();
  3011. bfSystem->mProjects.push_back(bfProject);
  3012. BfLogSys(bfSystem, "Creating project %p\n", bfProject);
  3013. return bfProject;
  3014. }
  3015. BF_EXPORT void BF_CALLTYPE BfSystem_ClearTypeOptions(BfSystem* bfSystem)
  3016. {
  3017. AutoCrit autoCrit(bfSystem->mDataLock);
  3018. bfSystem->mTypeOptions.Clear();
  3019. }
  3020. BF_EXPORT void BF_CALLTYPE BfSystem_AddTypeOptions(BfSystem* bfSystem, char* filter, int32 simdSetting, int32 optimizationLevel, int32 emitDebugInfo, int32 runtimeChecks,
  3021. int32 initLocalVariables, int32 emitDynamicCastCheck, int32 emitObjectAccessCheck, int32 allocStackTraceDepth)
  3022. {
  3023. AutoCrit autoCrit(bfSystem->mDataLock);
  3024. BfTypeOptions typeOptions;
  3025. String filterStr = filter;
  3026. int idx = 0;
  3027. while (true)
  3028. {
  3029. int semiIdx = (int)filterStr.IndexOf(';', idx);
  3030. String newFilter;
  3031. if (semiIdx == -1)
  3032. newFilter = filterStr.Substring(idx);
  3033. else
  3034. newFilter = filterStr.Substring(idx, semiIdx - idx);
  3035. newFilter.Trim();
  3036. if (!newFilter.IsEmpty())
  3037. {
  3038. if (newFilter.StartsWith('['))
  3039. {
  3040. newFilter.Remove(0);
  3041. if (newFilter.EndsWith(']'))
  3042. newFilter.Remove(newFilter.length() - 1);
  3043. newFilter.Trim();
  3044. typeOptions.mAttributeFilters.Add(newFilter);
  3045. }
  3046. else
  3047. typeOptions.mTypeFilters.Add(newFilter);
  3048. }
  3049. if (semiIdx == -1)
  3050. break;
  3051. idx = semiIdx + 1;
  3052. }
  3053. if ((typeOptions.mTypeFilters.IsEmpty()) && (typeOptions.mAttributeFilters.IsEmpty()))
  3054. return;
  3055. typeOptions.mSIMDSetting = simdSetting;
  3056. typeOptions.mOptimizationLevel = optimizationLevel;
  3057. typeOptions.mEmitDebugInfo = emitDebugInfo;
  3058. typeOptions.mRuntimeChecks = (BfOptionalBool)runtimeChecks;
  3059. typeOptions.mInitLocalVariables = (BfOptionalBool)initLocalVariables;
  3060. typeOptions.mEmitDynamicCastCheck = (BfOptionalBool)emitDynamicCastCheck;
  3061. typeOptions.mEmitObjectAccessCheck = (BfOptionalBool)emitObjectAccessCheck;
  3062. typeOptions.mAllocStackTraceDepth = allocStackTraceDepth;
  3063. bfSystem->mTypeOptions.push_back(typeOptions);
  3064. }
  3065. BF_EXPORT void BF_CALLTYPE BfProject_Delete(BfProject* bfProject)
  3066. {
  3067. auto bfSystem = bfProject->mSystem;
  3068. AutoCrit autoCrit(bfSystem->mSystemLock);
  3069. bfSystem->mProjectDeleteQueue.push_back(bfProject);
  3070. BF_ASSERT(bfSystem->mProjects[bfProject->mIdx] == bfProject);
  3071. bool wasRemoved = bfSystem->mProjects.Remove(bfProject);
  3072. BF_ASSERT(wasRemoved);
  3073. for (int i = bfProject->mIdx; i < (int)bfSystem->mProjects.size(); i++)
  3074. bfSystem->mProjects[i]->mIdx = i;
  3075. bfProject->mIdx = -1;
  3076. /*#ifdef _DEBUG
  3077. {
  3078. AutoCrit autoCrit(bfSystem->mSystemLock);
  3079. for (auto typeDefKV : bfSystem->mTypeDefs)
  3080. {
  3081. auto typeDef = typeDefKV.second;
  3082. BF_ASSERT(typeDef->mProject != bfProject);
  3083. }
  3084. }
  3085. #endif
  3086. delete bfProject;*/
  3087. }
  3088. BF_EXPORT void BF_CALLTYPE BfProject_ClearDependencies(BfProject* bfProject)
  3089. {
  3090. bfProject->mDependencies.Clear();
  3091. }
  3092. BF_EXPORT void BF_CALLTYPE BfProject_AddDependency(BfProject* bfProject, BfProject* depProject)
  3093. {
  3094. bfProject->mDependencies.push_back(depProject);
  3095. }
  3096. BF_EXPORT void BF_CALLTYPE BfProject_SetDisabled(BfProject* bfProject, bool disabled)
  3097. {
  3098. bfProject->mDisabled = disabled;
  3099. }
  3100. BF_EXPORT void BF_CALLTYPE BfProject_SetOptions(BfProject* bfProject, int targetType, const char* startupObject, const char* preprocessorMacros,
  3101. int optLevel, int ltoType, int relocType, int picLevel, BfProjectFlags flags)
  3102. {
  3103. bfProject->mTargetType = (BfTargetType)targetType;
  3104. bfProject->mStartupObject = startupObject;
  3105. BfCodeGenOptions codeGenOptions;
  3106. codeGenOptions.mOptLevel = (BfOptLevel)optLevel;
  3107. codeGenOptions.mLTOType = (BfLTOType)ltoType;
  3108. codeGenOptions.mRelocType = (BfRelocType)relocType;
  3109. codeGenOptions.mPICLevel = (BfPICLevel)picLevel;
  3110. codeGenOptions.mMergeFunctions = (flags & BfProjectFlags_MergeFunctions) != 0;
  3111. codeGenOptions.mLoadCombine = (flags & BfProjectFlags_CombineLoads) != 0;
  3112. codeGenOptions.mLoopVectorize = (flags & BfProjectFlags_VectorizeLoops) != 0;
  3113. codeGenOptions.mSLPVectorize = (flags & BfProjectFlags_VectorizeSLP) != 0;
  3114. if ((flags & BfProjectFlags_AsmOutput) != 0)
  3115. {
  3116. static bool setLLVMAsmKind = false;
  3117. if ((flags & BfProjectFlags_AsmOutput_ATT) != 0)
  3118. codeGenOptions.mAsmKind = BfAsmKind_ATT;
  3119. else
  3120. codeGenOptions.mAsmKind = BfAsmKind_Intel;
  3121. if (!setLLVMAsmKind)
  3122. {
  3123. setLLVMAsmKind = true;
  3124. BfIRCodeGen::SetAsmKind(codeGenOptions.mAsmKind);
  3125. }
  3126. }
  3127. bfProject->mCodeGenOptions = codeGenOptions;
  3128. bfProject->mSingleModule = (flags & BfProjectFlags_SingleModule) != 0;
  3129. bfProject->mAlwaysIncludeAll = (flags & BfProjectFlags_AlwaysIncludeAll) != 0;
  3130. bfProject->mPreprocessorMacros.Clear();
  3131. int startIdx = 0;
  3132. int idx = 0;
  3133. while (true)
  3134. {
  3135. char c = preprocessorMacros[idx];
  3136. if ((c == '\n') || (c == 0))
  3137. {
  3138. String macroStr = String(preprocessorMacros + startIdx, preprocessorMacros + idx);
  3139. if (macroStr.length() > 0)
  3140. bfProject->mPreprocessorMacros.Add(macroStr);
  3141. startIdx = idx + 1;
  3142. }
  3143. if (c == 0)
  3144. break;
  3145. idx++;
  3146. }
  3147. }
  3148. //////////////////////////////////////////////////////////////////////////
  3149. class FixTypesHelper : BfElementVisitor
  3150. {
  3151. public:
  3152. BfSystem* mBfSystem;
  3153. bool mInMethod;
  3154. bool mInTypeRef;
  3155. struct ReplaceRecord
  3156. {
  3157. BfAstNode* mNode;
  3158. String mNewStr;
  3159. };
  3160. std::map<int, ReplaceRecord> mReplaceMap;
  3161. public:
  3162. String GetTypeName(const StringImpl& typeName)
  3163. {
  3164. if (typeName == "long")
  3165. return "int64";
  3166. else if (typeName == "ulong")
  3167. return "uint64";
  3168. else if (typeName == "intptr")
  3169. return "int";
  3170. else if (typeName == "uintptr")
  3171. return "uint";
  3172. else if (typeName == "short")
  3173. return "int16";
  3174. else if (typeName == "ushort")
  3175. return "uint16";
  3176. else if (typeName == "byte")
  3177. return "uint8";
  3178. else if (typeName == "sbyte")
  3179. return "int8";
  3180. else if (typeName == "SByte")
  3181. return "Int8";
  3182. else if (typeName == "Byte")
  3183. return "UInt8";
  3184. else if (typeName == "Single")
  3185. return "Float";
  3186. else if (typeName == "IntPtr")
  3187. return "Int";
  3188. else if (typeName == "UIntPtr")
  3189. return "UInt";
  3190. //else if ((!mInMethod) || (mInTypeRef))
  3191. {
  3192. if (typeName == "int")
  3193. return "int32";
  3194. else if (typeName == "uint")
  3195. return "uint32";
  3196. }
  3197. return typeName;
  3198. }
  3199. void Visit(BfTypeReference* typeRef)
  3200. {
  3201. String typeName = typeRef->ToString();
  3202. String wantTypeName = GetTypeName(typeName);
  3203. if (typeName != wantTypeName)
  3204. {
  3205. ReplaceRecord replaceRecord = { typeRef, wantTypeName };
  3206. mReplaceMap[typeRef->GetSrcStart()] = replaceRecord;
  3207. }
  3208. SetAndRestoreValue<bool> prevInTypeRef(mInTypeRef, true);
  3209. BfElementVisitor::Visit(typeRef);
  3210. }
  3211. void Visit(BfIdentifierNode* identifier)
  3212. {
  3213. String typeName = identifier->ToString();
  3214. String wantTypeName = GetTypeName(typeName);
  3215. if (typeName != wantTypeName)
  3216. {
  3217. ReplaceRecord replaceRecord = { identifier, wantTypeName };
  3218. mReplaceMap[identifier->GetSrcStart()] = replaceRecord;
  3219. }
  3220. BfElementVisitor::Visit(identifier);
  3221. }
  3222. void Visit(BfTypeDeclaration* typeDecl)
  3223. {
  3224. BfElementVisitor::Visit(typeDecl);
  3225. }
  3226. void Visit(BfTupleTypeRef* typeRef)
  3227. {
  3228. SetAndRestoreValue<bool> prevInTypeRef(mInTypeRef, true);
  3229. BfElementVisitor::Visit(typeRef);
  3230. }
  3231. void Visit(BfGenericInstanceTypeRef* typeRef)
  3232. {
  3233. SetAndRestoreValue<bool> prevInTypeRef(mInTypeRef, true);
  3234. BfElementVisitor::Visit(typeRef);
  3235. }
  3236. void Visit(BfMethodDeclaration* methodDecl)
  3237. {
  3238. SetAndRestoreValue<bool> prevInMethod(mInMethod, true);
  3239. BfElementVisitor::Visit(methodDecl);
  3240. }
  3241. void FixStr(String& source)
  3242. {
  3243. for (int i = 0; i < (int)source.length(); i++)
  3244. {
  3245. if (source[i] == '\r')
  3246. source.Remove(i--, 1);
  3247. }
  3248. }
  3249. void Fix()
  3250. {
  3251. mInMethod = false;
  3252. mInTypeRef = false;
  3253. for (auto typeDef : mBfSystem->mTypeDefs)
  3254. {
  3255. if (typeDef->mTypeDeclaration == NULL)
  3256. continue;
  3257. auto parser = typeDef->mTypeDeclaration->GetSourceData()->ToParserData();
  3258. String fileName = parser->mFileName;
  3259. String origFileName = parser->mFileName;
  3260. origFileName.Insert(3, "Orig_");
  3261. String source;
  3262. source.Insert(0, parser->mSrc, parser->mSrcLength);
  3263. String origSource = source;
  3264. FixStr(origSource);
  3265. RecursiveCreateDirectory(GetFileDir(origFileName));
  3266. FILE* fp = fopen(origFileName.c_str(), "w");
  3267. fwrite(origSource.c_str(), 1, (int)origSource.length(), fp);
  3268. fclose(fp);
  3269. VisitMembers(parser->mRootNode);
  3270. int ofs = 0;
  3271. for (auto& pair : mReplaceMap)
  3272. {
  3273. int origLen = pair.second.mNode->GetSrcLength();
  3274. source.Remove(pair.first + ofs, origLen);
  3275. source.Insert(pair.first + ofs, pair.second.mNewStr);
  3276. ofs += (int)pair.second.mNewStr.length() - origLen;
  3277. }
  3278. mReplaceMap.clear();
  3279. FixStr(source);
  3280. fp = fopen(fileName.c_str(), "w");
  3281. fwrite(source.c_str(), 1, (int)source.length(), fp);
  3282. fclose(fp);
  3283. }
  3284. }
  3285. };
  3286. BF_EXPORT void BF_CALLTYPE BfSystem_FixTypes(BfSystem* bfSystem)
  3287. {
  3288. FixTypesHelper fixTypesHelper;
  3289. fixTypesHelper.mBfSystem = bfSystem;
  3290. fixTypesHelper.Fix();
  3291. }