BfParser.cpp 88 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615
  1. #pragma warning(disable:4996)
  2. #include "BfParser.h"
  3. #include "BfReducer.h"
  4. #include "BfPrinter.h"
  5. #include "BfDefBuilder.h"
  6. #include "BfCompiler.h"
  7. #include "BfSourceClassifier.h"
  8. #include "BfSourcePositionFinder.h"
  9. #include <sstream>
  10. #include "BeefySysLib/util/PerfTimer.h"
  11. #include "BeefySysLib/util/BeefPerf.h"
  12. #include "BeefySysLib/util/UTF8.h"
  13. #include "BfAutoComplete.h"
  14. #include "BfResolvePass.h"
  15. #include "BfElementVisitor.h"
  16. #include "BeefySysLib/util/UTF8.h"
  17. extern "C"
  18. {
  19. #include "BeefySysLib/third_party/utf8proc/utf8proc.h"
  20. }
  21. #include "BeefySysLib/util/AllocDebug.h"
  22. USING_NS_BF;
  23. static bool IsWhitespace(char c)
  24. {
  25. return (c == ' ') || (c == '\t') || (c == '\n') || (c == '\r');
  26. }
  27. static bool IsWhitespaceOrPunctuation(char c)
  28. {
  29. switch (c)
  30. {
  31. case ',':
  32. case ';':
  33. case ':':
  34. case '(':
  35. case ')':
  36. case '[':
  37. case ']':
  38. case '{':
  39. case '}':
  40. case '<':
  41. case '>':
  42. case '/':
  43. case '-':
  44. case '=':
  45. case '+':
  46. case '!':
  47. case '%':
  48. case '&':
  49. case '|':
  50. case '#':
  51. case '@':
  52. case '`':
  53. case '^':
  54. case '~':
  55. case '*':
  56. case '?':
  57. case '\n':
  58. case ' ':
  59. case '\t':
  60. case '\v':
  61. case '\f':
  62. case '\r':
  63. return true;
  64. default:
  65. return false;
  66. }
  67. }
  68. BfParser* BfParserData::ToParser()
  69. {
  70. if (mUniqueParser != NULL)
  71. {
  72. BF_ASSERT(mUniqueParser->mOrigSrcLength >= 0);
  73. BF_ASSERT((mUniqueParser->mCursorIdx >= -1) || (mUniqueParser->mCursorIdx <= mUniqueParser->mOrigSrcLength));
  74. }
  75. return mUniqueParser;
  76. }
  77. //////////////////////////////////////////////////////////////////////////
  78. /// raw_null_ostream - A raw_ostream that discards all output.
  79. /*class debug_ostream : public llvm::raw_ostream
  80. {
  81. /// write_impl - See raw_ostream::write_impl.
  82. void write_impl(const char *Ptr, size_t size) override
  83. {
  84. char str[256] = {0};
  85. memcpy(str, Ptr, std::min((int)size, 255));
  86. OutputDebugStr(str);
  87. }
  88. /// current_pos - Return the current position within the stream, not
  89. /// counting the bytes currently in the buffer.
  90. uint64_t current_pos() const override
  91. {
  92. return 0;
  93. }
  94. };*/
  95. //////////////////////////////////////////////////////////////////////////
  96. BfParserCache* Beefy::gBfParserCache = NULL;
  97. bool BfParserCache::DataEntry::operator==(const LookupEntry& lookup) const
  98. {
  99. if ((mParserData->mFileName == lookup.mFileName) &&
  100. (mParserData->mSrcLength == lookup.mSrcLength) &&
  101. (memcmp(mParserData->mSrc, lookup.mSrc, lookup.mSrcLength) == 0))
  102. {
  103. for (auto& setDefine : mParserData->mDefines_Def)
  104. if (!lookup.mProject->mPreprocessorMacros.Contains(setDefine))
  105. return false;
  106. for (auto& setDefine : mParserData->mDefines_NoDef)
  107. if (lookup.mProject->mPreprocessorMacros.Contains(setDefine))
  108. return false;
  109. return true;
  110. }
  111. return false;
  112. }
  113. BfParserCache::BfParserCache()
  114. {
  115. mRefCount = 0;
  116. }
  117. BfParserCache::~BfParserCache()
  118. {
  119. for (auto& entry : mEntries)
  120. {
  121. BF_ASSERT(entry.mParserData->mRefCount == 0);
  122. delete entry.mParserData;
  123. }
  124. }
  125. void BfParserCache::ReportMemory(MemReporter* memReporter)
  126. {
  127. int srcLen = 0;
  128. int allocBytesUsed = 0;
  129. int largeAllocs = 0;
  130. for (auto& entry : mEntries)
  131. {
  132. auto parserData = entry.mParserData;
  133. parserData->ReportMemory(memReporter);
  134. srcLen += parserData->mSrcLength;
  135. allocBytesUsed += (int)(parserData->mAlloc.mPages.size() * BfAstAllocManager::PAGE_SIZE);
  136. largeAllocs += parserData->mAlloc.mLargeAllocSizes;
  137. }
  138. int allocPages = 0;
  139. int usedPages = 0;
  140. mAstAllocManager.GetStats(allocPages, usedPages);
  141. OutputDebugStrF("Parsers: %d Chars: %d UsedAlloc: %dk BytesPerChar: %d SysAllocPages: %d SysUsedPages: %d (%dk) LargeAllocs: %dk\n", (int)mEntries.size(), srcLen, allocBytesUsed / 1024,
  142. allocBytesUsed / BF_MAX(1, srcLen), allocPages, usedPages, (usedPages * BfAstAllocManager::PAGE_SIZE) / 1024, largeAllocs / 1024);
  143. //memReporter->AddBumpAlloc("BumpAlloc", mAstAllocManager);
  144. }
  145. void BfParserData::ReportMemory(MemReporter* memReporter)
  146. {
  147. memReporter->Add("JumpTable", mJumpTableSize * sizeof(BfLineStartEntry));
  148. memReporter->Add("Source", mSrcLength);
  149. memReporter->AddBumpAlloc("AstAlloc", mAlloc);
  150. }
  151. static int DecodeInt(uint8* buf, int& idx)
  152. {
  153. int value = 0;
  154. int shift = 0;
  155. int curByte;
  156. do
  157. {
  158. curByte = buf[idx++];
  159. value |= ((curByte & 0x7f) << shift);
  160. shift += 7;
  161. } while (curByte >= 128);
  162. // Sign extend negative numbers.
  163. if (((curByte & 0x40) != 0) && (shift < 64))
  164. value |= ~0LL << shift;
  165. return value;
  166. }
  167. static int gCurDataId = 0;
  168. BfParserData::BfParserData()
  169. {
  170. mDataId = (int)BfpSystem_InterlockedExchangeAdd32((uint32*)&gCurDataId, 1) + 1;
  171. mHash = 0;
  172. mRefCount = -1;
  173. mJumpTable = NULL;
  174. mJumpTableSize = 0;
  175. mFailed = false;
  176. mCharIdData = NULL;
  177. mUniqueParser = NULL;
  178. mDidReduce = false;
  179. }
  180. BfParserData::~BfParserData()
  181. {
  182. delete[] mJumpTable;
  183. delete[] mCharIdData;
  184. }
  185. int BfParserData::GetCharIdAtIndex(int findIndex)
  186. {
  187. if (mCharIdData == NULL)
  188. return findIndex;
  189. int encodeIdx = 0;
  190. int charId = 1;
  191. int charIdx = 0;
  192. while (true)
  193. {
  194. int cmd = DecodeInt(mCharIdData, encodeIdx);
  195. if (cmd > 0)
  196. charId = cmd;
  197. else
  198. {
  199. int spanSize = -cmd;
  200. if ((findIndex >= charIdx) && (findIndex < charIdx + spanSize))
  201. return charId + (findIndex - charIdx);
  202. charId += spanSize;
  203. charIdx += spanSize;
  204. if (cmd == 0)
  205. return -1;
  206. }
  207. }
  208. }
  209. void BfParserData::GetLineCharAtIdx(int idx, int& line, int& lineChar)
  210. {
  211. auto* jumpEntry = mJumpTable + (idx / PARSER_JUMPTABLE_DIVIDE);
  212. if (jumpEntry->mCharIdx > idx)
  213. jumpEntry--;
  214. line = jumpEntry->mLineNum;
  215. lineChar = 0;
  216. int curSrcPos = jumpEntry->mCharIdx;
  217. while (curSrcPos < idx)
  218. {
  219. if (mSrc[curSrcPos] == '\n')
  220. {
  221. line++;
  222. lineChar = 0;
  223. }
  224. else
  225. {
  226. lineChar++;
  227. }
  228. curSrcPos++;
  229. }
  230. }
  231. bool BfParserData::IsUnwarnedAt(BfAstNode* node)
  232. {
  233. if (mUnwarns.empty())
  234. return false;
  235. auto unwarnItr = mUnwarns.upper_bound(node->GetSrcStart());
  236. if (unwarnItr == mUnwarns.begin())
  237. return false;
  238. unwarnItr--;
  239. int unwarnIdx = *unwarnItr;
  240. int checkIdx = node->GetSrcStart();
  241. int lineCount = 0;
  242. while (checkIdx > 0)
  243. {
  244. checkIdx--;
  245. if (checkIdx < unwarnIdx)
  246. return true;
  247. if (mSrc[checkIdx] == '\n')
  248. {
  249. lineCount++;
  250. // #unwarn must be immediately preceding the start of the statement containing this node
  251. if (lineCount == 2)
  252. return false;
  253. }
  254. }
  255. return true;
  256. }
  257. bool BfParserData::IsWarningEnabledAtSrcIndex(int warningNumber, int srcIdx)
  258. {
  259. bool enabled = true; //CDH TODO if/when we add warning level support, this default will change based on the warning number and the general project warning level setting
  260. int lastUnwarnPos = 0;
  261. for (const auto& it : mWarningEnabledChanges)
  262. {
  263. if (it.mKey > srcIdx)
  264. break;
  265. if (it.mValue.mWarningNumber == warningNumber)
  266. enabled = it.mValue.mEnable;
  267. if (it.mValue.mWarningNumber == -1)
  268. lastUnwarnPos = -1;
  269. }
  270. return enabled;
  271. }
  272. void BfParserData::Deref()
  273. {
  274. mRefCount--;
  275. BF_ASSERT(mRefCount >= 0);
  276. if (mRefCount == 0)
  277. {
  278. AutoCrit autoCrit(gBfParserCache->mCritSect);
  279. BfParserCache::DataEntry dataEntry;
  280. dataEntry.mParserData = this;
  281. bool didRemove = gBfParserCache->mEntries.Remove(dataEntry);
  282. BF_ASSERT(didRemove);
  283. delete this;
  284. }
  285. }
  286. //////////////////////////////////////////////////////////////////////////
  287. static int gParserCount = 0;
  288. BfParser::BfParser(BfSystem* bfSystem, BfProject* bfProject) : BfSource(bfSystem)
  289. {
  290. BfLogSys(bfSystem, "BfParser::BfParser %08X\n", this);
  291. gParserCount++;
  292. mUsingCache = false;
  293. mParserData = NULL;
  294. mAwaitingDelete = false;
  295. mScanOnly = false;
  296. mCompleteParse = false;
  297. mJumpTable = NULL;
  298. mProject = bfProject;
  299. mPassInstance = NULL;
  300. mPassInstance = NULL;
  301. mPrevRevision = NULL;
  302. mNextRevision = NULL;
  303. mOrigSrcLength = 0;
  304. mSrcAllocSize = -1;
  305. mSrcLength = 0;
  306. mSrcIdx = 0;
  307. mParserFlags = ParserFlag_None;
  308. mCursorIdx = -1;
  309. mCursorCheckIdx = -1;
  310. mLineStart = 0;
  311. //mCurToken = (BfSyntaxToken)0;
  312. mToken = BfToken_None;
  313. mSyntaxToken = BfSyntaxToken_Token;
  314. mTokenStart = 0;
  315. mTokenEnd = 0;
  316. mLineNum = 0;
  317. mCompatMode = false;
  318. mQuickCompatMode = false;
  319. mLiteral.mWarnType = 0;
  320. mDataId = -1;
  321. mTriviaStart = 0;
  322. mParsingFailed = false;
  323. mInAsmBlock = false;
  324. mPreprocessorIgnoredSectionNode = NULL;
  325. mPreprocessorIgnoreDepth = 0;
  326. if (bfProject != NULL)
  327. {
  328. for (auto macro : bfProject->mPreprocessorMacros)
  329. mPreprocessorDefines[macro] = BfDefineState_FromProject;
  330. }
  331. }
  332. //static std::set<BfAstNode*> gFoundNodes;
  333. BfParser::~BfParser()
  334. {
  335. int parserCount = gParserCount--;
  336. if (mParserData->mRefCount == -1)
  337. {
  338. // Owned data, never intended for cache
  339. mParserData->mSrc = NULL; // Count on BfSource dtor to release strc
  340. delete mParserData;
  341. }
  342. else if (mParserData->mRefCount == 0)
  343. {
  344. // Just never got added to the cache
  345. delete mParserData;
  346. }
  347. else
  348. {
  349. mParserData->Deref();
  350. }
  351. mSourceData = NULL;
  352. BfLogSys(mSystem, "BfParser::~BfParser %p\n", this);
  353. }
  354. void BfParser::SetCursorIdx(int cursorIdx)
  355. {
  356. mCursorIdx = cursorIdx;
  357. mCursorCheckIdx = cursorIdx;
  358. int checkIdx = cursorIdx;
  359. while (checkIdx > 0)
  360. {
  361. char c = mSrc[checkIdx - 1];
  362. if (!IsWhitespace(c))
  363. {
  364. if (c == '.')
  365. mCursorCheckIdx = checkIdx;
  366. break;
  367. }
  368. checkIdx--;
  369. }
  370. }
  371. //static int gDeleteCount = 0;
  372. //static int gIndentCount = 0;
  373. void BfParser::GetLineCharAtIdx(int idx, int& line, int& lineChar)
  374. {
  375. mParserData->GetLineCharAtIdx(idx, line, lineChar);
  376. }
  377. void BfParser::Fail(const StringImpl& error, int offset)
  378. {
  379. mPassInstance->FailAt(error, mSourceData, mSrcIdx + offset);
  380. }
  381. void BfParser::TokenFail(const StringImpl& error, int offset)
  382. {
  383. if (mPreprocessorIgnoredSectionNode == NULL)
  384. Fail(error, offset);
  385. }
  386. void BfParser::Init(uint64 cacheHash)
  387. {
  388. BF_ASSERT(mParserData == NULL);
  389. mParserData = new BfParserData();
  390. mSourceData = mParserData;
  391. mParserData->mFileName = mFileName;
  392. if (mDataId != -1)
  393. mParserData->mDataId = mDataId;
  394. else
  395. mDataId = mParserData->mDataId;
  396. mParserData->mAstAllocManager = &gBfParserCache->mAstAllocManager;
  397. mParserData->mSrc = mSrc;
  398. mParserData->mSrcLength = mSrcLength;
  399. if (cacheHash != 0)
  400. {
  401. BfLogSysM("Creating cached parserData %p for %p %s\n", mParserData, this, mFileName.c_str());
  402. mParserData->mHash = cacheHash;
  403. mParserData->mRefCount = 0; // 0 means we want to EVENTUALLY write it to the cache
  404. mSrcAllocSize = -1;
  405. }
  406. else
  407. {
  408. BfLogSysM("Creating unique parserData %p for %p %s\n", mParserData, this, mFileName.c_str());
  409. mParserData->mUniqueParser = this;
  410. }
  411. mJumpTableSize = ((mSrcLength + 1) + PARSER_JUMPTABLE_DIVIDE - 1) / PARSER_JUMPTABLE_DIVIDE;
  412. mJumpTable = new BfLineStartEntry[mJumpTableSize];
  413. memset(mJumpTable, 0, mJumpTableSize * sizeof(BfLineStartEntry));
  414. mParserData->mJumpTable = mJumpTable;
  415. mParserData->mJumpTableSize = mJumpTableSize;
  416. mAlloc = &mParserData->mAlloc;
  417. mAlloc->mSourceData = mSourceData;
  418. }
  419. void BfParser::NewLine()
  420. {
  421. mLineStart = mSrcIdx;
  422. mLineNum++;
  423. int idx = (mSrcIdx / PARSER_JUMPTABLE_DIVIDE);
  424. if (idx == 0)
  425. return;
  426. BF_ASSERT(idx < mJumpTableSize);
  427. BfLineStartEntry* jumpTableEntry = mJumpTable + idx;
  428. jumpTableEntry->mCharIdx = mSrcIdx;
  429. jumpTableEntry->mLineNum = mLineNum;
  430. }
  431. void BfParser::SetSource(const char* data, int length)
  432. {
  433. const int EXTRA_BUFFER_SIZE = 80; // Extra chars for a bit of AllocChars room
  434. //TODO: Check cache
  435. // Don't cache if we have a Cursorid set,
  436. // if mDataId != -1
  437. // if BfParerFlag != 0
  438. bool canCache = true;
  439. if (mDataId != -1)
  440. canCache = false;
  441. if (mParserFlags != 0)
  442. canCache = false;
  443. if (mCursorIdx != -1)
  444. canCache = false;
  445. if (mCompatMode)
  446. canCache = false;
  447. if (mQuickCompatMode)
  448. canCache = false;
  449. if (mFileName.IsEmpty())
  450. canCache = false;
  451. if (mProject == NULL)
  452. canCache = false;
  453. uint64 cacheHash = 0;
  454. if (canCache)
  455. {
  456. AutoCrit autoCrit(gBfParserCache->mCritSect);
  457. HashContext hashCtx;
  458. hashCtx.MixinStr(mFileName);
  459. hashCtx.Mixin(data, length);
  460. cacheHash = hashCtx.Finish64();
  461. BfParserCache::LookupEntry lookupEntry;
  462. lookupEntry.mFileName = mFileName;
  463. lookupEntry.mSrc = data;
  464. lookupEntry.mSrcLength = length;
  465. lookupEntry.mHash = cacheHash;
  466. lookupEntry.mProject = mProject;
  467. BfParserCache::DataEntry* dataEntryP;
  468. if (gBfParserCache->mEntries.TryGetWith(lookupEntry, &dataEntryP))
  469. {
  470. mUsingCache = true;
  471. mParserData = dataEntryP->mParserData;
  472. BF_ASSERT(mParserData->mDidReduce);
  473. BfLogSysM("Using cached parserData %p for %p %s\n", mParserData, this, mFileName.c_str());
  474. mParserData->mRefCount++;
  475. mSourceData = mParserData;
  476. mSrc = mParserData->mSrc;
  477. mSrcLength = mParserData->mSrcLength;
  478. mOrigSrcLength = mParserData->mSrcLength;
  479. mSrcAllocSize = -1;
  480. mSrcIdx = 0;
  481. mJumpTable = mParserData->mJumpTable;
  482. mJumpTableSize = mParserData->mJumpTableSize;
  483. mAlloc = &mParserData->mAlloc;
  484. return;
  485. }
  486. }
  487. mSrcLength = length;
  488. mOrigSrcLength = length;
  489. mSrcAllocSize = mSrcLength /*+ EXTRA_BUFFER_SIZE*/;
  490. char* ownedSrc = new char[mSrcAllocSize + 1];
  491. memcpy(ownedSrc, data, length);
  492. ownedSrc[length] = 0;
  493. mSrc = ownedSrc;
  494. mSrcIdx = 0;
  495. Init(cacheHash);
  496. }
  497. void BfParser::MoveSource(const char* data, int length) // Takes ownership of data ptr
  498. {
  499. mSrcLength = length;
  500. mOrigSrcLength = length;
  501. mSrcAllocSize = mSrcLength;
  502. mSrc = data;
  503. mSrcIdx = 0;
  504. Init();
  505. }
  506. void BfParser::RefSource(const char* data, int length)
  507. {
  508. mSrcLength = length;
  509. mOrigSrcLength = length;
  510. mSrcAllocSize = -1;
  511. mSrc = data;
  512. mSrcIdx = 0;
  513. Init();
  514. }
  515. bool BfParser::SrcPtrHasToken(const char* name)
  516. {
  517. const char* namePtr = name;
  518. int checkIdx = mSrcIdx - 1;
  519. while (*namePtr)
  520. {
  521. if (*(namePtr++) != mSrc[checkIdx])
  522. return false;
  523. checkIdx++;
  524. }
  525. if (!IsWhitespaceOrPunctuation(mSrc[checkIdx]))
  526. return false;
  527. mSrcIdx = checkIdx;
  528. mTokenEnd = checkIdx;
  529. return true;
  530. }
  531. void BfParser::AddErrorNode(int startIdx, int endIdx)
  532. {
  533. auto identifierNode = mAlloc->Alloc<BfIdentifierNode>();
  534. identifierNode->Init(mTriviaStart, startIdx, endIdx);
  535. //identifierNode->mSource = this;
  536. BfSource::AddErrorNode(identifierNode);
  537. }
  538. BfCommentKind BfParser::GetCommentKind(int startIdx)
  539. {
  540. if (((mSrc[startIdx] == '/') && (mSrc[startIdx + 1] == '*') && (mSrc[startIdx + 2] == '*') && (mSrc[startIdx + 3] == '<')) ||
  541. ((mSrc[startIdx] == '/') && (mSrc[startIdx + 1] == '/') && (mSrc[startIdx + 2] == '/') && (mSrc[startIdx + 3] == '<')))
  542. {
  543. return BfCommentKind_Documentation_Post;
  544. }
  545. if (((mSrc[startIdx] == '/') && (mSrc[startIdx + 1] == '*') && (mSrc[startIdx + 2] == '*') && (mSrc[startIdx + 3] != '/')) ||
  546. ((mSrc[startIdx] == '/') && (mSrc[startIdx + 1] == '/') && (mSrc[startIdx + 2] == '/') && (mSrc[startIdx + 3] != '/')))
  547. {
  548. return BfCommentKind_Documentation_Pre;
  549. }
  550. return BfCommentKind_Normal;
  551. }
  552. bool BfParser::EvaluatePreprocessor(BfExpression* expr)
  553. {
  554. bool isInvalid = false;
  555. if (expr == NULL)
  556. return false;
  557. if (auto binaryOp = BfNodeDynCast<BfBinaryOperatorExpression>(expr))
  558. {
  559. switch (binaryOp->mOp)
  560. {
  561. case BfBinaryOp_ConditionalOr:
  562. return EvaluatePreprocessor(binaryOp->mLeft) || EvaluatePreprocessor(binaryOp->mRight);
  563. case BfBinaryOp_ConditionalAnd:
  564. return EvaluatePreprocessor(binaryOp->mLeft) && EvaluatePreprocessor(binaryOp->mRight);
  565. default: break;
  566. }
  567. }
  568. if (auto unaryOp = BfNodeDynCast<BfUnaryOperatorExpression>(expr))
  569. {
  570. switch (unaryOp->mOp)
  571. {
  572. case BfUnaryOp_Not:
  573. return !EvaluatePreprocessor(unaryOp->mExpression);
  574. default: break;
  575. }
  576. }
  577. if (auto identifier = BfNodeDynCast<BfIdentifierNode>(expr))
  578. {
  579. return HandleIfDef(identifier->ToString()) == MaybeBool_True;
  580. }
  581. if (auto parenExpr = BfNodeDynCast<BfParenthesizedExpression>(expr))
  582. {
  583. return EvaluatePreprocessor(parenExpr->mExpression);
  584. }
  585. if (auto literalExpr = BfNodeDynCast<BfLiteralExpression>(expr))
  586. {
  587. if (literalExpr->mValue.mTypeCode == BfTypeCode_Boolean)
  588. {
  589. return literalExpr->mValue.mBool;
  590. }
  591. }
  592. mPassInstance->Fail("Invalid preprocessor expression", expr);
  593. return false;
  594. }
  595. BfBlock* BfParser::ParseInlineBlock(int spaceIdx, int endIdx)
  596. {
  597. BfBlock* block = NULL;
  598. SizedArray<BfAstNode*, 8> childArr;
  599. mSrcIdx = spaceIdx;
  600. BfAstNode* startNode = NULL;
  601. int usedEndIdx = spaceIdx;
  602. while (true)
  603. {
  604. NextToken(endIdx + 1);
  605. if (mSyntaxToken == BfSyntaxToken_HIT_END_IDX)
  606. {
  607. mSrcIdx = usedEndIdx;
  608. auto lastNode = mSidechannelRootNode->GetLast();
  609. if (lastNode != NULL)
  610. mSrcIdx = std::max(mSrcIdx, lastNode->GetSrcEnd());
  611. break;
  612. }
  613. usedEndIdx = mSrcIdx;
  614. auto childNode = CreateNode();
  615. if (childNode == NULL)
  616. break;
  617. if ((childNode->IsA<BfCommentNode>()))
  618. {
  619. mSidechannelRootNode->Add(childNode);
  620. mPendingSideNodes.push_back(childNode);
  621. continue;
  622. }
  623. if (startNode == NULL)
  624. startNode = childNode;
  625. if (block == NULL)
  626. block = mAlloc->Alloc<BfBlock>();
  627. block->Add(childNode);
  628. childArr.push_back(childNode);
  629. //block->mChildArr.Add(childNode, &mAlloc);
  630. }
  631. if (block != NULL)
  632. block->Init(childArr, mAlloc);
  633. return block;
  634. }
  635. BfExpression* BfParser::CreateInlineExpressionFromNode(BfBlock* block)
  636. {
  637. BfReducer reducer;
  638. reducer.mPassInstance = mPassInstance;
  639. reducer.mAlloc = mAlloc;
  640. reducer.mCompatMode = mCompatMode;
  641. reducer.mVisitorPos = BfReducer::BfVisitorPos(block);
  642. reducer.mVisitorPos.MoveNext();
  643. auto startNode = reducer.mVisitorPos.GetCurrent();
  644. if (startNode == NULL)
  645. return NULL;
  646. auto paramExpression = reducer.CreateExpression(startNode);
  647. if ((paramExpression != NULL) && (reducer.mVisitorPos.GetNext() != NULL))
  648. mPassInstance->Fail("Expression parsing error", reducer.mVisitorPos.GetNext());
  649. return paramExpression;
  650. }
  651. void BfParser::HandlePragma(const StringImpl& pragma, BfBlock* block)
  652. {
  653. auto itr = block->begin();
  654. auto paramNode = *itr;
  655. if (paramNode->ToString() == "warning")
  656. {
  657. ++itr;
  658. //auto iterNode = paramNode->mNext;
  659. //BfAstNode* iterNode = parentNode->mChildArr.GetAs<BfAstNode*>(++curIdx);
  660. BfAstNode* iterNode = itr.Get();
  661. if (iterNode)
  662. {
  663. ++itr;
  664. bool enable;
  665. if (iterNode->ToString() == "disable")
  666. {
  667. enable = false;
  668. }
  669. else if (iterNode->ToString() == "restore")
  670. {
  671. enable = true;
  672. }
  673. else
  674. {
  675. enable = true;
  676. mPassInstance->FailAt("Expected \"disable\" or \"restore\" after \"warning\"", mSourceData, iterNode->GetSrcStart(), iterNode->GetSrcLength());
  677. }
  678. //iterNode = parentNode->mChildArr.GetAs<BfAstNode*>(++curIdx);
  679. iterNode = itr.Get();
  680. while (iterNode)
  681. {
  682. ++itr;
  683. auto tokenStr = iterNode->ToString();
  684. if (tokenStr != ",") // commas allowed between warning numbers but not required; we just ignore them
  685. {
  686. bool isNum = true;
  687. for (const auto it : tokenStr)
  688. {
  689. char c = it;
  690. if (c < '0' || c > '9')
  691. {
  692. isNum = false;
  693. break;
  694. }
  695. }
  696. if (isNum)
  697. {
  698. BfParserWarningEnabledChange wec;
  699. wec.mEnable = enable;
  700. wec.mWarningNumber = atoi(tokenStr.c_str());
  701. mParserData->mWarningEnabledChanges[iterNode->GetSrcStart()] = wec;
  702. }
  703. else
  704. {
  705. mPassInstance->FailAt("Expected decimal warning number", mSourceData, iterNode->GetSrcStart(), iterNode->GetSrcLength());
  706. }
  707. }
  708. //iterNode = parentNode->mChildArr.Get(++curIdx);
  709. iterNode = itr.Get();
  710. }
  711. }
  712. else
  713. {
  714. mPassInstance->FailAfterAt("Expected \"disable\" or \"restore\" after \"warning\"", mSourceData, paramNode->GetSrcEnd() - 1);
  715. }
  716. }
  717. else
  718. {
  719. mPassInstance->FailAt("Unknown #pragma directive", mSourceData, paramNode->GetSrcStart(), paramNode->GetSrcLength());
  720. }
  721. }
  722. void BfParser::HandleDefine(const StringImpl& name, BfAstNode* paramNode)
  723. {
  724. mPreprocessorDefines[name] = BfDefineState_ManualSet;
  725. }
  726. void BfParser::HandleUndefine(const StringImpl& name)
  727. {
  728. mPreprocessorDefines[name] = BfDefineState_ManualUnset;
  729. }
  730. MaybeBool BfParser::HandleIfDef(const StringImpl& name)
  731. {
  732. BfDefineState defineState;
  733. if (mPreprocessorDefines.TryGetValue(name, &defineState))
  734. {
  735. if (defineState == BfDefineState_FromProject)
  736. {
  737. mParserData->mDefines_Def.Add(name);
  738. }
  739. return (defineState != BfDefineState_ManualUnset) ? MaybeBool_True : MaybeBool_False;
  740. }
  741. else
  742. {
  743. mParserData->mDefines_NoDef.Add(name);
  744. return MaybeBool_False;
  745. }
  746. }
  747. MaybeBool BfParser::HandleProcessorCondition(BfBlock* paramNode)
  748. {
  749. if (paramNode == NULL)
  750. return MaybeBool_False;
  751. bool found = false;
  752. auto paramExpression = CreateInlineExpressionFromNode(paramNode);
  753. if (paramExpression != NULL)
  754. {
  755. return EvaluatePreprocessor(paramExpression) ? MaybeBool_True : MaybeBool_False;
  756. }
  757. return MaybeBool_False;
  758. }
  759. void BfParser::HandleInclude(BfAstNode* paramNode)
  760. {
  761. }
  762. void BfParser::HandleIncludeNext(BfAstNode* paramNode)
  763. {
  764. }
  765. void BfParser::HandlePreprocessor()
  766. {
  767. int triviaStart = mTriviaStart;
  768. int checkIdx = 0;
  769. for (int checkIdx = mLineStart; checkIdx < mSrcIdx - 1; checkIdx++)
  770. {
  771. if (!isspace((uint8)mSrc[checkIdx]))
  772. {
  773. if (mPreprocessorIgnoreDepth == 0)
  774. {
  775. mPassInstance->FailAt("Preprocessor directives must appear as the first non-whitespace character on a line", mSourceData, checkIdx);
  776. break;
  777. }
  778. else
  779. continue; // Keep searching for #endif
  780. }
  781. }
  782. String pragma;
  783. String pragmaParam;
  784. bool atEnd = false;
  785. int startIdx = mSrcIdx - 1;
  786. int spaceIdx = -1;
  787. int charIdx = -1;
  788. while (true)
  789. {
  790. char c = mSrc[mSrcIdx++];
  791. if (c == '\n')
  792. {
  793. int checkIdx = mSrcIdx - 2;
  794. bool hadSlash = false;
  795. while (checkIdx >= startIdx)
  796. {
  797. char checkC = mSrc[checkIdx];
  798. if (checkC == '\\')
  799. {
  800. hadSlash = true;
  801. break;
  802. }
  803. if ((checkC != ' ') && (checkC != '\t'))
  804. break;
  805. checkIdx--;
  806. }
  807. if (!hadSlash)
  808. break;
  809. }
  810. if (c == '\0')
  811. {
  812. mSrcIdx--;
  813. break;
  814. }
  815. if (charIdx == -1)
  816. {
  817. if (!IsWhitespaceOrPunctuation(c))
  818. charIdx = mSrcIdx - 1;
  819. }
  820. else if ((IsWhitespaceOrPunctuation(c)) && (spaceIdx == -1))
  821. spaceIdx = mSrcIdx - 1;
  822. }
  823. if (charIdx == -1)
  824. {
  825. mPassInstance->FailAt("Preprocessor directive expected", mSourceData, startIdx);
  826. return;
  827. }
  828. int endIdx = mSrcIdx - 1;
  829. while (endIdx >= startIdx)
  830. {
  831. if (!IsWhitespace(mSrc[endIdx]))
  832. break;
  833. endIdx--;
  834. }
  835. BfBlock* paramNode = NULL;
  836. if (spaceIdx != -1)
  837. {
  838. pragma = String(mSrc + charIdx, mSrc + spaceIdx);
  839. int breakIdx = spaceIdx;
  840. while (spaceIdx <= endIdx)
  841. {
  842. if (!isspace((uint8)mSrc[spaceIdx]))
  843. break;
  844. spaceIdx++;
  845. }
  846. if (spaceIdx <= endIdx)
  847. pragmaParam = String(mSrc + spaceIdx, mSrc + endIdx + 1);
  848. paramNode = ParseInlineBlock(breakIdx, endIdx);
  849. }
  850. else
  851. {
  852. pragma = String(mSrc + charIdx, mSrc + endIdx + 1);
  853. mSrcIdx = endIdx + 1;
  854. }
  855. bool wantsSingleParam = true;
  856. bool addToPreprocessorAccept = false;
  857. bool addToPreprocessorAcceptResolved = true;
  858. bool wantedParam = false;
  859. if (mPreprocessorIgnoreDepth > 0)
  860. {
  861. BF_ASSERT(!mPreprocessorNodeStack.empty());
  862. int ignoreEnd = std::max(mPreprocessorIgnoredSectionNode->GetSrcStart(), mLineStart - 1);
  863. if (pragma == "endif")
  864. {
  865. mPreprocessorIgnoreDepth--;
  866. if (mPreprocessorIgnoreDepth > 0)
  867. return;
  868. mPreprocessorNodeStack.pop_back();
  869. mPreprocessorIgnoredSectionNode->SetSrcEnd(ignoreEnd);
  870. mPreprocessorIgnoredSectionNode = NULL;
  871. triviaStart = ignoreEnd;
  872. }
  873. else if ((pragma == "if") ||
  874. ((mCompatMode) && (pragma == "ifdef")) ||
  875. ((mCompatMode) && (pragma == "ifndef")))
  876. {
  877. wantsSingleParam = false;
  878. wantedParam = true;
  879. mPreprocessorIgnoreDepth++;
  880. }
  881. else if (pragma == "else")
  882. {
  883. if (mCompatMode)
  884. {
  885. if (paramNode != NULL)
  886. {
  887. if (paramNode->ToString() == "if")
  888. {
  889. bool found = HandleProcessorCondition(paramNode) != MaybeBool_False;
  890. if (found)
  891. {
  892. addToPreprocessorAccept = true;
  893. mPreprocessorNodeStack.pop_back();
  894. mPreprocessorIgnoreDepth = 0;
  895. mPreprocessorIgnoredSectionNode->SetSrcEnd(ignoreEnd);
  896. mPreprocessorIgnoredSectionNode = NULL;
  897. triviaStart = ignoreEnd;
  898. }
  899. else
  900. {
  901. mPreprocessorIgnoredSectionStarts.insert(mSrcIdx);
  902. }
  903. return;
  904. }
  905. }
  906. }
  907. if ((mPreprocessorIgnoreDepth == 1) && !mPreprocessorNodeStack.back().second)
  908. {
  909. addToPreprocessorAccept = true;
  910. mPreprocessorNodeStack.pop_back();
  911. mPreprocessorIgnoreDepth = 0;
  912. mPreprocessorIgnoredSectionNode->SetSrcEnd(ignoreEnd);
  913. mPreprocessorIgnoredSectionNode = NULL;
  914. triviaStart = ignoreEnd;
  915. }
  916. }
  917. else if (pragma == "elif")
  918. {
  919. wantsSingleParam = false;
  920. if ((mPreprocessorIgnoreDepth == 1) && !mPreprocessorNodeStack.back().second)
  921. {
  922. wantedParam = true;
  923. bool found = HandleProcessorCondition(paramNode) != MaybeBool_False;
  924. if (found)
  925. {
  926. addToPreprocessorAccept = true;
  927. mPreprocessorNodeStack.pop_back();
  928. mPreprocessorIgnoreDepth = 0;
  929. mPreprocessorIgnoredSectionNode->SetSrcEnd(ignoreEnd);
  930. mPreprocessorIgnoredSectionNode = NULL;
  931. triviaStart = ignoreEnd;
  932. }
  933. else
  934. {
  935. mPreprocessorIgnoredSectionStarts.insert(mSrcIdx);
  936. }
  937. }
  938. }
  939. if (mPreprocessorIgnoreDepth > 0)
  940. return;
  941. }
  942. else
  943. {
  944. if ((pragma == "if") ||
  945. ((mCompatMode) && (pragma == "ifdef")) ||
  946. ((mCompatMode) && (pragma == "ifndef")))
  947. {
  948. wantsSingleParam = false;
  949. wantedParam = true;
  950. bool found = false;
  951. if (!mQuickCompatMode)
  952. {
  953. if (pragma == "if")
  954. found = HandleProcessorCondition(paramNode) != MaybeBool_False;
  955. else if (pragma == "ifdef")
  956. found = HandleIfDef(pragmaParam) != MaybeBool_False;
  957. else if (pragma == "ifndef")
  958. found = HandleIfDef(pragmaParam) != MaybeBool_True;
  959. }
  960. if (!found)
  961. mPreprocessorIgnoredSectionStarts.insert(mSrcIdx);
  962. addToPreprocessorAccept = true;
  963. if ((!found) && (!mQuickCompatMode) && (!mCompleteParse))
  964. {
  965. addToPreprocessorAcceptResolved = false;
  966. mPreprocessorIgnoreDepth = 1;
  967. }
  968. }
  969. else if (pragma == "else")
  970. {
  971. if (!mQuickCompatMode && !mCompleteParse)
  972. {
  973. if (mPreprocessorNodeStack.empty())
  974. mPassInstance->FailAt("Unexpected #else", mSourceData, startIdx, mSrcIdx - startIdx);
  975. else
  976. {
  977. BF_ASSERT(mPreprocessorNodeStack.back().second);
  978. mPreprocessorIgnoreDepth = 1;
  979. }
  980. }
  981. }
  982. else if (pragma == "elif")
  983. {
  984. wantsSingleParam = false;
  985. if (!mQuickCompatMode && !mCompleteParse)
  986. {
  987. if (mPreprocessorNodeStack.empty())
  988. mPassInstance->FailAt("Unexpected #elif", mSourceData, startIdx, mSrcIdx - startIdx);
  989. else
  990. {
  991. BF_ASSERT(mPreprocessorNodeStack.back().second);
  992. mPreprocessorIgnoreDepth = 1;
  993. }
  994. }
  995. wantedParam = true;
  996. }
  997. else if (pragma == "endif")
  998. {
  999. if (mPreprocessorNodeStack.empty())
  1000. mPassInstance->FailAt("Unexpected #endif", mSourceData, startIdx, mSrcIdx - startIdx);
  1001. else
  1002. mPreprocessorNodeStack.pop_back();
  1003. }
  1004. else if (pragma == "define")
  1005. {
  1006. HandleDefine(pragmaParam, paramNode);
  1007. wantedParam = true;
  1008. }
  1009. else if (pragma == "undef")
  1010. {
  1011. HandleUndefine(pragmaParam);
  1012. wantedParam = true;
  1013. }
  1014. else if (pragma == "error")
  1015. {
  1016. if (!mQuickCompatMode)
  1017. {
  1018. //TODO: Remove
  1019. //OutputDebugStrF("####################ERROR %s\n", pragmaParam.c_str());
  1020. }
  1021. mPassInstance->FailAt(pragmaParam, mSourceData, startIdx);
  1022. wantedParam = true;
  1023. }
  1024. else if (pragma == "warning")
  1025. {
  1026. wantsSingleParam = false;
  1027. mPassInstance->WarnAt(BfWarning_CS1030_PragmaWarning, pragmaParam, mSourceData, startIdx);
  1028. wantedParam = true;
  1029. }
  1030. else if (pragma == "region")
  1031. {
  1032. wantsSingleParam = false;
  1033. wantedParam = true;
  1034. }
  1035. else if (pragma == "endregion")
  1036. {
  1037. wantsSingleParam = false;
  1038. if (!pragmaParam.empty())
  1039. wantedParam = true;
  1040. }
  1041. else if (pragma == "pragma")
  1042. {
  1043. wantsSingleParam = false;
  1044. wantedParam = true;
  1045. if (paramNode != NULL)
  1046. HandlePragma(pragmaParam, paramNode);
  1047. }
  1048. else if (pragma == "unwarn")
  1049. {
  1050. mParserData->mUnwarns.insert(mSrcIdx);
  1051. }
  1052. else if ((mCompatMode) && (pragma == "include"))
  1053. {
  1054. HandleInclude(paramNode);
  1055. wantedParam = true;
  1056. }
  1057. else if ((mCompatMode) && (pragma == "include_next"))
  1058. {
  1059. HandleIncludeNext(paramNode);
  1060. wantedParam = true;
  1061. }
  1062. else
  1063. {
  1064. mPassInstance->FailAt("Unknown preprocessor directive", mSourceData, startIdx, mSrcIdx - startIdx);
  1065. }
  1066. }
  1067. if ((wantsSingleParam) && (paramNode != NULL) && (paramNode->mChildArr.size() > 1))
  1068. {
  1069. mPassInstance->FailAt("Only one parameter expected", mSourceData, paramNode->GetSrcStart(), paramNode->GetSrcLength());
  1070. }
  1071. if ((wantedParam) && (paramNode == NULL))
  1072. {
  1073. mPassInstance->FailAt("Expected parameter", mSourceData, startIdx, mSrcIdx - startIdx);
  1074. }
  1075. else if ((!wantedParam) && (paramNode != NULL))
  1076. {
  1077. mPassInstance->FailAt("Parameter not expected", mSourceData, startIdx, mSrcIdx - startIdx);
  1078. }
  1079. mTokenStart = charIdx;
  1080. mTokenEnd = charIdx + (int)pragma.length();
  1081. mTriviaStart = -1;
  1082. auto bfPreprocessorCmdNode = mAlloc->Alloc<BfIdentifierNode>();
  1083. bfPreprocessorCmdNode->Init(this);
  1084. mTriviaStart = triviaStart;
  1085. auto bfPreprocessorNode = mAlloc->Alloc<BfPreprocessorNode>();
  1086. mTokenStart = startIdx;
  1087. mTokenEnd = mSrcIdx;
  1088. bfPreprocessorNode->Init(this);
  1089. bfPreprocessorNode->Add(bfPreprocessorCmdNode);
  1090. bfPreprocessorNode->mCommand = bfPreprocessorCmdNode;
  1091. if (paramNode != NULL)
  1092. {
  1093. int curIdx = 0;
  1094. bfPreprocessorNode->mArgument = paramNode;
  1095. }
  1096. mPendingSideNodes.push_back(bfPreprocessorNode);
  1097. mTokenStart = mSrcIdx;
  1098. mTriviaStart = mSrcIdx;
  1099. triviaStart = mSrcIdx;
  1100. if (addToPreprocessorAccept)
  1101. mPreprocessorNodeStack.push_back(std::pair<BfAstNode*, bool>(bfPreprocessorNode, addToPreprocessorAcceptResolved));
  1102. if (mPreprocessorIgnoreDepth > 0)
  1103. {
  1104. mPreprocessorIgnoredSectionNode = mAlloc->Alloc<BfPreprocesorIgnoredSectionNode>();
  1105. mPreprocessorIgnoredSectionNode->Init(this);
  1106. mSidechannelRootNode->Add(mPreprocessorIgnoredSectionNode);
  1107. mPendingSideNodes.push_back(mPreprocessorIgnoredSectionNode);
  1108. }
  1109. }
  1110. static int ValSign(int64 val)
  1111. {
  1112. if (val < 0)
  1113. return -1;
  1114. if (val > 0)
  1115. return 1;
  1116. return 0;
  1117. }
  1118. template <int Len>
  1119. struct StrHashT
  1120. {
  1121. const static int HASH = 0;
  1122. };
  1123. template <>
  1124. struct StrHashT<4>
  1125. {
  1126. template <const char* Str>
  1127. struct DoHash
  1128. {
  1129. const static int HASH = (StrHashT<3>::HASH) ^ Str[4];
  1130. };
  1131. };
  1132. // This is little endian only
  1133. #define TOKEN_HASH(a, b, c, d) ((int)a << 0) | ((int)b << 8) | ((int)c << 16) | ((int)d << 24)
  1134. const int text_const = (1 << 2);
  1135. const int gClassConst = 0;
  1136. uint32 BfParser::GetTokenHash()
  1137. {
  1138. char hashChars[4] = { 0 };
  1139. int idx = 0;
  1140. uint32 tokenHash = 0;
  1141. int checkIdx = mSrcIdx - 1;
  1142. while ((!IsWhitespaceOrPunctuation(mSrc[checkIdx])) && (idx < 4))
  1143. {
  1144. hashChars[idx++] = mSrc[checkIdx];
  1145. checkIdx++;
  1146. }
  1147. return *((uint32*)hashChars);
  1148. }
  1149. double BfParser::ParseLiteralDouble()
  1150. {
  1151. char buf[256];
  1152. int len = std::min(mTokenEnd - mTokenStart, 255);
  1153. memcpy(buf, &mSrc[mTokenStart], len);
  1154. char c = buf[len - 1];
  1155. if ((c == 'd') || (c == 'D') || (c == 'f') || (c == 'F'))
  1156. buf[len - 1] = '\0';
  1157. else
  1158. buf[len] = '\0';
  1159. return strtod(buf, NULL);
  1160. }
  1161. void BfParser::NextToken(int endIdx)
  1162. {
  1163. mToken = BfToken_None;
  1164. if (mSyntaxToken == BfSyntaxToken_EOF)
  1165. Fail("Unexpected end of file");
  1166. mTriviaStart = mSrcIdx;
  1167. bool isLineStart = true;
  1168. bool isVerbatim = false;
  1169. int verbatimStart = -1;
  1170. while (true)
  1171. {
  1172. bool setVerbatim = false;
  1173. uint32 checkTokenHash = 0;
  1174. if ((endIdx != -1) && (mSrcIdx >= endIdx))
  1175. {
  1176. mSyntaxToken = BfSyntaxToken_HIT_END_IDX;
  1177. return;
  1178. }
  1179. mTokenStart = mSrcIdx;
  1180. mTokenEnd = mSrcIdx + 1;
  1181. char c = mSrc[mSrcIdx++];
  1182. if ((mPreprocessorIgnoreDepth > 0) && (endIdx == -1))
  1183. {
  1184. if (c == 0)
  1185. {
  1186. mSyntaxToken = BfSyntaxToken_EOF;
  1187. mSrcIdx--;
  1188. break;
  1189. }
  1190. if ((c != '#') || (!isLineStart))
  1191. {
  1192. if (c == '\n')
  1193. {
  1194. NewLine();
  1195. isLineStart = true;
  1196. continue;
  1197. }
  1198. if (IsWhitespace(c))
  1199. continue;
  1200. isLineStart = false;
  1201. continue;
  1202. }
  1203. }
  1204. switch (c)
  1205. {
  1206. case '!':
  1207. if (mSrc[mSrcIdx] == '=')
  1208. {
  1209. mToken = BfToken_CompareNotEquals;
  1210. mTokenEnd = ++mSrcIdx;
  1211. }
  1212. else
  1213. mToken = BfToken_Bang;
  1214. mSyntaxToken = BfSyntaxToken_Token;
  1215. return;
  1216. case '=':
  1217. if (mSrc[mSrcIdx] == '=')
  1218. {
  1219. mToken = BfToken_CompareEquals;
  1220. mTokenEnd = ++mSrcIdx;
  1221. }
  1222. else if (mSrc[mSrcIdx] == '>')
  1223. {
  1224. mToken = BfToken_FatArrow;
  1225. mTokenEnd = ++mSrcIdx;
  1226. }
  1227. else
  1228. mToken = BfToken_AssignEquals;
  1229. mSyntaxToken = BfSyntaxToken_Token;
  1230. return;
  1231. case '+':
  1232. if (mSrc[mSrcIdx] == '+')
  1233. {
  1234. mToken = BfToken_DblPlus;
  1235. mTokenEnd = ++mSrcIdx;
  1236. }
  1237. else if (mSrc[mSrcIdx] == '=')
  1238. {
  1239. mToken = BfToken_PlusEquals;
  1240. mTokenEnd = ++mSrcIdx;
  1241. }
  1242. else
  1243. mToken = BfToken_Plus;
  1244. mSyntaxToken = BfSyntaxToken_Token;
  1245. return;
  1246. case '^':
  1247. if (mSrc[mSrcIdx] == '=')
  1248. {
  1249. mToken = BfToken_XorEquals;
  1250. mTokenEnd = ++mSrcIdx;
  1251. }
  1252. else
  1253. mToken = BfToken_Carat;
  1254. mSyntaxToken = BfSyntaxToken_Token;
  1255. return;
  1256. case '~':
  1257. mToken = BfToken_Tilde;
  1258. mSyntaxToken = BfSyntaxToken_Token;
  1259. return;
  1260. case '%':
  1261. if (mSrc[mSrcIdx] == '=')
  1262. {
  1263. mToken = BfToken_ModulusEquals;
  1264. mTokenEnd = ++mSrcIdx;
  1265. }
  1266. else
  1267. mToken = BfToken_Modulus;
  1268. mSyntaxToken = BfSyntaxToken_Token;
  1269. return;
  1270. case '&':
  1271. if (mSrc[mSrcIdx] == '&')
  1272. {
  1273. mToken = BfToken_DblAmpersand;
  1274. mTokenEnd = ++mSrcIdx;
  1275. }
  1276. else if (mSrc[mSrcIdx] == '=')
  1277. {
  1278. mToken = BfToken_AndEquals;
  1279. mTokenEnd = ++mSrcIdx;
  1280. }
  1281. else
  1282. mToken = BfToken_Ampersand;
  1283. mSyntaxToken = BfSyntaxToken_Token;
  1284. return;
  1285. case '|':
  1286. if (mSrc[mSrcIdx] == '|')
  1287. {
  1288. mToken = BfToken_DblBar;
  1289. mTokenEnd = ++mSrcIdx;
  1290. }
  1291. else if (mSrc[mSrcIdx] == '=')
  1292. {
  1293. mToken = BfToken_OrEquals;
  1294. mTokenEnd = ++mSrcIdx;
  1295. }
  1296. else
  1297. mToken = BfToken_Bar;
  1298. mSyntaxToken = BfSyntaxToken_Token;
  1299. return;
  1300. case '*':
  1301. if (mSrc[mSrcIdx] == '=')
  1302. {
  1303. mToken = BfToken_MultiplyEquals;
  1304. mTokenEnd = ++mSrcIdx;
  1305. }
  1306. else
  1307. mToken = BfToken_Star;
  1308. mSyntaxToken = BfSyntaxToken_Token;
  1309. return;
  1310. case '?':
  1311. if (mSrc[mSrcIdx] == '?')
  1312. {
  1313. mToken = BfToken_DblQuestion;
  1314. mTokenEnd = ++mSrcIdx;
  1315. }
  1316. else if (mSrc[mSrcIdx] == '.')
  1317. {
  1318. mToken = BfToken_QuestionDot;
  1319. mTokenEnd = ++mSrcIdx;
  1320. }
  1321. else if (mSrc[mSrcIdx] == '[')
  1322. {
  1323. mToken = BfToken_QuestionLBracket;
  1324. mTokenEnd = ++mSrcIdx;
  1325. }
  1326. else
  1327. mToken = BfToken_Question;
  1328. mSyntaxToken = BfSyntaxToken_Token;
  1329. return;
  1330. case '<':
  1331. if (mSrc[mSrcIdx] == '<')
  1332. {
  1333. mTokenEnd = ++mSrcIdx;
  1334. if (mSrc[mSrcIdx] == '=')
  1335. {
  1336. mToken = BfToken_ShiftLeftEquals;
  1337. mTokenEnd = ++mSrcIdx;
  1338. }
  1339. else
  1340. mToken = BfToken_LDblChevron;
  1341. }
  1342. else if (mSrc[mSrcIdx] == '=')
  1343. {
  1344. if (mSrc[mSrcIdx + 1] == '>')
  1345. {
  1346. mToken = BfToken_Spaceship;
  1347. mSrcIdx += 2;
  1348. mTokenEnd = mSrcIdx;
  1349. }
  1350. else
  1351. {
  1352. mToken = BfToken_LessEquals;
  1353. mTokenEnd = ++mSrcIdx;
  1354. }
  1355. }
  1356. else
  1357. mToken = BfToken_LChevron;
  1358. mSyntaxToken = BfSyntaxToken_Token;
  1359. return;
  1360. case '>':
  1361. if (mSrc[mSrcIdx] == '>')
  1362. {
  1363. mTokenEnd = ++mSrcIdx;
  1364. if (mSrc[mSrcIdx] == '=')
  1365. {
  1366. mToken = BfToken_ShiftRightEquals;
  1367. mTokenEnd = ++mSrcIdx;
  1368. }
  1369. else
  1370. mToken = BfToken_RDblChevron;
  1371. }
  1372. else if (mSrc[mSrcIdx] == '=')
  1373. {
  1374. mToken = BfToken_GreaterEquals;
  1375. mTokenEnd = ++mSrcIdx;
  1376. }
  1377. else
  1378. mToken = BfToken_RChevron;
  1379. mSyntaxToken = BfSyntaxToken_Token;
  1380. return;
  1381. case '@':
  1382. setVerbatim = true;
  1383. c = mSrc[mSrcIdx];
  1384. if (c == '\"')
  1385. {
  1386. setVerbatim = true;
  1387. }
  1388. else if (((c >= 'A') && (c <= 'a')) || ((c >= 'a') && (c <= 'z')) || (c == '_') || (c == '@'))
  1389. {
  1390. setVerbatim = true;
  1391. }
  1392. else
  1393. {
  1394. mSyntaxToken = BfSyntaxToken_Identifier;
  1395. //mToken = BfToken_At;
  1396. //mSyntaxToken = BfSyntaxToken_Token;
  1397. //Fail("Keyword, identifier, or string expected after verbatim specifier: @"); // CS1646
  1398. return;
  1399. }
  1400. break;
  1401. case '"':
  1402. case '\'':
  1403. {
  1404. String lineHeader;
  1405. String strLiteral;
  1406. char startChar = c;
  1407. bool isMultiline = false;
  1408. if ((mSrc[mSrcIdx] == '"') && (mSrc[mSrcIdx + 1] == '"'))
  1409. {
  1410. isMultiline = true;
  1411. mSrcIdx += 2;
  1412. }
  1413. int contentErrorStart = -1;
  1414. int lineIdx = 0;
  1415. int lineIndentIdx = -1;
  1416. if (isMultiline)
  1417. {
  1418. int checkIdx = mSrcIdx;
  1419. int lineStartIdx = checkIdx;
  1420. while (true)
  1421. {
  1422. char c = mSrc[checkIdx++];
  1423. if ((c == '"') && (mSrc[checkIdx] == '"') && (mSrc[checkIdx + 1] == '"'))
  1424. {
  1425. lineIndentIdx = lineStartIdx;
  1426. for (int i = lineStartIdx; i < checkIdx - 1; i++)
  1427. {
  1428. char c = mSrc[i];
  1429. if ((c != '\t') && (c != ' '))
  1430. {
  1431. mPassInstance->FailAt("Multi-line string literal closing delimiter must begin on a new line", mSourceData, i, checkIdx - i + 3);
  1432. break;
  1433. }
  1434. lineHeader.Append(c);
  1435. }
  1436. break;
  1437. }
  1438. else if (c == '\n')
  1439. {
  1440. if (contentErrorStart != -1)
  1441. {
  1442. mPassInstance->FailAt("Multi-line string literal content must begin on a new line", mSourceData, contentErrorStart, checkIdx - contentErrorStart - 1);
  1443. contentErrorStart = -1;
  1444. }
  1445. lineStartIdx = checkIdx;
  1446. lineIdx++;
  1447. }
  1448. else if (c == '\0')
  1449. break; // Will throw an error in next pass
  1450. else if ((c == ' ') || (c == '\t') || (c == '\r'))
  1451. {
  1452. // Allow
  1453. }
  1454. else if (lineIdx == 0)
  1455. {
  1456. if (contentErrorStart == -1)
  1457. contentErrorStart = checkIdx - 1;
  1458. }
  1459. }
  1460. }
  1461. int lineCount = lineIdx + 1;
  1462. lineIdx = 0;
  1463. int lineStart = mSrcIdx;
  1464. while (true)
  1465. {
  1466. char c = mSrc[mSrcIdx++];
  1467. if (c == '\0')
  1468. {
  1469. // Invalid file end
  1470. mPassInstance->FailAt("String not terminated", mSourceData, mTokenStart, mSrcIdx - mTokenStart);
  1471. mSrcIdx--;
  1472. break;
  1473. }
  1474. else if (c == '\n')
  1475. {
  1476. if (isMultiline)
  1477. {
  1478. lineIdx++;
  1479. if ((lineIdx > 1) && (lineIdx < lineCount - 1))
  1480. {
  1481. strLiteral += "\n";
  1482. }
  1483. lineStart = mSrcIdx;
  1484. for (int i = 0; i < lineHeader.GetLength(); i++)
  1485. {
  1486. char wantC = lineHeader[i];
  1487. char c = mSrc[mSrcIdx];
  1488. if (c == '\r')
  1489. continue;
  1490. if (c == '\n')
  1491. break;
  1492. if (wantC == c)
  1493. {
  1494. mSrcIdx++;
  1495. }
  1496. else
  1497. {
  1498. BfError* error = NULL;
  1499. if (c == ' ')
  1500. {
  1501. error = mPassInstance->FailAt("Unexpected space in indentation of line in multi-line string literal", mSourceData, mSrcIdx, 1, BfFailFlag_ShowSpaceChars);
  1502. }
  1503. else if (c == '\t')
  1504. {
  1505. error = mPassInstance->FailAt("Unexpected tab in indentation of line in multi-line string literal", mSourceData, mSrcIdx, 1, BfFailFlag_ShowSpaceChars);
  1506. }
  1507. else
  1508. {
  1509. error = mPassInstance->FailAt("Insufficient indentation of line in multi-line string literal", mSourceData, lineStart, mSrcIdx - lineStart + 1, BfFailFlag_ShowSpaceChars);
  1510. }
  1511. if (error != NULL)
  1512. {
  1513. mPassInstance->MoreInfoAt("Change indentation of this line to match closing delimiter", mSourceData, lineIndentIdx, lineHeader.GetLength(), BfFailFlag_ShowSpaceChars);
  1514. }
  1515. break;
  1516. }
  1517. }
  1518. NewLine();
  1519. }
  1520. else
  1521. {
  1522. mSrcIdx--;
  1523. int errorIdx = mSrcIdx - 1;
  1524. while ((errorIdx > 0) && (IsWhitespace(mSrc[errorIdx])))
  1525. errorIdx--;
  1526. mPassInstance->FailAfterAt("Newline not allowed in string", mSourceData, errorIdx);
  1527. break;
  1528. }
  1529. }
  1530. else if ((c == '"') && (c == startChar))
  1531. {
  1532. if (isMultiline)
  1533. {
  1534. if ((mSrc[mSrcIdx] == '"') && (mSrc[mSrcIdx + 1] == '"')) // Triple quote
  1535. {
  1536. // Done
  1537. mSrcIdx += 2;
  1538. break;
  1539. }
  1540. strLiteral += '"';
  1541. }
  1542. else
  1543. {
  1544. if (mSrc[mSrcIdx] == '"') // Double quote
  1545. {
  1546. strLiteral += '"';
  1547. mSrcIdx++;
  1548. }
  1549. else
  1550. break;
  1551. }
  1552. }
  1553. else if ((c == '\'') && (c == startChar))
  1554. {
  1555. break;
  1556. }
  1557. else if ((c == '\\') && (!isVerbatim))
  1558. {
  1559. char c = mSrc[mSrcIdx++];
  1560. switch (c)
  1561. {
  1562. case '0':
  1563. strLiteral += '\0';
  1564. break;
  1565. case 'a':
  1566. strLiteral += '\a';
  1567. break;
  1568. case 'b':
  1569. strLiteral += '\b';
  1570. break;
  1571. case 'f':
  1572. strLiteral += '\f';
  1573. break;
  1574. case 'n':
  1575. strLiteral += '\n';
  1576. break;
  1577. case 'r':
  1578. strLiteral += '\r';
  1579. break;
  1580. case 't':
  1581. strLiteral += '\t';
  1582. break;
  1583. case 'v':
  1584. strLiteral += '\v';
  1585. break;
  1586. case '\\':
  1587. case '"':
  1588. case '\'':
  1589. strLiteral += c;
  1590. break;
  1591. case 'x':
  1592. {
  1593. int wantHexChars = 2;
  1594. int hexVal = 0;
  1595. int numHexChars = 0;
  1596. while (true)
  1597. {
  1598. char c = mSrc[mSrcIdx];
  1599. int hexChar = 0;
  1600. if ((c >= '0') && (c <= '9'))
  1601. hexChar = c - '0';
  1602. else if ((c >= 'a') && (c <= 'f'))
  1603. hexChar = c - 'a' + 0xa;
  1604. else if ((c >= 'A') && (c <= 'F'))
  1605. hexChar = c - 'A' + 0xA;
  1606. else
  1607. {
  1608. Fail("Expected two hex characters");
  1609. break;
  1610. }
  1611. mSrcIdx++;
  1612. numHexChars++;
  1613. hexVal = (hexVal * 0x10) + hexChar;
  1614. if (numHexChars == wantHexChars)
  1615. break;
  1616. }
  1617. strLiteral += (char)hexVal;
  1618. }
  1619. break;
  1620. case 'u':
  1621. {
  1622. if (mSrc[mSrcIdx] != '{')
  1623. {
  1624. Fail("Expected hexadecimal code in braces after unicode escape");
  1625. break;
  1626. }
  1627. mSrcIdx++;
  1628. int hexStart = mSrcIdx;
  1629. int hexVal = 0;
  1630. int numHexChars = 0;
  1631. while (true)
  1632. {
  1633. char c = mSrc[mSrcIdx];
  1634. int hexChar = 0;
  1635. if (c == '}')
  1636. {
  1637. if (numHexChars == 0)
  1638. Fail("Unicode escape sequence expects hex digits");
  1639. mSrcIdx++;
  1640. break;
  1641. }
  1642. if ((c >= '0') && (c <= '9'))
  1643. hexChar = c - '0';
  1644. else if ((c >= 'a') && (c <= 'f'))
  1645. hexChar = c - 'a' + 0xa;
  1646. else if ((c >= 'A') && (c <= 'F'))
  1647. hexChar = c - 'A' + 0xA;
  1648. else
  1649. {
  1650. Fail("Hex encoding error");
  1651. break;
  1652. }
  1653. mSrcIdx++;
  1654. numHexChars++;
  1655. if (numHexChars > 8)
  1656. {
  1657. Fail("Too many hex digits for an unicode scalar");
  1658. }
  1659. hexVal = (hexVal * 0x10) + hexChar;
  1660. }
  1661. char outStrUTF8[8];
  1662. int size = u8_toutf8(outStrUTF8, 8, (uint32)hexVal);
  1663. if (size == 0)
  1664. {
  1665. mPassInstance->FailAt("Invalid unicode scalar", mSourceData, hexStart, mSrcIdx - hexStart - 1);
  1666. }
  1667. strLiteral += outStrUTF8;
  1668. }
  1669. break;
  1670. default:
  1671. Fail("Unrecognized escape sequence");
  1672. strLiteral += c;
  1673. }
  1674. }
  1675. else
  1676. strLiteral += c;
  1677. }
  1678. if (isVerbatim)
  1679. {
  1680. mTokenStart--;
  1681. }
  1682. mTokenEnd = mSrcIdx;
  1683. mSyntaxToken = BfSyntaxToken_Literal;
  1684. if (startChar == '\'')
  1685. {
  1686. mLiteral.mTypeCode = BfTypeCode_Char8;
  1687. if (strLiteral.length() == 0)
  1688. {
  1689. if (mPreprocessorIgnoredSectionNode == NULL)
  1690. mPassInstance->FailAt("Empty char literal", mSourceData, mTokenStart, mSrcIdx - mTokenStart);
  1691. }
  1692. else if (strLiteral.length() > 1)
  1693. {
  1694. int utf8Len = u8_seqlen((char*)strLiteral.c_str());
  1695. if (utf8Len == (int)strLiteral.length())
  1696. {
  1697. mLiteral.mUInt64 = u8_toucs((char*)strLiteral.c_str(), (int)strLiteral.length());
  1698. }
  1699. else if (mPreprocessorIgnoredSectionNode == NULL)
  1700. {
  1701. bool isGraphemeCluster = false;
  1702. // There's no explicit unicode limit to how many diacriticals a grapheme cluster can contain,
  1703. // but we apply a limit for sanity for the purpose of this error
  1704. if (strLiteral.length() < 64)
  1705. {
  1706. int numCodePoints;
  1707. int numCombiningMarks;
  1708. UTF8Categorize(strLiteral.c_str(), (int)strLiteral.length(), numCodePoints, numCombiningMarks);
  1709. isGraphemeCluster = numCodePoints - numCombiningMarks <= 1;
  1710. }
  1711. if (isGraphemeCluster)
  1712. mPassInstance->FailAt("Grapheme clusters cannot be used as character literals", mSourceData, mTokenStart + 1, mSrcIdx - mTokenStart - 2);
  1713. else
  1714. mPassInstance->FailAt("Too many characters in character literal", mSourceData, mTokenStart + 1, mSrcIdx - mTokenStart - 2);
  1715. }
  1716. }
  1717. else
  1718. {
  1719. mLiteral.mInt64 = (uint8)strLiteral[0];
  1720. }
  1721. if (mLiteral.mInt64 >= 0x10000)
  1722. mLiteral.mTypeCode = BfTypeCode_Char32;
  1723. else if (mLiteral.mInt64 >= 0x100)
  1724. mLiteral.mTypeCode = BfTypeCode_Char16;
  1725. }
  1726. else
  1727. {
  1728. auto* strLiteralPtr = new String(std::move(strLiteral));
  1729. mParserData->mStringLiterals.push_back(strLiteralPtr);
  1730. mLiteral.mTypeCode = BfTypeCode_CharPtr;
  1731. mLiteral.mString = strLiteralPtr;
  1732. }
  1733. return;
  1734. }
  1735. break;
  1736. case '/':
  1737. if (mSrc[mSrcIdx] == '/')
  1738. {
  1739. // Comment line
  1740. while (true)
  1741. {
  1742. char c = mSrc[mSrcIdx++];
  1743. if ((c == '\n') || (c == '\0'))
  1744. {
  1745. mSrcIdx--;
  1746. break;
  1747. }
  1748. }
  1749. mTokenEnd = mSrcIdx;
  1750. if (mPreprocessorIgnoredSectionNode == NULL)
  1751. {
  1752. bool handled = false;
  1753. if (!mPendingSideNodes.IsEmpty())
  1754. {
  1755. if (auto prevComment = BfNodeDynCast<BfCommentNode>(mPendingSideNodes.back()))
  1756. {
  1757. // This is required for folding '///' style multi-line documentation into a single node
  1758. if (prevComment->GetTriviaStart() == mTriviaStart)
  1759. {
  1760. if (GetCommentKind(prevComment->mSrcStart) == GetCommentKind(mTokenStart))
  1761. {
  1762. prevComment->SetSrcEnd(mSrcIdx);
  1763. handled = true;
  1764. }
  1765. }
  1766. }
  1767. }
  1768. if (!handled)
  1769. {
  1770. auto bfCommentNode = mAlloc->Alloc<BfCommentNode>();
  1771. bfCommentNode->Init(this);
  1772. bfCommentNode->mCommentKind = GetCommentKind(mTokenStart);
  1773. mSidechannelRootNode->Add(bfCommentNode);
  1774. mPendingSideNodes.push_back(bfCommentNode);
  1775. }
  1776. }
  1777. break;
  1778. }
  1779. else if (mSrc[mSrcIdx] == '=')
  1780. {
  1781. mToken = BfToken_DivideEquals;
  1782. mTokenEnd = ++mSrcIdx;
  1783. mSyntaxToken = BfSyntaxToken_Token;
  1784. return;
  1785. }
  1786. else if (mSrc[mSrcIdx] == '*')
  1787. {
  1788. // Comment block
  1789. int nestCount = 1;
  1790. mSrcIdx++;
  1791. while (true)
  1792. {
  1793. char c = mSrc[mSrcIdx++];
  1794. if (c == '\n')
  1795. {
  1796. NewLine();
  1797. }
  1798. else if ((c == '\0') || ((c == '*') && (mSrc[mSrcIdx] == '/')))
  1799. {
  1800. // Block ends
  1801. if (c == '\0')
  1802. {
  1803. nestCount = 0;
  1804. mSrcIdx--;
  1805. }
  1806. else
  1807. {
  1808. c = 0;
  1809. nestCount--;
  1810. mSrcIdx++;
  1811. }
  1812. if (nestCount == 0)
  1813. {
  1814. mTokenEnd = mSrcIdx;
  1815. if (mPreprocessorIgnoredSectionNode == NULL)
  1816. {
  1817. bool handled = false;
  1818. if (!mPendingSideNodes.IsEmpty())
  1819. {
  1820. if (auto prevComment = BfNodeDynCast<BfCommentNode>(mPendingSideNodes.back()))
  1821. {
  1822. // This is required for folding documentation into a single node
  1823. if (prevComment->GetTriviaStart() == mTriviaStart)
  1824. {
  1825. if (GetCommentKind(prevComment->mSrcStart) == GetCommentKind(mTokenStart))
  1826. {
  1827. prevComment->SetSrcEnd(mSrcIdx);
  1828. handled = true;
  1829. }
  1830. }
  1831. }
  1832. }
  1833. if (!handled)
  1834. {
  1835. auto bfCommentNode = mAlloc->Alloc<BfCommentNode>();
  1836. bfCommentNode->Init(this);
  1837. bfCommentNode->mCommentKind = GetCommentKind(mTokenStart);
  1838. mSidechannelRootNode->Add(bfCommentNode);
  1839. mPendingSideNodes.push_back(bfCommentNode);
  1840. }
  1841. }
  1842. break;
  1843. }
  1844. }
  1845. else if ((!mCompatMode) && ((c == '/') && (mSrc[mSrcIdx] == '*') && (mSrc[mSrcIdx - 2] != '/')))
  1846. {
  1847. nestCount++;
  1848. mSrcIdx++;
  1849. }
  1850. }
  1851. }
  1852. else
  1853. {
  1854. mToken = BfToken_ForwardSlash;
  1855. mSyntaxToken = BfSyntaxToken_Token;
  1856. return;
  1857. }
  1858. break;
  1859. case '#':
  1860. HandlePreprocessor();
  1861. if (mSyntaxToken == BfSyntaxToken_EOF)
  1862. return;
  1863. break;
  1864. case '.':
  1865. if (mSrc[mSrcIdx] == '.')
  1866. {
  1867. if (mSrc[mSrcIdx + 1] == '.')
  1868. {
  1869. mSrcIdx += 2;
  1870. mTokenEnd = mSrcIdx;
  1871. mToken = BfToken_DotDotDot;
  1872. mSyntaxToken = BfSyntaxToken_Token;
  1873. }
  1874. else
  1875. {
  1876. mSrcIdx++;
  1877. mTokenEnd = mSrcIdx;
  1878. mToken = BfToken_DotDot;
  1879. mSyntaxToken = BfSyntaxToken_Token;
  1880. }
  1881. }
  1882. else
  1883. {
  1884. mToken = BfToken_Dot;
  1885. mSyntaxToken = BfSyntaxToken_Token;
  1886. }
  1887. return;
  1888. case ',':
  1889. mToken = BfToken_Comma;
  1890. mSyntaxToken = BfSyntaxToken_Token;
  1891. return;
  1892. case ';':
  1893. if (mInAsmBlock)
  1894. {
  1895. mToken = BfToken_AsmNewline;
  1896. mSyntaxToken = BfSyntaxToken_Token;
  1897. }
  1898. else
  1899. {
  1900. mToken = BfToken_Semicolon;
  1901. mSyntaxToken = BfSyntaxToken_Token;
  1902. }
  1903. return;
  1904. case ':':
  1905. {
  1906. if ((mCompatMode) && (mSrc[mSrcIdx] == ':'))
  1907. {
  1908. mSrcIdx++;
  1909. mTokenEnd = mSrcIdx;
  1910. mToken = BfToken_Dot;
  1911. mSyntaxToken = BfSyntaxToken_Token;
  1912. }
  1913. else
  1914. {
  1915. mToken = BfToken_Colon;
  1916. mSyntaxToken = BfSyntaxToken_Token;
  1917. }
  1918. }
  1919. return;
  1920. case '(':
  1921. mToken = BfToken_LParen;
  1922. mSyntaxToken = BfSyntaxToken_Token;
  1923. return;
  1924. case ')':
  1925. mToken = BfToken_RParen;
  1926. mSyntaxToken = BfSyntaxToken_Token;
  1927. return;
  1928. case '{':
  1929. mToken = BfToken_LBrace;
  1930. mSyntaxToken = BfSyntaxToken_Token;
  1931. return;
  1932. case '}':
  1933. mToken = BfToken_RBrace;
  1934. mSyntaxToken = BfSyntaxToken_Token;
  1935. return;
  1936. case '[':
  1937. mToken = BfToken_LBracket;
  1938. mSyntaxToken = BfSyntaxToken_Token;
  1939. return;
  1940. case ']':
  1941. mToken = BfToken_RBracket;
  1942. mSyntaxToken = BfSyntaxToken_Token;
  1943. return;
  1944. case '\n':
  1945. NewLine();
  1946. if (!mInAsmBlock)
  1947. continue;
  1948. mToken = BfToken_AsmNewline;
  1949. mSyntaxToken = BfSyntaxToken_Token;
  1950. return;
  1951. case ' ':
  1952. case '\t':
  1953. case '\v':
  1954. case '\f':
  1955. case '\r':
  1956. continue; // Whitespace
  1957. case '\0':
  1958. mSrcIdx--; // Stay on EOF marker
  1959. mSyntaxToken = BfSyntaxToken_EOF;
  1960. return;
  1961. default:
  1962. if (((c >= '0') && (c <= '9')) || (c == '-'))
  1963. {
  1964. bool prevIsDot = (mSrcIdx > 1) && (mSrc[mSrcIdx - 2] == '.');
  1965. if (c == '-')
  1966. {
  1967. // Not a number!
  1968. if (mSrc[mSrcIdx] == '-')
  1969. {
  1970. mToken = BfToken_DblMinus;
  1971. mSrcIdx++;
  1972. }
  1973. else if (mSrc[mSrcIdx] == '=')
  1974. {
  1975. mToken = BfToken_MinusEquals;
  1976. mSrcIdx++;
  1977. }
  1978. else if ((mCompatMode) && (mSrc[mSrcIdx] == '>'))
  1979. {
  1980. mToken = BfToken_Dot;
  1981. mSrcIdx++;
  1982. }
  1983. else
  1984. mToken = BfToken_Minus;
  1985. mSyntaxToken = BfSyntaxToken_Token;
  1986. mTokenEnd = mSrcIdx;
  1987. return;
  1988. }
  1989. bool wasNeg = false;
  1990. bool hadOverflow = false;
  1991. int64 val = 0;
  1992. int numberBase = 10;
  1993. int expVal = 0;
  1994. int expSign = 0;
  1995. bool hasExp = false;
  1996. bool hadSeps = false;
  1997. bool hadLeadingHexSep = false;
  1998. int hexDigits = 0;
  1999. if (c == '-')
  2000. {
  2001. wasNeg = true; //TODO: This never actually gets set any more (eaten as BfToken_Minus above). Move checks that use this to later in pipeline, then remove this
  2002. c = mSrc[mSrcIdx++];
  2003. }
  2004. val = c - '0';
  2005. if (c == '0')
  2006. {
  2007. switch (mSrc[mSrcIdx])
  2008. {
  2009. case 'b':
  2010. case 'B':
  2011. numberBase = 2;
  2012. mSrcIdx++;
  2013. break;
  2014. case 'o':
  2015. case 'O':
  2016. numberBase = 8;
  2017. mSrcIdx++;
  2018. break;
  2019. case 'x':
  2020. case 'X':
  2021. numberBase = 16;
  2022. mSrcIdx++;
  2023. break;
  2024. }
  2025. }
  2026. while (true)
  2027. {
  2028. char c = mSrc[mSrcIdx++];
  2029. if (c == '\'')
  2030. {
  2031. hadSeps = true;
  2032. if ((numberBase == 0x10) && (hexDigits == 0))
  2033. hadLeadingHexSep = true;
  2034. continue;
  2035. }
  2036. if ((numberBase == 10) && ((c == 'e') || (c == 'E')))
  2037. {
  2038. // Specifying exponent
  2039. while (true)
  2040. {
  2041. c = mSrc[mSrcIdx++];
  2042. if (c == '+')
  2043. {
  2044. if (expSign != 0)
  2045. TokenFail("Format error");
  2046. expSign = 1;
  2047. }
  2048. else if (c == '-')
  2049. {
  2050. if (expSign != 0)
  2051. TokenFail("Format error");
  2052. expSign = -1;
  2053. }
  2054. else if ((c >= '0') && (c <= '9'))
  2055. {
  2056. hasExp = true;
  2057. expVal *= 10;
  2058. expVal += c - '0';
  2059. }
  2060. else
  2061. {
  2062. if (expSign == -1)
  2063. expVal = -expVal;
  2064. mSrcIdx--;
  2065. break;
  2066. }
  2067. }
  2068. if (!hasExp)
  2069. {
  2070. TokenFail("Expected an exponent");
  2071. }
  2072. }
  2073. // The 'prevIsDot' helps tuple lookups like "tuple.0.0", interpreting those as two integers rather than a float
  2074. if (((c == '.') && (!prevIsDot)) || (hasExp))
  2075. {
  2076. // Switch to floating point mode
  2077. //double dVal = val;
  2078. //double dValScale = 0.1;
  2079. //if (hasExp)
  2080. //dVal *= pow(10, expVal);
  2081. while (true)
  2082. {
  2083. char c = mSrc[mSrcIdx++];
  2084. if (IsWhitespaceOrPunctuation(c))
  2085. {
  2086. mTokenEnd = mSrcIdx - 1;
  2087. mSrcIdx--;
  2088. mLiteral.mTypeCode = BfTypeCode_Double;
  2089. mLiteral.mDouble = ParseLiteralDouble();//dVal;
  2090. mSyntaxToken = BfSyntaxToken_Literal;
  2091. return;
  2092. }
  2093. if ((c == 'e') || (c == 'E'))
  2094. {
  2095. // Specifying exponent
  2096. if (hasExp)
  2097. TokenFail("Format error");
  2098. while (true)
  2099. {
  2100. c = mSrc[mSrcIdx++];
  2101. if (c == '+')
  2102. {
  2103. if (expSign != 0)
  2104. TokenFail("Format error");
  2105. expSign = 1;
  2106. }
  2107. else if (c == '-')
  2108. {
  2109. if (expSign != 0)
  2110. TokenFail("Format error");
  2111. expSign = -1;
  2112. }
  2113. else if ((c >= '0') && (c <= '9'))
  2114. {
  2115. hasExp = true;
  2116. expVal *= 10;
  2117. expVal += c - '0';
  2118. }
  2119. else
  2120. {
  2121. if (expSign == -1)
  2122. expVal = -expVal;
  2123. mSrcIdx--;
  2124. //dVal *= pow(10, expVal);
  2125. break;
  2126. }
  2127. }
  2128. if (!hasExp)
  2129. {
  2130. TokenFail("Expected an exponent");
  2131. }
  2132. continue;
  2133. }
  2134. if ((c == 'f') || (c == 'F'))
  2135. {
  2136. mTokenEnd = mSrcIdx;
  2137. mLiteral.mTypeCode = BfTypeCode_Single;
  2138. mLiteral.mSingle = (float)ParseLiteralDouble();//(float)dVal;
  2139. mSyntaxToken = BfSyntaxToken_Literal;
  2140. return;
  2141. }
  2142. else if ((c == 'd') || (c == 'D'))
  2143. {
  2144. mTokenEnd = mSrcIdx;
  2145. mLiteral.mTypeCode = BfTypeCode_Double;
  2146. mLiteral.mDouble = ParseLiteralDouble();//(double)dVal;
  2147. mSyntaxToken = BfSyntaxToken_Literal;
  2148. return;
  2149. }
  2150. else if ((c >= '0') && (c <= '9'))
  2151. {
  2152. //dVal += (c - '0') * dValScale;
  2153. //dValScale *= 0.1;
  2154. }
  2155. else if ((((c >= 'A') && (c <= 'Z')) || ((c >= 'a') && (c <= 'z'))) &&
  2156. (mSrc[mSrcIdx - 2] == '.'))
  2157. {
  2158. // This is actually a integer followed by an Int32 call (like 123.ToString)
  2159. mSrcIdx -= 2;
  2160. mTokenEnd = mSrcIdx;
  2161. mLiteral.mInt64 = val;
  2162. mLiteral.mTypeCode = BfTypeCode_IntUnknown;
  2163. mSyntaxToken = BfSyntaxToken_Literal;
  2164. return;
  2165. }
  2166. else
  2167. {
  2168. mSrcIdx--;
  2169. mTokenEnd = mSrcIdx;
  2170. mLiteral.mTypeCode = BfTypeCode_Double;
  2171. mLiteral.mDouble = ParseLiteralDouble();//(double)dVal;
  2172. mSyntaxToken = BfSyntaxToken_Literal;
  2173. TokenFail("Unexpected character while parsing number", 0);
  2174. return;
  2175. }
  2176. }
  2177. return;
  2178. }
  2179. if (IsWhitespaceOrPunctuation(c))
  2180. {
  2181. mTokenEnd = mSrcIdx - 1;
  2182. mSrcIdx--;
  2183. if (wasNeg)
  2184. val = -val;
  2185. if ((numberBase == 0x10) &&
  2186. ((hexDigits == 16) || ((hadSeps) && (hexDigits > 8)) || ((hadLeadingHexSep) && (hexDigits == 8))))
  2187. {
  2188. if (hexDigits > 16)
  2189. mPassInstance->FailAt("Too many hex digits for int64", mSourceData, mTokenStart, mSrcIdx - mTokenStart);
  2190. mLiteral.mInt64 = val;
  2191. if ((val < 0) && (!wasNeg))
  2192. mLiteral.mTypeCode = BfTypeCode_UInt64;
  2193. else
  2194. mLiteral.mTypeCode = BfTypeCode_Int64;
  2195. }
  2196. else
  2197. {
  2198. mLiteral.mInt64 = val;
  2199. mLiteral.mTypeCode = BfTypeCode_IntUnknown;
  2200. if ((hadOverflow) || (val < -0x80000000LL) || (val > 0xFFFFFFFFLL))
  2201. mPassInstance->FailAt("Value doesn't fit into int32", mSourceData, mTokenStart, mSrcIdx - mTokenStart);
  2202. else
  2203. {
  2204. if ((numberBase == 0x10) && (hexDigits == 7))
  2205. mLiteral.mWarnType = BfWarning_BF4201_Only7Hex;
  2206. //mPassInstance->WarnAt(0, "Only 7 hex digits specified. Add a leading zero to clarify intention.", this, mTokenStart, mSrcIdx - mTokenStart);
  2207. if ((numberBase == 0x10) && (hexDigits > 8))
  2208. mLiteral.mWarnType = BfWarning_BF4202_TooManyHexForInt;
  2209. //mPassInstance->FailAt("Too many hex digits for an int, but too few for a long. Use 'L' suffix if a long was intended.", this, mTokenStart, mSrcIdx - mTokenStart);
  2210. /*if (val > 0x7FFFFFFF)
  2211. mLiteral.mTypeCode = BfTypeCode_UIntUnknown;*/
  2212. }
  2213. }
  2214. mSyntaxToken = BfSyntaxToken_Literal;
  2215. return;
  2216. }
  2217. int64 prevVal = val;
  2218. if ((c >= '0') && (c <= '9') && (c < '0' + numberBase))
  2219. {
  2220. if (numberBase == 0x10)
  2221. hexDigits++;
  2222. val *= numberBase;
  2223. val += c - '0';
  2224. }
  2225. else if ((numberBase == 0x10) && (c >= 'A') && (c <= 'F'))
  2226. {
  2227. hexDigits++;
  2228. val *= numberBase;
  2229. val += c - 'A' + 0xA;
  2230. }
  2231. else if ((numberBase == 0x10) && (c >= 'a') && (c <= 'f'))
  2232. {
  2233. hexDigits++;
  2234. val *= numberBase;
  2235. val += c - 'a' + 0xa;
  2236. }
  2237. else if ((c == 'u') || (c == 'U'))
  2238. {
  2239. if (wasNeg)
  2240. val = -val;
  2241. if ((mSrc[mSrcIdx] == 'l') || (mSrc[mSrcIdx] == 'L'))
  2242. {
  2243. if (mSrc[mSrcIdx] == 'l')
  2244. TokenFail("Uppercase 'L' required for int64");
  2245. mSrcIdx++;
  2246. mTokenEnd = mSrcIdx;
  2247. mLiteral.mTypeCode = BfTypeCode_UInt64;
  2248. mLiteral.mUInt64 = (uint64)val;
  2249. if (hexDigits > 16)
  2250. mPassInstance->FailAt("Too many hex digits for int64", mSourceData, mTokenStart, mSrcIdx - mTokenStart);
  2251. else if ((hadOverflow) || (wasNeg))
  2252. mPassInstance->FailAt("Value doesn't fit into uint64", mSourceData, mTokenStart, mSrcIdx - mTokenStart);
  2253. mSyntaxToken = BfSyntaxToken_Literal;
  2254. return;
  2255. }
  2256. mTokenEnd = mSrcIdx;
  2257. mLiteral.mTypeCode = BfTypeCode_UIntPtr;
  2258. mLiteral.mUInt32 = (uint32)val;
  2259. if ((hadOverflow) || (wasNeg) || ((uint64)val != (uint64)mLiteral.mUInt32))
  2260. mPassInstance->FailAt("Value doesn't fit into uint32", mSourceData, mTokenStart, mSrcIdx - mTokenStart);
  2261. mSyntaxToken = BfSyntaxToken_Literal;
  2262. return;
  2263. }
  2264. else if ((c == 'l') || (c == 'L'))
  2265. {
  2266. if (c == 'l')
  2267. TokenFail("Uppercase 'L' required for int64");
  2268. if (wasNeg)
  2269. val = -val;
  2270. if ((mSrc[mSrcIdx] == 'u') || (mSrc[mSrcIdx] == 'U'))
  2271. {
  2272. mSrcIdx++;
  2273. mTokenEnd = mSrcIdx;
  2274. mLiteral.mTypeCode = BfTypeCode_UInt64;
  2275. mLiteral.mUInt64 = (uint64)val;
  2276. if (hexDigits > 16)
  2277. mPassInstance->FailAt("Too many hex digits for int64", mSourceData, mTokenStart, mSrcIdx - mTokenStart);
  2278. else if ((hadOverflow) || (wasNeg))
  2279. mPassInstance->FailAt("Value doesn't fit into uint64", mSourceData, mTokenStart, mSrcIdx - mTokenStart);
  2280. mSyntaxToken = BfSyntaxToken_Literal;
  2281. return;
  2282. }
  2283. mTokenEnd = mSrcIdx;
  2284. mLiteral.mTypeCode = BfTypeCode_Int64;
  2285. mLiteral.mInt64 = (int64)val;
  2286. bool signMatched = true;
  2287. if (val != 0)
  2288. signMatched = (val < 0) == wasNeg;
  2289. if (hexDigits > 16)
  2290. mPassInstance->FailAt("Too many hex digits for int64", mSourceData, mTokenStart, mSrcIdx - mTokenStart);
  2291. else if ((hadOverflow) || (!signMatched))
  2292. mPassInstance->FailAt("Value doesn't fit into int64", mSourceData, mTokenStart, mSrcIdx - mTokenStart);
  2293. mSyntaxToken = BfSyntaxToken_Literal;
  2294. return;
  2295. }
  2296. else if ((c == 'f') || (c == 'F'))
  2297. {
  2298. mTokenEnd = mSrcIdx;
  2299. mLiteral.mTypeCode = BfTypeCode_Single;
  2300. mLiteral.mSingle = (float)ParseLiteralDouble();//(float)val;
  2301. mSyntaxToken = BfSyntaxToken_Literal;
  2302. return;
  2303. }
  2304. else if ((c == 'd') || (c == 'D'))
  2305. {
  2306. mTokenEnd = mSrcIdx;
  2307. mLiteral.mTypeCode = BfTypeCode_Double;
  2308. mLiteral.mDouble = ParseLiteralDouble();//(double)val;
  2309. mSyntaxToken = BfSyntaxToken_Literal;
  2310. return;
  2311. }
  2312. else
  2313. {
  2314. mTokenEnd = mSrcIdx - 1;
  2315. mSrcIdx--;
  2316. if (wasNeg)
  2317. val = -val;
  2318. mLiteral.mInt64 = val;
  2319. mLiteral.mTypeCode = BfTypeCode_IntUnknown;
  2320. mSyntaxToken = BfSyntaxToken_Literal;
  2321. TokenFail("Unexpected character while parsing number", 0);
  2322. return;
  2323. }
  2324. //if ((val < 0) && (val != -0x8000000000000000))
  2325. if ((uint64)prevVal > (uint64)val)
  2326. hadOverflow = true;
  2327. }
  2328. }
  2329. else
  2330. {
  2331. if ((mCompatMode) && (c == '\\'))
  2332. {
  2333. int checkIdx = mSrcIdx;
  2334. bool isAtLineEnd = true;
  2335. while (true)
  2336. {
  2337. char checkC = mSrc[checkIdx];
  2338. if ((checkC == '\r') || (checkC == '\n'))
  2339. break;
  2340. if ((checkC != ' ') && (checkC != '\t'))
  2341. {
  2342. isAtLineEnd = false;
  2343. break;
  2344. }
  2345. checkIdx++;
  2346. }
  2347. if (isAtLineEnd)
  2348. continue;
  2349. }
  2350. if (!isVerbatim)
  2351. {
  2352. switch (GetTokenHash())
  2353. {
  2354. case TOKEN_HASH('t', 'r', 'u', 'e'):
  2355. if (SrcPtrHasToken("true"))
  2356. {
  2357. mLiteral.mTypeCode = BfTypeCode_Boolean;
  2358. mLiteral.mInt64 = 1;
  2359. mSyntaxToken = BfSyntaxToken_Literal;
  2360. return;
  2361. }
  2362. break;
  2363. case TOKEN_HASH('f', 'a', 'l', 's'):
  2364. if (SrcPtrHasToken("false"))
  2365. {
  2366. mLiteral.mTypeCode = BfTypeCode_Boolean;
  2367. mLiteral.mInt64 = 0;
  2368. mSyntaxToken = BfSyntaxToken_Literal;
  2369. return;
  2370. }
  2371. break;
  2372. case TOKEN_HASH('a', 'b', 's', 't'):
  2373. if ((!mCompatMode) && (SrcPtrHasToken("abstract")))
  2374. mToken = BfToken_Abstract;
  2375. break;
  2376. case TOKEN_HASH('a', 'l', 'i', 'g'):
  2377. if (SrcPtrHasToken("alignof"))
  2378. mToken = BfToken_AlignOf;
  2379. break;
  2380. case TOKEN_HASH('a', 'p', 'p', 'e'):
  2381. if ((!mCompatMode) && (SrcPtrHasToken("append")))
  2382. mToken = BfToken_Append;
  2383. break;
  2384. case TOKEN_HASH('a', 's', 0, 0):
  2385. if ((!mCompatMode) && (SrcPtrHasToken("as")))
  2386. mToken = BfToken_As;
  2387. break;
  2388. case TOKEN_HASH('a', 's', 'm', 0):
  2389. if (SrcPtrHasToken("asm"))
  2390. mToken = BfToken_Asm;
  2391. break;
  2392. case TOKEN_HASH('b', 'a', 's', 'e'):
  2393. if (SrcPtrHasToken("base"))
  2394. mToken = BfToken_Base;
  2395. break;
  2396. case TOKEN_HASH('b', 'o', 'x', 0):
  2397. if ((!mCompatMode) && (SrcPtrHasToken("box")))
  2398. mToken = BfToken_Box;
  2399. break;
  2400. case TOKEN_HASH('b', 'r', 'e', 'a'):
  2401. if (SrcPtrHasToken("break"))
  2402. mToken = BfToken_Break;
  2403. break;
  2404. case TOKEN_HASH('c', 'a', 's', 'e'):
  2405. if (SrcPtrHasToken("case"))
  2406. mToken = BfToken_Case;
  2407. break;
  2408. case TOKEN_HASH('c', 'a', 't', 'c'):
  2409. if (SrcPtrHasToken("catch"))
  2410. mToken = BfToken_Catch;
  2411. break;
  2412. case TOKEN_HASH('c', 'h', 'e', 'c'):
  2413. if ((!mCompatMode) && (SrcPtrHasToken("checked")))
  2414. mToken = BfToken_Checked;
  2415. break;
  2416. case TOKEN_HASH('c', 'l', 'a', 's'):
  2417. if (SrcPtrHasToken("class"))
  2418. mToken = BfToken_Class;
  2419. break;
  2420. case TOKEN_HASH('c', 'o', 'n', 'c'):
  2421. if ((!mCompatMode) && (SrcPtrHasToken("concrete")))
  2422. mToken = BfToken_Concrete;
  2423. break;
  2424. case TOKEN_HASH('c', 'o', 'n', 's'):
  2425. if (SrcPtrHasToken("const"))
  2426. mToken = BfToken_Const;
  2427. break;
  2428. case TOKEN_HASH('c', 'o', 'n', 't'):
  2429. if (SrcPtrHasToken("continue"))
  2430. mToken = BfToken_Continue;
  2431. break;
  2432. case TOKEN_HASH('d', 'e', 'c', 'l'):
  2433. if (SrcPtrHasToken("decltype"))
  2434. mToken = BfToken_Decltype;
  2435. break;
  2436. case TOKEN_HASH('d', 'e', 'f', 'a'):
  2437. if (SrcPtrHasToken("default"))
  2438. mToken = BfToken_Default;
  2439. break;
  2440. case TOKEN_HASH('d', 'e', 'f', 'e'):
  2441. if ((!mCompatMode) && (SrcPtrHasToken("defer")))
  2442. mToken = BfToken_Defer;
  2443. break;
  2444. case TOKEN_HASH('d', 'e', 'l', 'e'):
  2445. if ((!mCompatMode) && (SrcPtrHasToken("delegate")))
  2446. mToken = BfToken_Delegate;
  2447. else if (SrcPtrHasToken("delete"))
  2448. mToken = BfToken_Delete;
  2449. break;
  2450. case TOKEN_HASH('d', 'o', 0, 0):
  2451. if (SrcPtrHasToken("do"))
  2452. mToken = BfToken_Do;
  2453. break;
  2454. break;
  2455. case TOKEN_HASH('e', 'l', 's', 'e'):
  2456. if (SrcPtrHasToken("else"))
  2457. mToken = BfToken_Else;
  2458. break;
  2459. case TOKEN_HASH('e', 'n', 'u', 'm'):
  2460. if (SrcPtrHasToken("enum"))
  2461. mToken = BfToken_Enum;
  2462. break;
  2463. case TOKEN_HASH('e', 'x', 'p', 'l'):
  2464. if ((!mCompatMode) && (SrcPtrHasToken("explicit")))
  2465. mToken = BfToken_Explicit;
  2466. break;
  2467. case TOKEN_HASH('e', 'x', 't', 'e'):
  2468. if (SrcPtrHasToken("extern"))
  2469. mToken = BfToken_Extern;
  2470. else if ((!mCompatMode) && (SrcPtrHasToken("extension")))
  2471. mToken = BfToken_Extension;
  2472. break;
  2473. case TOKEN_HASH('f', 'a', 'l', 'l'):
  2474. if ((!mCompatMode) && (SrcPtrHasToken("fallthrough")))
  2475. mToken = BfToken_Fallthrough;
  2476. break;
  2477. case TOKEN_HASH('f', 'i', 'n', 'a'):
  2478. if (SrcPtrHasToken("finally"))
  2479. mToken = BfToken_Finally;
  2480. break;
  2481. case TOKEN_HASH('f', 'i', 'x', 'e'):
  2482. if (SrcPtrHasToken("fixed"))
  2483. mToken = BfToken_Fixed;
  2484. break;
  2485. case TOKEN_HASH('f', 'o', 'r', 0):
  2486. if (SrcPtrHasToken("for"))
  2487. mToken = BfToken_For;
  2488. break;
  2489. case TOKEN_HASH('f', 'o', 'r', 'e'):
  2490. if ((!mCompatMode) && (SrcPtrHasToken("foreach")))
  2491. {
  2492. mToken = BfToken_For;
  2493. mPassInstance->WarnAt(0, "'foreach' should be renamed to 'for'", mSourceData, mTokenStart, mSrcIdx - mTokenStart);
  2494. }
  2495. break;
  2496. case TOKEN_HASH('f', 'u', 'n', 'c'):
  2497. if ((!mCompatMode) && (SrcPtrHasToken("function")))
  2498. mToken = BfToken_Function;
  2499. break;
  2500. case TOKEN_HASH('g', 'o', 't', 'o'):
  2501. if (SrcPtrHasToken("goto"))
  2502. mToken = BfToken_Goto;
  2503. break;
  2504. case TOKEN_HASH('i', 'f', 0, 0):
  2505. if (SrcPtrHasToken("if"))
  2506. mToken = BfToken_If;
  2507. break;
  2508. case TOKEN_HASH('i', 'm', 'p', 'l'):
  2509. if ((!mCompatMode) && (SrcPtrHasToken("implicit")))
  2510. mToken = BfToken_Implicit;
  2511. break;
  2512. case TOKEN_HASH('i', 'n', 0, 0):
  2513. if ((!mCompatMode) && (SrcPtrHasToken("in")))
  2514. mToken = BfToken_In;
  2515. break;
  2516. case TOKEN_HASH('i', 'n', 'l', 'i'):
  2517. if ((!mCompatMode) && (SrcPtrHasToken("inline")))
  2518. mToken = BfToken_Inline;
  2519. break;
  2520. case TOKEN_HASH('i', 'n', 't', 'e'):
  2521. if ((!mCompatMode) && (SrcPtrHasToken("interface")))
  2522. mToken = BfToken_Interface;
  2523. else if ((!mCompatMode) && (SrcPtrHasToken("internal")))
  2524. mToken = BfToken_Internal;
  2525. break;
  2526. case TOKEN_HASH('i', 's', 0, 0):
  2527. if ((!mCompatMode) && (SrcPtrHasToken("is")))
  2528. mToken = BfToken_Is;
  2529. break;
  2530. case TOKEN_HASH('l', 'e', 't', 0):
  2531. if ((!mCompatMode) && (SrcPtrHasToken("let")))
  2532. mToken = BfToken_Let;
  2533. break;
  2534. case TOKEN_HASH('m', 'i', 'x', 'i'):
  2535. if ((!mCompatMode) && (SrcPtrHasToken("mixin")))
  2536. mToken = BfToken_Mixin;
  2537. break;
  2538. case TOKEN_HASH('m', 'u', 't', 0):
  2539. if ((!mCompatMode) && (SrcPtrHasToken("mut")))
  2540. mToken = BfToken_Mut;
  2541. break;
  2542. case TOKEN_HASH('n', 'a', 'm', 'e'):
  2543. if (SrcPtrHasToken("namespace"))
  2544. mToken = BfToken_Namespace;
  2545. break;
  2546. case TOKEN_HASH('n', 'e', 'w', 0):
  2547. if (SrcPtrHasToken("new"))
  2548. mToken = BfToken_New;
  2549. break;
  2550. case TOKEN_HASH('n', 'u', 'l', 'l'):
  2551. if (SrcPtrHasToken("null"))
  2552. mToken = BfToken_Null;
  2553. break;
  2554. case TOKEN_HASH('o', 'p', 'e', 'r'):
  2555. if (SrcPtrHasToken("operator"))
  2556. mToken = BfToken_Operator;
  2557. break;
  2558. case TOKEN_HASH('o', 'u', 't', 0):
  2559. if ((!mCompatMode) && (SrcPtrHasToken("out")))
  2560. mToken = BfToken_Out;
  2561. break;
  2562. case TOKEN_HASH('o', 'v', 'e', 'r'):
  2563. if (SrcPtrHasToken("override"))
  2564. mToken = BfToken_Override;
  2565. break;
  2566. case TOKEN_HASH('p', 'a', 'r', 'a'):
  2567. if ((!mCompatMode) && (SrcPtrHasToken("params")))
  2568. mToken = BfToken_Params;
  2569. break;
  2570. case TOKEN_HASH('p', 'r', 'i', 'v'):
  2571. if (SrcPtrHasToken("private"))
  2572. mToken = BfToken_Private;
  2573. break;
  2574. case TOKEN_HASH('p', 'r', 'o', 't'):
  2575. if (SrcPtrHasToken("protected"))
  2576. mToken = BfToken_Protected;
  2577. break;
  2578. case TOKEN_HASH('p', 'u', 'b', 'l'):
  2579. if (SrcPtrHasToken("public"))
  2580. mToken = BfToken_Public;
  2581. break;
  2582. case TOKEN_HASH('r', 'e', 'a', 'd'):
  2583. if ((!mCompatMode) && (SrcPtrHasToken("readonly")))
  2584. mToken = BfToken_ReadOnly;
  2585. break;
  2586. case TOKEN_HASH('r', 'e', 'f', 0):
  2587. if ((!mCompatMode) && (SrcPtrHasToken("ref")))
  2588. mToken = BfToken_Ref;
  2589. break;
  2590. case TOKEN_HASH('r', 'e', 'p', 'e'):
  2591. if ((!mCompatMode) && (SrcPtrHasToken("repeat")))
  2592. mToken = BfToken_Repeat;
  2593. break;
  2594. case TOKEN_HASH('r', 'e', 't', 't'):
  2595. if ((!mCompatMode) && (SrcPtrHasToken("rettype")))
  2596. mToken = BfToken_RetType;
  2597. break;
  2598. case TOKEN_HASH('r', 'e', 't', 'u'):
  2599. if (SrcPtrHasToken("return"))
  2600. mToken = BfToken_Return;
  2601. break;
  2602. case TOKEN_HASH('s', 'c', 'o', 'p'):
  2603. if ((!mCompatMode) && (SrcPtrHasToken("scope")))
  2604. mToken = BfToken_Scope;
  2605. break;
  2606. case TOKEN_HASH('s', 'e', 'a', 'l'):
  2607. if ((!mCompatMode) && (SrcPtrHasToken("sealed")))
  2608. mToken = BfToken_Sealed;
  2609. break;
  2610. case TOKEN_HASH('s', 'i', 'z', 'e'):
  2611. if (SrcPtrHasToken("sizeof"))
  2612. mToken = BfToken_SizeOf;
  2613. break;
  2614. case TOKEN_HASH('s', 't', 'a', 'c'):
  2615. if ((!mCompatMode) && (SrcPtrHasToken("stack")))
  2616. mToken = BfToken_Stack;
  2617. break;
  2618. case TOKEN_HASH('s', 't', 'a', 't'):
  2619. if (SrcPtrHasToken("static"))
  2620. mToken = BfToken_Static;
  2621. break;
  2622. case TOKEN_HASH('s', 't', 'r', 'i'):
  2623. if (SrcPtrHasToken("strideof"))
  2624. mToken = BfToken_StrideOf;
  2625. break;
  2626. case TOKEN_HASH('s', 't', 'r', 'u'):
  2627. if (SrcPtrHasToken("struct"))
  2628. mToken = BfToken_Struct;
  2629. break;
  2630. case TOKEN_HASH('s', 'w', 'i', 't'):
  2631. if (SrcPtrHasToken("switch"))
  2632. mToken = BfToken_Switch;
  2633. break;
  2634. case TOKEN_HASH('t', 'h', 'i', 's'):
  2635. if (SrcPtrHasToken("this"))
  2636. mToken = BfToken_This;
  2637. break;
  2638. case TOKEN_HASH('t', 'h', 'r', 'o'):
  2639. if (SrcPtrHasToken("throw"))
  2640. mToken = BfToken_Throw;
  2641. break;
  2642. case TOKEN_HASH('t', 'r', 'y', 0):
  2643. if (SrcPtrHasToken("try"))
  2644. mToken = BfToken_Try;
  2645. break;
  2646. case TOKEN_HASH('t', 'y', 'p', 'e'):
  2647. if (SrcPtrHasToken("typeof"))
  2648. mToken = BfToken_TypeOf;
  2649. else if (SrcPtrHasToken("typealias"))
  2650. mToken = BfToken_TypeAlias;
  2651. break;
  2652. case TOKEN_HASH('u', 'n', 'c', 'h'):
  2653. if (SrcPtrHasToken("unchecked"))
  2654. mToken = BfToken_Unchecked;
  2655. break;
  2656. case TOKEN_HASH('u', 'n', 's', 'i'):
  2657. if (mCompatMode)
  2658. {
  2659. if (SrcPtrHasToken("unsigned"))
  2660. mToken = BfToken_Unsigned;
  2661. }
  2662. break;
  2663. case TOKEN_HASH('u', 's', 'i', 'n'):
  2664. if (SrcPtrHasToken("using"))
  2665. mToken = BfToken_Using;
  2666. break;
  2667. case TOKEN_HASH('v', 'a', 'r', 0):
  2668. if ((!mCompatMode) && (SrcPtrHasToken("var")))
  2669. mToken = BfToken_Var;
  2670. break;
  2671. case TOKEN_HASH('v', 'i', 'r', 't'):
  2672. if (SrcPtrHasToken("virtual"))
  2673. mToken = BfToken_Virtual;
  2674. break;
  2675. case TOKEN_HASH('v', 'o', 'l', 'a'):
  2676. if (SrcPtrHasToken("volatile"))
  2677. mToken = BfToken_Volatile;
  2678. break;
  2679. case TOKEN_HASH('w', 'h', 'e', 'n'):
  2680. if (SrcPtrHasToken("when"))
  2681. mToken = BfToken_When;
  2682. break;
  2683. case TOKEN_HASH('w', 'h', 'e', 'r'):
  2684. if (SrcPtrHasToken("where"))
  2685. mToken = BfToken_Where;
  2686. break;
  2687. case TOKEN_HASH('w', 'h', 'i', 'l'):
  2688. if (SrcPtrHasToken("while"))
  2689. mToken = BfToken_While;
  2690. break;
  2691. case TOKEN_HASH('y', 'i', 'e', 'l'):
  2692. if ((!mCompatMode) && (SrcPtrHasToken("yield")))
  2693. mToken = BfToken_Yield;
  2694. break;
  2695. }
  2696. }
  2697. if (mToken != BfToken_None)
  2698. {
  2699. mSyntaxToken = BfSyntaxToken_Token;
  2700. return;
  2701. }
  2702. bool allowChar = false;
  2703. if (mCompatMode)
  2704. allowChar = (c == '$') || (c == '`');
  2705. if ((uint8)c >= 0xC0)
  2706. {
  2707. int cLen = 0;
  2708. mSrcIdx--;
  2709. uint32 c32 = u8_toucs(mSrc + mSrcIdx, mOrigSrcLength - mSrcIdx, &cLen);
  2710. mSrcIdx += cLen;
  2711. utf8proc_category_t cat = utf8proc_category(c32);
  2712. switch (cat)
  2713. {
  2714. case UTF8PROC_CATEGORY_LU:
  2715. case UTF8PROC_CATEGORY_LL:
  2716. case UTF8PROC_CATEGORY_LT:
  2717. case UTF8PROC_CATEGORY_LM:
  2718. case UTF8PROC_CATEGORY_LO:
  2719. case UTF8PROC_CATEGORY_NL:
  2720. allowChar = true;
  2721. default: break;
  2722. }
  2723. }
  2724. if ((allowChar) ||
  2725. ((c >= 'A') && (c <= 'Z')) ||
  2726. ((c >= 'a') && (c <= 'z')) ||
  2727. (c == '_'))
  2728. {
  2729. if (isVerbatim)
  2730. mTokenStart = verbatimStart;
  2731. while (true)
  2732. {
  2733. int curSrcIdx = mSrcIdx;
  2734. char c = mSrc[mSrcIdx++];
  2735. bool isValidChar =
  2736. (((c >= 'A') && (c <= 'Z')) || ((c >= 'a') && (c <= 'z')) || (c == '_') || ((c >= '0') && (c <= '9')));
  2737. if (mCompatMode)
  2738. isValidChar |= (c == '$') || (c == '`') || (c == '\'');
  2739. if ((uint8)c >= 0xC0)
  2740. {
  2741. int cLen = 0;
  2742. mSrcIdx--;
  2743. uint32 c32 = u8_toucs(mSrc + mSrcIdx, mOrigSrcLength - mSrcIdx, &cLen);
  2744. mSrcIdx += cLen;
  2745. utf8proc_category_t cat = utf8proc_category(c32);
  2746. switch (cat)
  2747. {
  2748. case UTF8PROC_CATEGORY_LU:
  2749. case UTF8PROC_CATEGORY_LL:
  2750. case UTF8PROC_CATEGORY_LT:
  2751. case UTF8PROC_CATEGORY_LM:
  2752. case UTF8PROC_CATEGORY_LO:
  2753. case UTF8PROC_CATEGORY_NL:
  2754. case UTF8PROC_CATEGORY_MN:
  2755. case UTF8PROC_CATEGORY_MC:
  2756. case UTF8PROC_CATEGORY_ND:
  2757. case UTF8PROC_CATEGORY_PC:
  2758. case UTF8PROC_CATEGORY_CF:
  2759. isValidChar = true;
  2760. default: break;
  2761. }
  2762. }
  2763. if (!isValidChar)
  2764. {
  2765. mTokenEnd = curSrcIdx;
  2766. mSrcIdx = curSrcIdx;
  2767. mSyntaxToken = BfSyntaxToken_Identifier;
  2768. return;
  2769. }
  2770. }
  2771. mSyntaxToken = BfSyntaxToken_Identifier;
  2772. return;
  2773. }
  2774. else
  2775. {
  2776. AddErrorNode(mTokenStart, mSrcIdx);
  2777. mTriviaStart = mSrcIdx;
  2778. TokenFail("Unexpected character");
  2779. continue;
  2780. }
  2781. }
  2782. return;
  2783. }
  2784. if ((setVerbatim) && (!isVerbatim))
  2785. {
  2786. isVerbatim = true;
  2787. verbatimStart = mTokenStart;
  2788. }
  2789. }
  2790. }
  2791. static int gParseBlockIdx = 0;
  2792. static int gParseMemberIdx = 0;
  2793. void BfParser::ParseBlock(BfBlock* astNode, int depth)
  2794. {
  2795. gParseBlockIdx++;
  2796. int startParseBlockIdx = gParseBlockIdx;
  2797. bool isAsmBlock = false;
  2798. SizedArray<BfAstNode*, 32> childArr;
  2799. while (true)
  2800. {
  2801. if ((mSyntaxToken == BfSyntaxToken_Token) && (mToken == BfToken_Asm))
  2802. {
  2803. if (isAsmBlock || mInAsmBlock)
  2804. mPassInstance->Fail("Already inside an 'asm' block", astNode);
  2805. else
  2806. isAsmBlock = true;
  2807. }
  2808. NextToken();
  2809. if (mPreprocessorIgnoredSectionNode != NULL)
  2810. {
  2811. if (mSyntaxToken != BfSyntaxToken_EOF)
  2812. continue;
  2813. mPreprocessorIgnoredSectionNode->SetSrcEnd(mSrcIdx);
  2814. }
  2815. if (mScanOnly)
  2816. {
  2817. if (mSyntaxToken == BfSyntaxToken_EOF)
  2818. break;
  2819. continue;
  2820. }
  2821. gParseMemberIdx++;
  2822. int memberIdx = gParseMemberIdx;
  2823. auto childNode = CreateNode();
  2824. if (childNode == NULL)
  2825. break;
  2826. if (mSyntaxToken == BfSyntaxToken_EOF)
  2827. {
  2828. if (astNode != 0)
  2829. Fail("Unexpected end of file");
  2830. break;
  2831. }
  2832. if (mToken == BfToken_LBrace)
  2833. {
  2834. BfBlock* newBlock;
  2835. BfInlineAsmStatement* asmBlock = nullptr;
  2836. BfBlock* genBlock = nullptr;
  2837. /*if (isAsmBlock)
  2838. {
  2839. asmBlock = mAlloc->Alloc<BfInlineAsmStatement>();
  2840. asmBlock->mOpenBrace = (BfTokenNode*)CreateNode();
  2841. newBlock = asmBlock;
  2842. mInAsmBlock = true;
  2843. isAsmBlock = false;
  2844. }
  2845. else*/
  2846. {
  2847. genBlock = mAlloc->Alloc<BfBlock>();
  2848. genBlock->mOpenBrace = (BfTokenNode*)CreateNode();
  2849. newBlock = genBlock;
  2850. }
  2851. newBlock->Init(this);
  2852. ParseBlock(newBlock, depth + 1);
  2853. if (mToken == BfToken_RBrace)
  2854. {
  2855. if (genBlock)
  2856. genBlock->mCloseBrace = (BfTokenNode*)CreateNode();
  2857. else if (asmBlock)
  2858. asmBlock->mCloseBrace = (BfTokenNode*)CreateNode();
  2859. newBlock->SetSrcEnd(mSrcIdx);
  2860. }
  2861. else
  2862. {
  2863. if (mSyntaxToken == BfSyntaxToken_EOF)
  2864. mPassInstance->FailAfterAt("Expected '}'", mSourceData, newBlock->GetSrcEnd() - 1);
  2865. }
  2866. mInAsmBlock = false;
  2867. astNode->Add(newBlock);
  2868. childArr.push_back(newBlock);
  2869. }
  2870. else if (mToken == BfToken_RBrace)
  2871. {
  2872. if (depth == 0)
  2873. Fail("Unexpected ending brace");
  2874. break;
  2875. }
  2876. else
  2877. {
  2878. astNode->Add(childNode);
  2879. childArr.push_back(childNode);
  2880. if ((mSyntaxToken == BfSyntaxToken_Token) && (mToken == BfToken_RBrace))
  2881. break;
  2882. }
  2883. }
  2884. astNode->Init(childArr, mAlloc);
  2885. }
  2886. const char* BfNodeToString(BfAstNode* node)
  2887. {
  2888. static char str[256] = { 0 };
  2889. strncpy(str, node->GetSourceData()->mSrc + node->GetSrcStart(), node->GetSrcLength());
  2890. return str;
  2891. }
  2892. BfAstNode* BfParser::CreateNode()
  2893. {
  2894. switch (mSyntaxToken)
  2895. {
  2896. case BfSyntaxToken_Token:
  2897. {
  2898. auto bfTokenNode = mAlloc->Alloc<BfTokenNode>();
  2899. bfTokenNode->Init(this);
  2900. bfTokenNode->SetToken(mToken);
  2901. return bfTokenNode;
  2902. }
  2903. case BfSyntaxToken_Identifier:
  2904. {
  2905. //auto bfIdentifierNode = new BfIdentifierNode();
  2906. auto bfIdentifierNode = mAlloc->Alloc<BfIdentifierNode>();
  2907. bfIdentifierNode->Init(this);
  2908. return bfIdentifierNode;
  2909. }
  2910. case BfSyntaxToken_Literal:
  2911. {
  2912. auto bfLiteralExpression = mAlloc->Alloc<BfLiteralExpression>();
  2913. bfLiteralExpression->Init(this);
  2914. bfLiteralExpression->mValue = mLiteral;
  2915. mLiteral.mTypeCode = BfTypeCode_None;
  2916. mLiteral.mWarnType = 0;
  2917. return bfLiteralExpression;
  2918. }
  2919. default: break;
  2920. }
  2921. return NULL;
  2922. }
  2923. void BfParser::Parse(BfPassInstance* passInstance)
  2924. {
  2925. BP_ZONE_F("BfParser::Parse %s", mFileName.c_str());
  2926. mPassInstance = passInstance;
  2927. if (mUsingCache)
  2928. {
  2929. mRootNode = mParserData->mRootNode;
  2930. mSidechannelRootNode = mParserData->mSidechannelRootNode;
  2931. mErrorRootNode = mParserData->mErrorRootNode;
  2932. return;
  2933. }
  2934. mRootNode = mAlloc->Alloc<BfRootNode>();
  2935. mRootNode->Init(this);
  2936. mParserData->mRootNode = mRootNode;
  2937. mSidechannelRootNode = mAlloc->Alloc<BfRootNode>();
  2938. mSidechannelRootNode->Init(this);
  2939. mParserData->mSidechannelRootNode = mSidechannelRootNode;
  2940. mErrorRootNode = mAlloc->Alloc<BfRootNode>();
  2941. mErrorRootNode->Init(this);
  2942. mParserData->mErrorRootNode = mErrorRootNode;
  2943. ParseBlock(mRootNode, 0);
  2944. if (mPreprocessorNodeStack.size() > 0)
  2945. {
  2946. mPassInstance->Warn(0, "No matching #endif found", mPreprocessorNodeStack.back().first);
  2947. }
  2948. for (int i = 1; i < mJumpTableSize; i++)
  2949. if (mJumpTable[i].mCharIdx == 0)
  2950. mJumpTable[i] = mJumpTable[i - 1];
  2951. if (mPassInstance->HasFailed())
  2952. mParsingFailed = true;
  2953. if ((mPassInstance->HasMessages()) || (mParsingFailed))
  2954. {
  2955. mParserData->mFailed = true; // Don't reuse cache if there were errors or warnings
  2956. }
  2957. mPassInstance = NULL;
  2958. }
  2959. int BfParser::GetCharIdAtIndex(int findIndex)
  2960. {
  2961. return mParserData->GetCharIdAtIndex(findIndex);
  2962. }
  2963. void BfParser::Close()
  2964. {
  2965. BfSource::Close();
  2966. BfLogSys(mSystem, "Parser %p closing. RefCount:%d Failed:%d\n", this, mParserData->mRefCount, mParserData->mFailed);
  2967. if ((mParserData->mRefCount == 0) && (!mParserData->mFailed))
  2968. {
  2969. BF_ASSERT(mParserData->mDidReduce);
  2970. AutoCrit autoCrit(gBfParserCache->mCritSect);
  2971. BfParserCache::DataEntry dataEntry;
  2972. dataEntry.mParserData = mParserData;
  2973. if (gBfParserCache->mEntries.Add(dataEntry))
  2974. {
  2975. BfLogSys(mSystem, "Parser %p added to cache\n", this);
  2976. mParserData->mRefCount++;
  2977. }
  2978. else
  2979. {
  2980. // It's possible two of the same entries were being parsed at the same time on different threads.
  2981. // Just let the loser be deleted in the dtor
  2982. BfLogSys(mSystem, "Duplicate parser %p not added to cache\n", this);
  2983. }
  2984. }
  2985. }
  2986. void BfParser::GenerateAutoCompleteFrom(int srcPosition)
  2987. {
  2988. BfSourcePositionFinder posFinder(this, srcPosition);
  2989. posFinder.Visit(mRootNode);
  2990. if (posFinder.mClosestElement != NULL)
  2991. {
  2992. }
  2993. }
  2994. void BfParser::ReportMemory(MemReporter* memReporter)
  2995. {
  2996. //memReporter->Add("SmallAstAlloc", (int)mAlloc->mPages.size() * BfAstAllocManager::PAGE_SIZE);
  2997. //memReporter->Add("LargeAstAlloc", mAlloc->mLargeAllocSizes);
  2998. // if (!mUsingCache)
  2999. // memReporter->AddBumpAlloc("AstAlloc", *mAlloc);
  3000. //
  3001. // memReporter->Add("JumpTable", mJumpTableSize * sizeof(BfLineStartEntry));
  3002. memReporter->Add(sizeof(BfParser));
  3003. if (mParserData->mRefCount <= 0)
  3004. mParserData->ReportMemory(memReporter);
  3005. // if (mSrcAllocSize > 0)
  3006. // memReporter->Add("Source", mSrcAllocSize);
  3007. }
  3008. class BfInnermostFinder : public BfElementVisitor
  3009. {
  3010. public:
  3011. int mCursorIdx;
  3012. BfAstNode* mFoundNode;
  3013. BfInnermostFinder(int cursorIdx)
  3014. {
  3015. mFoundNode = NULL;
  3016. mCursorIdx = cursorIdx;
  3017. }
  3018. virtual void Visit(BfAstNode* node) override
  3019. {
  3020. if ((node->Contains(mCursorIdx)) && (!node->IsA<BfBlock>()))
  3021. {
  3022. if ((mFoundNode == NULL) || ((node->GetSrcLength()) <= (mFoundNode->GetSrcLength())))
  3023. mFoundNode = node;
  3024. }
  3025. }
  3026. virtual void Visit(BfMemberReferenceExpression* memberRefExpr) override
  3027. {
  3028. BfElementVisitor::Visit(memberRefExpr);
  3029. if (mFoundNode == memberRefExpr->mMemberName)
  3030. {
  3031. mFoundNode = memberRefExpr;
  3032. }
  3033. }
  3034. virtual void Visit(BfAttributedIdentifierNode* identifierNode) override
  3035. {
  3036. BfElementVisitor::Visit(identifierNode);
  3037. if (mFoundNode == identifierNode->mIdentifier)
  3038. {
  3039. mFoundNode = identifierNode;
  3040. }
  3041. }
  3042. virtual void Visit(BfQualifiedNameNode* qualifiedNameNode) override
  3043. {
  3044. BfElementVisitor::Visit(qualifiedNameNode);
  3045. if (mFoundNode == qualifiedNameNode->mRight)
  3046. {
  3047. mFoundNode = qualifiedNameNode;
  3048. }
  3049. }
  3050. virtual void Visit(BfBinaryOperatorExpression* binaryOpExpr) override
  3051. {
  3052. BfElementVisitor::Visit(binaryOpExpr);
  3053. if (mFoundNode == binaryOpExpr->mOpToken)
  3054. {
  3055. mFoundNode = binaryOpExpr;
  3056. }
  3057. }
  3058. virtual void Visit(BfPreprocessorNode* preprocNode) override
  3059. {
  3060. if (preprocNode->mArgument != NULL)
  3061. {
  3062. for (auto arg : preprocNode->mArgument->mChildArr)
  3063. {
  3064. Visit((BfAstNode*)arg);
  3065. if (mFoundNode == arg)
  3066. {
  3067. mFoundNode = preprocNode;
  3068. }
  3069. }
  3070. }
  3071. }
  3072. };
  3073. static BfAstNode* FindDebugExpressionNode(BfAstNode* checkNode, int cursorIdx)
  3074. {
  3075. BfInnermostFinder innermostFinder(cursorIdx);
  3076. innermostFinder.VisitChild(checkNode);
  3077. BfAstNode* exprNode = innermostFinder.mFoundNode;
  3078. return exprNode;
  3079. }
  3080. //////////////////////////////////////////////////////////////////////////
  3081. BF_EXPORT void BF_CALLTYPE BfParser_SetSource(BfParser* bfParser, const char* data, int length, const char* fileName)
  3082. {
  3083. bfParser->mFileName = fileName;
  3084. bfParser->SetSource(data, length);
  3085. }
  3086. BF_EXPORT void BF_CALLTYPE BfParser_SetCharIdData(BfParser* bfParser, uint8* data, int length)
  3087. {
  3088. if (bfParser->mParserData->mCharIdData != NULL)
  3089. delete bfParser->mParserData->mCharIdData;
  3090. bfParser->mParserData->mCharIdData = new uint8[length];
  3091. memcpy(bfParser->mParserData->mCharIdData, data, length);
  3092. }
  3093. BF_EXPORT void BF_CALLTYPE BfParser_SetHashMD5(BfParser* bfParser, Val128* md5Hash)
  3094. {
  3095. if (md5Hash != NULL)
  3096. bfParser->mParserData->mMD5Hash = *md5Hash;
  3097. }
  3098. BF_EXPORT void BF_CALLTYPE BfParser_Delete(BfParser* bfParser)
  3099. {
  3100. if (bfParser->mNextRevision != NULL)
  3101. bfParser->mNextRevision->mPrevRevision = NULL;
  3102. auto itr = std::find(bfParser->mSystem->mParsers.begin(), bfParser->mSystem->mParsers.end(), bfParser);
  3103. bfParser->mSystem->mParsers.erase(itr);
  3104. delete bfParser;
  3105. }
  3106. BF_EXPORT void BF_CALLTYPE BfParser_SetNextRevision(BfParser* bfParser, BfParser* nextRevision)
  3107. {
  3108. BF_ASSERT(bfParser->mNextRevision == NULL);
  3109. BF_ASSERT(nextRevision->mPrevRevision == NULL);
  3110. bfParser->mNextRevision = nextRevision;
  3111. nextRevision->mPrevRevision = bfParser;
  3112. nextRevision->mDataId = bfParser->mDataId;
  3113. }
  3114. BF_EXPORT void BF_CALLTYPE BfParser_SetCursorIdx(BfParser* bfParser, int cursorIdx)
  3115. {
  3116. bfParser->SetCursorIdx(cursorIdx);
  3117. }
  3118. BF_EXPORT void BF_CALLTYPE BfParser_SetIsClassifying(BfParser* bfParser)
  3119. {
  3120. bfParser->mParserFlags = (BfParserFlag)(bfParser->mParserFlags | ParserFlag_Classifying);
  3121. }
  3122. BF_EXPORT void BF_CALLTYPE BfParser_SetAutocomplete(BfParser* bfParser, int cursorIdx)
  3123. {
  3124. BF_ASSERT(bfParser->mParserData->mRefCount == -1);
  3125. bfParser->SetCursorIdx(cursorIdx);
  3126. bfParser->mParserFlags = (BfParserFlag)(bfParser->mParserFlags | ParserFlag_Autocomplete | ParserFlag_Classifying);
  3127. }
  3128. PerfManager* BfGetPerfManager(BfParser* bfParser)
  3129. {
  3130. if (bfParser == NULL)
  3131. return NULL;
  3132. if (bfParser->mCursorIdx != -1)
  3133. return gPerfManager;
  3134. return NULL;
  3135. }
  3136. BF_EXPORT bool BF_CALLTYPE BfParser_Parse(BfParser* bfParser, BfPassInstance* bfPassInstance, bool compatMode)
  3137. {
  3138. BP_ZONE("BfParser_Parse");
  3139. int startFailIdx = bfPassInstance->mFailedIdx;
  3140. bfParser->mCompatMode = compatMode;
  3141. bfParser->mQuickCompatMode = compatMode;
  3142. bfParser->Parse(bfPassInstance);
  3143. return startFailIdx == bfPassInstance->mFailedIdx;
  3144. }
  3145. BF_EXPORT bool BF_CALLTYPE BfParser_Reduce(BfParser* bfParser, BfPassInstance* bfPassInstance)
  3146. {
  3147. BP_ZONE("BfParser_Reduce");
  3148. if (bfParser->mUsingCache)
  3149. return true; // Already reduced
  3150. bfParser->FinishSideNodes();
  3151. int startFailIdx = bfPassInstance->mFailedIdx;
  3152. int startWarningCount = bfPassInstance->mWarningCount;
  3153. BfReducer bfReducer;
  3154. bfReducer.mSource = bfParser;
  3155. bfReducer.mCompatMode = bfParser->mCompatMode;
  3156. bfReducer.mPassInstance = bfPassInstance;
  3157. bfReducer.HandleRoot(bfParser->mRootNode);
  3158. if ((startFailIdx != bfPassInstance->mFailedIdx) ||
  3159. (startWarningCount != bfPassInstance->mWarningCount))
  3160. bfParser->mParserData->mFailed = true;
  3161. bfParser->mParserData->mDidReduce = true;
  3162. bfParser->Close();
  3163. return startFailIdx == bfPassInstance->mFailedIdx;
  3164. }
  3165. static Array<int> gCharMapping;
  3166. BF_EXPORT const char* BF_CALLTYPE BfParser_Format(BfParser* bfParser, int formatStart, int formatEnd, int** outCharMapping)
  3167. {
  3168. BP_ZONE("BfParser_Reduce");
  3169. String& outString = *gTLStrReturn.Get();
  3170. outString.clear();
  3171. gCharMapping.Clear();
  3172. BfPrinter bfPrinter(bfParser->mRootNode, bfParser->mSidechannelRootNode, bfParser->mErrorRootNode);
  3173. bfPrinter.mFormatStart = formatStart;
  3174. bfPrinter.mFormatEnd = formatEnd;
  3175. bfPrinter.mCharMapping = &gCharMapping;
  3176. bfPrinter.Visit(bfParser->mRootNode);
  3177. outString = bfPrinter.mOutString;
  3178. *outCharMapping = &gCharMapping[0];
  3179. return outString.c_str();
  3180. }
  3181. BF_EXPORT const char* BF_CALLTYPE BfParser_DocPrep(BfParser* bfParser)
  3182. {
  3183. BP_ZONE("BfParser_Reduce");
  3184. String& outString = *gTLStrReturn.Get();
  3185. outString.clear();
  3186. gCharMapping.Clear();
  3187. BfPrinter bfPrinter(bfParser->mRootNode, bfParser->mSidechannelRootNode, bfParser->mErrorRootNode);
  3188. bfPrinter.mFormatStart = -1;
  3189. bfPrinter.mFormatEnd = -1;
  3190. bfPrinter.mCharMapping = &gCharMapping;
  3191. bfPrinter.mDocPrep = true;
  3192. bfPrinter.Visit(bfParser->mRootNode);
  3193. outString = bfPrinter.mOutString;
  3194. return outString.c_str();
  3195. }
  3196. BF_EXPORT const char* BF_CALLTYPE BfParser_GetDebugExpressionAt(BfParser* bfParser, int cursorIdx)
  3197. {
  3198. BP_ZONE("BfParser_Reduce");
  3199. String& outString = *gTLStrReturn.Get();
  3200. outString.clear();
  3201. BfAstNode* exprNode = FindDebugExpressionNode(bfParser->mRootNode, cursorIdx);
  3202. if (exprNode == NULL)
  3203. exprNode = FindDebugExpressionNode(bfParser->mSidechannelRootNode, cursorIdx);
  3204. if (exprNode == NULL)
  3205. return NULL;
  3206. if ((exprNode->IsA<BfMethodDeclaration>()) ||
  3207. (exprNode->IsA<BfBlock>()) ||
  3208. (exprNode->IsA<BfStatement>()) ||
  3209. (exprNode->IsA<BfTokenNode>())
  3210. )
  3211. {
  3212. return NULL;
  3213. }
  3214. BfPrinter bfPrinter(bfParser->mRootNode, NULL, NULL);
  3215. bfPrinter.mReformatting = true;
  3216. bfPrinter.mIgnoreTrivia = true;
  3217. bfPrinter.VisitChild(exprNode);
  3218. outString = bfPrinter.mOutString;
  3219. if (auto preprocessorNode = BfNodeDynCast<BfPreprocessorNode>(exprNode))
  3220. {
  3221. auto firstStr = preprocessorNode->mArgument->mChildArr[0]->ToString();
  3222. if (firstStr == "warning")
  3223. {
  3224. String warningNumStr = preprocessorNode->mArgument->mChildArr.back()->ToString();
  3225. int warningNum = atoi(warningNumStr.c_str());
  3226. String warningStr;
  3227. switch (warningNum)
  3228. {
  3229. case BfWarning_CS0108_MemberHidesInherited:
  3230. warningStr = "CS0108: Derived member hides inherited member";
  3231. break;
  3232. case BfWarning_CS0114_MethodHidesInherited:
  3233. warningStr = "CS0114: Derived method hides inherited member";
  3234. break;
  3235. case BfWarning_CS0162_UnreachableCode:
  3236. warningStr = "CS0162: Unreachable code";
  3237. break;
  3238. case BfWarning_CS0168_VariableDeclaredButNeverUsed:
  3239. warningStr = "CS0168: Variable declared but never used";
  3240. break;
  3241. case BfWarning_CS0472_ValueTypeNullCompare:
  3242. warningStr = "CS0472: ValueType compared to null";
  3243. break;
  3244. case BfWarning_CS1030_PragmaWarning:
  3245. warningStr = "CS1030: Pragma warning";
  3246. break;
  3247. }
  3248. if (!warningStr.empty())
  3249. outString = "`" + warningStr;
  3250. }
  3251. }
  3252. return outString.c_str();
  3253. }
  3254. BF_EXPORT BfResolvePassData* BF_CALLTYPE BfParser_CreateResolvePassData(BfParser* bfParser, BfResolveType resolveType)
  3255. {
  3256. auto bfResolvePassData = new BfResolvePassData();
  3257. bfResolvePassData->mResolveType = resolveType;
  3258. bfResolvePassData->mParser = bfParser;
  3259. if ((bfParser != NULL) && ((bfParser->mParserFlags & ParserFlag_Autocomplete) != 0))
  3260. bfResolvePassData->mAutoComplete = new BfAutoComplete(resolveType);
  3261. return bfResolvePassData;
  3262. }
  3263. BF_EXPORT bool BF_CALLTYPE BfParser_BuildDefs(BfParser* bfParser, BfPassInstance* bfPassInstance, BfResolvePassData* resolvePassData, bool fullRefresh)
  3264. {
  3265. BP_ZONE("BfParser_BuildDefs");
  3266. int startFailIdx = bfPassInstance->mFailedIdx;
  3267. BfDefBuilder defBuilder(bfParser->mSystem);
  3268. defBuilder.mResolvePassData = resolvePassData;
  3269. defBuilder.Process(bfPassInstance, bfParser, fullRefresh);
  3270. return startFailIdx == bfPassInstance->mFailedIdx;;
  3271. }
  3272. BF_EXPORT void BF_CALLTYPE BfParser_RemoveDefs(BfParser* bfParser)
  3273. {
  3274. }
  3275. BF_EXPORT void BF_CALLTYPE BfParser_ClassifySource(BfParser* bfParser, BfSourceClassifier::CharData* charData, bool preserveFlags)
  3276. {
  3277. if (!bfParser->mIsClosed)
  3278. bfParser->Close();
  3279. BfSourceClassifier bfSourceClassifier(bfParser, charData);
  3280. bfSourceClassifier.mPreserveFlags = preserveFlags;
  3281. bfSourceClassifier.Visit(bfParser->mRootNode);
  3282. bfSourceClassifier.mIsSideChannel = false; //? false or true?
  3283. bfSourceClassifier.Visit(bfParser->mErrorRootNode);
  3284. bfSourceClassifier.mIsSideChannel = true;
  3285. bfSourceClassifier.Visit(bfParser->mSidechannelRootNode);
  3286. }
  3287. BF_EXPORT void BF_CALLTYPE BfParser_GenerateAutoCompletionFrom(BfParser* bfParser, int srcPosition)
  3288. {
  3289. BP_ZONE("BfParser_GenerateAutoCompletionFrom");
  3290. bfParser->GenerateAutoCompleteFrom(srcPosition);
  3291. }
  3292. BF_EXPORT void BF_CALLTYPE BfParser_SetCompleteParse(BfParser* bfParser)
  3293. {
  3294. bfParser->mCompleteParse = true;
  3295. }