BfDemangler.cpp 49 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517
  1. #include "BfDemangler.h"
  2. USING_NS_BF;
  3. static char SafeGetChar(const StringImpl& str, int idx)
  4. {
  5. if (idx >= (int)str.length())
  6. return '!';
  7. return str[idx];
  8. }
  9. DemangleBase::DemangleBase()
  10. {
  11. mCurIdx = 0;
  12. mFailed = false;
  13. mLanguage = DbgLanguage_Unknown;
  14. mInArgs = false;
  15. mBeefFixed = false;
  16. }
  17. bool DemangleBase::Failed()
  18. {
  19. //BF_DBG_FATAL("DwDemangler::Failed");
  20. mFailed = true;
  21. return false;
  22. }
  23. void DemangleBase::Require(bool result)
  24. {
  25. //BF_ASSERT(result);
  26. if (!result)
  27. {
  28. mFailed = true;
  29. }
  30. }
  31. //////////////////////////////////////////////////////////////////////////
  32. DwDemangler::DwDemangler()
  33. {
  34. mOmitSubstituteAdd = false;
  35. mIsFirstName = true;
  36. mTemplateDepth = 0;
  37. mCaptureTargetType = false;
  38. mFunctionPopSubstitute = false;
  39. mRawDemangle = false;
  40. }
  41. #define RETURN_STR(strVal) do { outName = strVal; return true; } while(false)
  42. bool DwDemangler::DemangleBuiltinType(StringImpl& outName)
  43. {
  44. auto firstChar = SafeGetChar(mMangledName, mCurIdx++);
  45. switch (firstChar)
  46. {
  47. case 'v':
  48. RETURN_STR("void");
  49. case 'w':
  50. RETURN_STR("wchar_t");
  51. case 'b':
  52. RETURN_STR("bool");
  53. case 'a':
  54. if (mLanguage == DbgLanguage_Beef)
  55. RETURN_STR("int8");
  56. else
  57. RETURN_STR("sbyte");
  58. case 'h':
  59. if (mLanguage == DbgLanguage_Beef)
  60. RETURN_STR("uint8");
  61. else
  62. RETURN_STR("byte");
  63. case 's':
  64. RETURN_STR("short");
  65. case 't':
  66. RETURN_STR("ushort");
  67. case 'i':
  68. if (mLanguage == DbgLanguage_Beef)
  69. RETURN_STR("int32");
  70. else
  71. RETURN_STR("int");
  72. case 'j':
  73. if (mLanguage == DbgLanguage_Beef)
  74. RETURN_STR("uint32");
  75. else
  76. RETURN_STR("uint");
  77. case 'x':
  78. RETURN_STR("long");
  79. case 'l':
  80. if (mLanguage == DbgLanguage_Beef)
  81. RETURN_STR("int32");
  82. else
  83. RETURN_STR("int");
  84. case 'm':
  85. if (mLanguage == DbgLanguage_Beef)
  86. RETURN_STR("uint32");
  87. else
  88. RETURN_STR("uint");
  89. case 'y':
  90. RETURN_STR("ulong");
  91. case 'c':
  92. if (mLanguage == DbgLanguage_Beef)
  93. RETURN_STR("char8");
  94. else
  95. RETURN_STR("char");
  96. case 'f':
  97. RETURN_STR("float");
  98. case 'd':
  99. RETURN_STR("double");
  100. case 'n':
  101. RETURN_STR("__int128");
  102. case 'o':
  103. RETURN_STR("__uint128");
  104. case 'e':
  105. RETURN_STR("__float80");
  106. case 'g':
  107. RETURN_STR("__float128");
  108. case 'z':
  109. RETURN_STR("...");
  110. case 'D':
  111. {
  112. char nextChar = SafeGetChar(mMangledName, mCurIdx++);
  113. switch (nextChar)
  114. {
  115. case 'i':
  116. RETURN_STR("char32");
  117. case 's':
  118. RETURN_STR("char16");
  119. case 'a':
  120. RETURN_STR("auto");
  121. case 'c':
  122. RETURN_STR("decltype(auto)");
  123. case 'n':
  124. RETURN_STR("std::nullptr_t");
  125. default:
  126. RETURN_STR("?");
  127. }
  128. }
  129. break;
  130. default:
  131. mCurIdx--;
  132. break;
  133. }
  134. return false;
  135. }
  136. bool DwDemangler::DemangleArrayType(StringImpl& outName)
  137. {
  138. //TODO:
  139. /*auto firstChar = SafeGetChar(mMangledName, mCurIdx++);
  140. switch (firstChar)
  141. {
  142. case 'A':
  143. {
  144. }
  145. break;
  146. default:
  147. mCurIdx--;
  148. }*/
  149. return false;
  150. }
  151. bool DwDemangler::DemangleClassEnumType(StringImpl& outName)
  152. {
  153. if (DemangleName(outName))
  154. return true;
  155. //TODO: 'Ts', 'Tu', 'Te'
  156. return false;
  157. }
  158. bool DwDemangler::DemangleFunction(StringImpl& outName)
  159. {
  160. bool wantsReturnValue = false;
  161. //String outName;
  162. bool hasTemplateArgs;
  163. Require(DemangleName(outName, &hasTemplateArgs));
  164. mIsFirstName = false;
  165. if (hasTemplateArgs)
  166. wantsReturnValue = true;
  167. // Pop either function name or template args
  168. if (mSubstituteList.size() > 0)
  169. mSubstituteList.pop_back();
  170. if (mCaptureTargetType)
  171. {
  172. int lastAt = (int)outName.LastIndexOf('@');
  173. if (lastAt != -1)
  174. {
  175. DwDemangler subDemangler;
  176. outName.Remove(0, lastAt + 1);
  177. outName = subDemangler.Demangle(outName);
  178. return true;
  179. }
  180. int lastDot = (int)outName.LastIndexOf('.');
  181. if (lastDot != -1)
  182. outName.RemoveToEnd(lastDot);
  183. return true;
  184. }
  185. // New
  186. if (mFunctionPopSubstitute)
  187. {
  188. BF_ASSERT(mSubstituteList.size() > 0);
  189. if (mSubstituteList.size() > 0)
  190. mSubstituteList.pop_back();
  191. mFunctionPopSubstitute = false;
  192. }
  193. if (mCurIdx < (int) mMangledName.length())
  194. {
  195. //TODO: Needed? Caused a crash. mSubstituteList.pop_back(); // Remove method name
  196. int atPos = (int)outName.LastIndexOf('@');
  197. if (atPos != -1)
  198. {
  199. int dotPos = (int)outName.LastIndexOf('.', atPos);
  200. if (dotPos != -1)
  201. {
  202. StringT<256> prefix = outName.Substring(dotPos + 1, atPos - dotPos - 1);
  203. if ((prefix == "get") || (prefix == "set"))
  204. {
  205. outName = outName.Substring(0, dotPos + 1) + outName.Substring(atPos + 1) + " " + prefix;
  206. return true;
  207. }
  208. }
  209. }
  210. outName += "(";
  211. bool needsComma = false;
  212. for (int paramIdx = 0; mCurIdx < (int)mMangledName.length(); paramIdx++)
  213. {
  214. if (SafeGetChar(mMangledName, mCurIdx) == 'E')
  215. break;
  216. if (needsComma)
  217. outName += ", ";
  218. StringT<256> paramType;
  219. Require(DemangleType(paramType));
  220. bool atEnd = mCurIdx >= (int) mMangledName.length();
  221. if ((paramIdx == 0) && (wantsReturnValue))
  222. {
  223. outName = paramType + " " + outName;
  224. }
  225. else
  226. {
  227. if ((paramType == "void") && (paramIdx == 0) && (atEnd))
  228. break;
  229. outName += paramType;
  230. needsComma = true;
  231. }
  232. if (mFailed)
  233. break;
  234. }
  235. outName += ")";
  236. }
  237. return true;
  238. }
  239. bool DwDemangler::DemangleLocalName(StringImpl& outName)
  240. {
  241. auto firstChar = SafeGetChar(mMangledName, mCurIdx++);
  242. if (firstChar == 'Z')
  243. {
  244. if (SafeGetChar(mMangledName, mCurIdx) == 'L') // Literal (?)
  245. mCurIdx++;
  246. DemangleFunction(outName);
  247. auto endChar = SafeGetChar(mMangledName, mCurIdx++);
  248. if (endChar != 'E')
  249. return false;
  250. endChar = SafeGetChar(mMangledName, mCurIdx++);
  251. if (endChar == 's')
  252. {
  253. //
  254. }
  255. else
  256. {
  257. mCurIdx--;
  258. StringT<256> entityName;
  259. Require(DemangleName(entityName));
  260. if (mLanguage == DbgLanguage_Beef)
  261. outName += "." + entityName;
  262. else
  263. outName += "::" + entityName;
  264. }
  265. endChar = SafeGetChar(mMangledName, mCurIdx++);
  266. if (endChar == '_')
  267. {
  268. //
  269. }
  270. else
  271. {
  272. mCurIdx--;
  273. }
  274. BF_ASSERT(mSubstituteList.size() > 0);
  275. if (mSubstituteList.size() >= 2)
  276. {
  277. mSubstituteList.pop_back();
  278. mSubstituteList[mSubstituteList.size() - 1] = outName;
  279. }
  280. return true;
  281. }
  282. mCurIdx--;
  283. return false;
  284. }
  285. bool DwDemangler::DemangleType(StringImpl& outName)
  286. {
  287. StringT<256> cvQualifiers;
  288. if (DemangleCVQualifiers(cvQualifiers))
  289. {
  290. Require(DemangleType(outName));
  291. outName = cvQualifiers + " " + outName;
  292. mSubstituteList.push_back(outName);
  293. return true;
  294. }
  295. auto firstChar = SafeGetChar(mMangledName, mCurIdx++);
  296. switch (firstChar)
  297. {
  298. case 'D':
  299. {
  300. auto nextChar = SafeGetChar(mMangledName, mCurIdx++);
  301. if (nextChar == 'p')
  302. {
  303. Require(DemangleType(outName));
  304. return true;
  305. }
  306. mCurIdx--;
  307. }
  308. case 'P':
  309. if (DemangleFunctionType(outName))
  310. {
  311. mSubstituteList.push_back(outName);
  312. return true;
  313. }
  314. if (DemangleType(outName))
  315. {
  316. outName = outName + "*";
  317. mSubstituteList.push_back(outName);
  318. return true;
  319. }
  320. break;
  321. case 'R':
  322. if (DemangleType(outName))
  323. {
  324. outName = outName + "&";
  325. mSubstituteList.push_back(outName);
  326. return true;
  327. }
  328. break;
  329. case 'O':
  330. if (DemangleType(outName))
  331. {
  332. if (outName[outName.length() - 1] != '&')
  333. outName = outName + "&&";
  334. mSubstituteList.push_back(outName);
  335. return true;
  336. }
  337. break;
  338. case 'U':
  339. {
  340. StringT<256> modName;
  341. Require(DemangleUnqualifiedName(modName));
  342. Require(DemangleType(outName));
  343. if (modName[0] == '@')
  344. outName = outName + " " + modName.Substring(1);
  345. else
  346. outName = modName + " " + outName;
  347. return true;
  348. }
  349. break;
  350. //TODO: 'C', 'G', 'U'
  351. default:
  352. mCurIdx--;
  353. break;
  354. }
  355. if (DemangleBuiltinType(outName))
  356. return true;
  357. if (DemangleFunctionType(outName))
  358. return true;
  359. if (DemangleSubstitution(outName))
  360. {
  361. StringT<256> templateArgs;
  362. if (DemangleTemplateArgs(templateArgs))
  363. {
  364. outName += templateArgs;
  365. mSubstituteList.push_back(outName);
  366. }
  367. return true;
  368. }
  369. if (DemangleClassEnumType(outName))
  370. return true;
  371. //TODO: DemangleArrayType
  372. //TODO: DemanglePointerToMemberType
  373. if (DemangleTemplateParam(outName))
  374. return true;
  375. //TODO: TemplateTemplateParam
  376. //TODO: DeclType
  377. return false;
  378. }
  379. bool DwDemangler::DemangleFunctionType(StringImpl& outName)
  380. {
  381. auto firstChar = SafeGetChar(mMangledName, mCurIdx++);
  382. if (firstChar == 'F')
  383. {
  384. StringT<256> returnType;
  385. Require(DemangleType(returnType));
  386. outName = returnType + " (*)(";
  387. for (int paramNum = 0; true; paramNum++)
  388. {
  389. if (DemangleEnd())
  390. break;
  391. if (paramNum > 0)
  392. outName += ", ";
  393. StringT<256> paramType;
  394. Require(DemangleType(paramType));
  395. outName += paramType;
  396. }
  397. outName += ")";
  398. return true;
  399. }
  400. mCurIdx--;
  401. return false;
  402. }
  403. bool DwDemangler::DemangleNestedName(StringImpl& outName)
  404. {
  405. auto firstChar = SafeGetChar(mMangledName, mCurIdx++);
  406. switch (firstChar)
  407. {
  408. case 'N':
  409. {
  410. }
  411. break;
  412. }
  413. mCurIdx--;
  414. return false;
  415. }
  416. bool DwDemangler::DemangleCVQualifiers(StringImpl& outName)
  417. {
  418. auto firstChar = SafeGetChar(mMangledName, mCurIdx++);
  419. switch (firstChar)
  420. {
  421. case 'r':
  422. RETURN_STR("restrict");
  423. case 'V':
  424. RETURN_STR("volatile");
  425. case 'K':
  426. RETURN_STR("const");
  427. }
  428. mCurIdx--;
  429. return false;
  430. }
  431. bool DwDemangler::DemangleRefQualifier(StringImpl& outName)
  432. {
  433. auto firstChar = SafeGetChar(mMangledName, mCurIdx++);
  434. switch (firstChar)
  435. {
  436. case 'R':
  437. RETURN_STR("&");
  438. case 'O':
  439. RETURN_STR("&&");
  440. }
  441. mCurIdx--;
  442. return false;
  443. }
  444. bool DwDemangler::DemangleOperatorName(StringImpl& outName)
  445. {
  446. auto firstChar = SafeGetChar(mMangledName, mCurIdx++);
  447. StringT<64> opCode;
  448. opCode += firstChar;
  449. opCode += SafeGetChar(mMangledName, mCurIdx++);
  450. StringT<64> opName;
  451. if (opCode == "nw")
  452. opName = " new";
  453. else if (opCode == "na")
  454. opName = " new[]";
  455. else if (opCode == "dl")
  456. opName = " delete";
  457. else if (opCode == "da")
  458. opName = " delete[]";
  459. else if (opCode == "pl")
  460. opName = "+";
  461. else if (opCode == "mi")
  462. opName = "-";
  463. else if (opCode == "ml")
  464. opName = "*";
  465. else if (opCode == "dv")
  466. opName = "/";
  467. else if (opCode == "rm")
  468. opName = "%";
  469. else if (opCode == "an")
  470. opName = "&";
  471. else if (opCode == "or")
  472. opName = "|";
  473. else if (opCode == "eo")
  474. opName = "^";
  475. else if (opCode == "aS")
  476. opName = "=";
  477. else if (opCode == "pL")
  478. opName = "+=";
  479. else if (opCode == "mI")
  480. opName = "-=";
  481. else if (opCode == "mL")
  482. opName = "*=";
  483. else if (opCode == "dV")
  484. opName = "/=";
  485. else if (opCode == "rM")
  486. opName = "%=";
  487. else if (opCode == "aN")
  488. opName = "&=";
  489. else if (opCode == "oR")
  490. opName = "|=";
  491. else if (opCode == "eO")
  492. opName = "^=";
  493. else if (opCode == "ls")
  494. opName = "<<";
  495. else if (opCode == "rs")
  496. opName = ">>";
  497. else if (opCode == "eq")
  498. opName = "==";
  499. else if (opCode == "ne")
  500. opName = "!=";
  501. else if (opCode == "lt")
  502. opName = "<";
  503. else if (opCode == "gt")
  504. opName = ">";
  505. else if (opCode == "ge")
  506. opName = ">=";
  507. else if (opCode == "le")
  508. opName = "<=";
  509. else if (opCode == "aa")
  510. opName = "&&";
  511. else if (opCode == "oo")
  512. opName = "||";
  513. else if (opCode == "ad")
  514. opName = "&";
  515. else if (opCode == "de")
  516. opName = "*";
  517. else if (opCode == "ng")
  518. opName = "-";
  519. else if (opCode == "nt")
  520. opName = "!";
  521. else if (opCode == "ps")
  522. opName = "+";
  523. else if (opCode == "co")
  524. opName = "~";
  525. else if (opCode == "pp")
  526. opName = "++";
  527. else if (opCode == "mm")
  528. opName = "--";
  529. else if (opCode == "cm")
  530. opName = ",";
  531. else if (opCode == "pm")
  532. opName = "->*";
  533. else if (opCode == "pt")
  534. opName = "->";
  535. else if (opCode == "ix")
  536. opName = "[]";
  537. else if (opCode == "cl")
  538. opName = "()";
  539. else if (opCode == "qu")
  540. opName = "?";
  541. else if (opCode == "li")
  542. {
  543. opName = "\"\"";
  544. }
  545. else if (opCode == "cv")
  546. {
  547. StringT<256> typeName;
  548. Require(DemangleType(typeName));
  549. opName = " " + typeName;
  550. }
  551. else if ((opCode == "C1") || (opCode == "C2") || (opCode == "C3"))
  552. {
  553. outName += "this";
  554. }
  555. else if ((opCode == "D0") || (opCode == "D1") || (opCode == "D2"))
  556. {
  557. outName += "~this";
  558. }
  559. else
  560. {
  561. mCurIdx -= 2;
  562. return false;
  563. }
  564. if (!opName.empty())
  565. outName += "operator" + opName;
  566. //mSubstituteList.push_back(outName);
  567. return true;
  568. }
  569. bool DwDemangler::DemangleSourceName(StringImpl& outName)
  570. {
  571. auto c = SafeGetChar(mMangledName, mCurIdx);
  572. if ((c >= '0') && (c <= '9'))
  573. {
  574. int nameLen = 0;
  575. while (mCurIdx < (int) mMangledName.length())
  576. {
  577. char c = mMangledName[mCurIdx];
  578. if ((c >= '0') && (c <= '9'))
  579. {
  580. nameLen = (int) (c - '0') + (nameLen * 10);
  581. mCurIdx++;
  582. }
  583. else
  584. break;
  585. }
  586. for (int nameIdx = 0; ((nameIdx < nameLen) && (mCurIdx < (int) mMangledName.length())); nameIdx++)
  587. {
  588. char c = mMangledName[mCurIdx++];
  589. outName += c;
  590. }
  591. //mSubstituteList.push_back(outName);
  592. return true;
  593. }
  594. return false;
  595. }
  596. bool DwDemangler::DemangleUnqualifiedName(StringImpl& outName)
  597. {
  598. if (DemangleOperatorName(outName)) // Also handles ctor/dtor
  599. return true;
  600. if (DemangleSourceName(outName))
  601. return true;
  602. return false;
  603. }
  604. bool DwDemangler::DemangleEnd()
  605. {
  606. auto firstChar = SafeGetChar(mMangledName, mCurIdx++);
  607. if (firstChar == 'E')
  608. return true;
  609. mCurIdx--;
  610. return false;
  611. }
  612. bool DwDemangler::DemangleInternalName(StringImpl& outName)
  613. {
  614. auto firstChar = SafeGetChar(mMangledName, mCurIdx++);
  615. if (firstChar == 'L')
  616. {
  617. bool result = DemangleSourceName(outName);
  618. Require(result);
  619. return result;
  620. }
  621. mCurIdx--;
  622. return false;
  623. }
  624. bool DwDemangler::DemangleExprPriamry(StringImpl& outName)
  625. {
  626. auto firstChar = SafeGetChar(mMangledName, mCurIdx++);
  627. if (firstChar == 'L')
  628. {
  629. StringT<256> outType;
  630. Require(DemangleType(outType));
  631. StringT<256> value;
  632. while (true)
  633. {
  634. auto c = SafeGetChar(mMangledName, mCurIdx++);
  635. if (c == 'E')
  636. break;
  637. value += c;
  638. }
  639. if (outType == "bool")
  640. outName = (value == "0") ? "false" : "true";
  641. else
  642. outName = value;
  643. return true;
  644. }
  645. mCurIdx--;
  646. return false;
  647. }
  648. bool DwDemangler::DemangleTemplateArg(StringImpl& outName)
  649. {
  650. if (DemangleType(outName))
  651. return true;
  652. if (DemangleExprPriamry(outName))
  653. return true;
  654. //TODO: Expression, Simple Expressions, Argument Pack
  655. return false;
  656. }
  657. bool DwDemangler::DemangleTemplateArgs(StringImpl& outName)
  658. {
  659. auto firstChar = SafeGetChar(mMangledName, mCurIdx++);
  660. if (firstChar == 'I')
  661. {
  662. bool recordTemplateArgs = mIsFirstName && (mTemplateDepth == 0);
  663. if (recordTemplateArgs)
  664. mTemplateList.Clear();
  665. mTemplateDepth++;
  666. bool inParamPack = false;
  667. bool foundEnd = false;
  668. bool needsComma = false;
  669. outName = "<";
  670. for (int argIdx = 0; true; argIdx++)
  671. {
  672. if (mFailed)
  673. return true;
  674. if (DemangleEnd())
  675. {
  676. if (inParamPack)
  677. {
  678. inParamPack = false;
  679. continue;
  680. }
  681. else
  682. break;
  683. }
  684. StringT<256> templateArg;
  685. auto firstChar = SafeGetChar(mMangledName, mCurIdx);
  686. if (firstChar == 'J')
  687. {
  688. mCurIdx++;
  689. inParamPack = true;
  690. continue;
  691. }
  692. Require(DemangleTemplateArg(templateArg));
  693. if (recordTemplateArgs)
  694. mTemplateList.push_back(templateArg);
  695. if (needsComma)
  696. outName += ", ";
  697. outName += templateArg;
  698. needsComma = true;
  699. }
  700. outName += ">";
  701. mTemplateDepth--;
  702. return true;
  703. }
  704. mCurIdx--;
  705. return false;
  706. }
  707. bool DwDemangler::DemangleSubstitution(StringImpl& outName)
  708. {
  709. auto firstChar = SafeGetChar(mMangledName, mCurIdx++);
  710. if (firstChar == 'S')
  711. {
  712. int idx = 0;
  713. bool hadChars = 0;
  714. while (true)
  715. {
  716. char idxChar = SafeGetChar(mMangledName, mCurIdx++);
  717. if (idxChar == 't')
  718. {
  719. DemangleUnqualifiedName(outName);
  720. outName = "std." + outName;
  721. mSubstituteList.push_back(outName);
  722. mOmitSubstituteAdd = true;
  723. return true;
  724. }
  725. mOmitSubstituteAdd = true;
  726. if (idxChar == 'a')
  727. {
  728. RETURN_STR("std.allocator");
  729. }
  730. if (idxChar == 'b')
  731. {
  732. RETURN_STR("std.basic_string");
  733. }
  734. if (idxChar == 's')
  735. {
  736. RETURN_STR("std.string");
  737. }
  738. if (idxChar == 'i')
  739. {
  740. RETURN_STR("std.basic_istream<char, std.char_traits<char>>");
  741. }
  742. if (idxChar == 'o')
  743. {
  744. RETURN_STR("std.basic_ostream<char, std.char_traits<char>>");
  745. }
  746. if (idxChar == 'd')
  747. {
  748. RETURN_STR("std.basic_iostream<char, std.char_traits<char>>");
  749. }
  750. if (idxChar == '?')
  751. break;
  752. if (idxChar == '_')
  753. break;
  754. hadChars = true;
  755. if ((idxChar >= '0') && (idxChar <= '9'))
  756. idx = (idxChar - '0') + (idx * 36);
  757. else if ((idxChar >= 'A') && (idxChar <= 'Z'))
  758. idx = ((idxChar - 'A') + 10) + (idx * 36);
  759. }
  760. if (hadChars)
  761. idx++;
  762. if ((idx >= 0) && (idx < (int) mSubstituteList.size()))
  763. {
  764. outName = mSubstituteList[idx];
  765. return true;
  766. }
  767. outName = "?";
  768. Failed();
  769. return true;
  770. }
  771. mCurIdx--;
  772. return false;
  773. }
  774. bool DwDemangler::DemangleTemplateParam(StringImpl& outName)
  775. {
  776. auto firstChar = SafeGetChar(mMangledName, mCurIdx++);
  777. if (firstChar == 'T')
  778. {
  779. int idx = 0;
  780. bool hadChars = 0;
  781. while (true)
  782. {
  783. char idxChar = SafeGetChar(mMangledName, mCurIdx++);
  784. if (idxChar == '?')
  785. break;
  786. if (idxChar == '_')
  787. break;
  788. hadChars = true;
  789. if ((idxChar >= '0') && (idxChar <= '9'))
  790. idx = (idxChar - '0') + (idx * 36);
  791. else if ((idxChar >= 'A') && (idxChar <= 'Z'))
  792. idx = ((idxChar - 'A') + 10) + (idx * 36);
  793. }
  794. if (hadChars)
  795. idx++;
  796. if ((idx >= 0) && (idx < (int)mTemplateList.size()))
  797. {
  798. outName = mTemplateList[idx];
  799. mSubstituteList.push_back(outName);
  800. return true;
  801. }
  802. outName = "?";
  803. Failed();
  804. return true;
  805. }
  806. mCurIdx--;
  807. return false;
  808. }
  809. bool DwDemangler::DemangleUnscopedName(StringImpl& outName)
  810. {
  811. if (DemangleUnqualifiedName(outName))
  812. return true;
  813. if (DemangleSubstitution(outName))
  814. return true;
  815. return false;
  816. }
  817. bool DwDemangler::DemangleName(StringImpl& outName, bool* outHasTemplateArgs)
  818. {
  819. if (outHasTemplateArgs != NULL)
  820. *outHasTemplateArgs = false;
  821. auto firstChar = SafeGetChar(mMangledName, mCurIdx++);
  822. switch (firstChar)
  823. {
  824. case 'N': // NestedName
  825. {
  826. StringT<64> cvQualifier;
  827. if (DemangleCVQualifiers(cvQualifier))
  828. outName += cvQualifier + " ";
  829. StringT<64> refQualifier;
  830. if (DemangleRefQualifier(refQualifier))
  831. outName += refQualifier + " ";
  832. int nameCount = 0;
  833. while ((!DemangleEnd()) && (!mFailed))
  834. {
  835. StringT<128> unqualifiedName;
  836. mOmitSubstituteAdd = false;
  837. if ((DemangleUnscopedName(unqualifiedName)) ||
  838. (DemangleInternalName(unqualifiedName)))
  839. {
  840. if (outHasTemplateArgs != NULL)
  841. *outHasTemplateArgs = false;
  842. if (nameCount > 0)
  843. {
  844. if (mLanguage == DbgLanguage_Beef)
  845. outName += ".";
  846. else
  847. outName += "::";
  848. }
  849. outName += unqualifiedName;
  850. if (!mOmitSubstituteAdd)
  851. mSubstituteList.push_back(outName);
  852. else
  853. mOmitSubstituteAdd = false;
  854. nameCount++;
  855. continue;
  856. }
  857. StringT<128> templateArgs;
  858. if (DemangleTemplateArgs(templateArgs))
  859. {
  860. if (outHasTemplateArgs != NULL)
  861. *outHasTemplateArgs = true;
  862. int arrayDims = 0;
  863. if (!mRawDemangle)
  864. {
  865. if (outName == "__TUPLE")
  866. {
  867. outName = "(" + templateArgs.Substring(1, templateArgs.length() - 2) + ")";
  868. mSubstituteList.push_back(outName);
  869. continue;
  870. }
  871. else if (outName == "Box")
  872. {
  873. outName = templateArgs.Substring(1, templateArgs.length() - 2) + "^";
  874. mSubstituteList.push_back(outName);
  875. continue;
  876. }
  877. if (outName == "System.Array1")
  878. arrayDims = 1;
  879. else if (outName == "System.Array2")
  880. arrayDims = 2;
  881. else if (outName == "System.Array3")
  882. arrayDims = 3;
  883. }
  884. if (arrayDims > 0)
  885. {
  886. outName = templateArgs.Substring(1, templateArgs.length() - 2) + "[";
  887. for (int i = 0; i < arrayDims - 1; i++)
  888. outName += ",";
  889. outName += "]";
  890. }
  891. else
  892. {
  893. outName += templateArgs;
  894. mSubstituteList.push_back(outName);
  895. }
  896. continue;
  897. }
  898. Failed();
  899. break;
  900. }
  901. return true;
  902. }
  903. break;
  904. }
  905. mCurIdx--;
  906. if (DemangleUnscopedName(outName))
  907. {
  908. if (!mOmitSubstituteAdd)
  909. mSubstituteList.push_back(outName);
  910. else
  911. mOmitSubstituteAdd = false;
  912. StringT<128> templateArgs;
  913. if (DemangleTemplateArgs(templateArgs))
  914. {
  915. if (outHasTemplateArgs != NULL)
  916. *outHasTemplateArgs = true;
  917. outName += templateArgs;
  918. }
  919. if ((outName.length() > 0) && (outName[outName.length() - 1] == '.'))
  920. {
  921. // an incomplete 'std.'
  922. StringT<128> unqualifiedName;
  923. if ((DemangleUnscopedName(unqualifiedName)) ||
  924. (DemangleInternalName(unqualifiedName)))
  925. {
  926. outName += unqualifiedName;
  927. }
  928. else
  929. {
  930. Failed();
  931. }
  932. }
  933. return true;
  934. }
  935. if (DemangleLocalName(outName))
  936. return true;
  937. return false;
  938. }
  939. String DwDemangler::Demangle(const StringImpl& mangledName)
  940. {
  941. BF_ASSERT(mCurIdx == 0);
  942. /*String overrideVal = "_ZZL9DumpStatsP16TCMalloc_PrinteriE3MiB";
  943. //String overrideVal = "_ZN3Hey4Dude3Bro9TestClass7MethodBEivf";
  944. //"_ZN3Hey4Dude3Bro9TestClass14DlgTestGenericIiE12TestThinggieEi";
  945. //"_ZStL19piecewise_construct";
  946. //"_ZNSbIwSt11char_traitsIwESaIwEED1Ev";
  947. //"_ZN12_GLOBAL__N_124do_realloc_with_callbackEPvjPFvS0_EPFjPKvE";
  948. //"_ZNK17TCMalloc_PageMap2ILi19EE3getEj";
  949. //"_ZN5BeefyL13FromBigEndianEs";
  950. //"_ZNSt6vectorIZN4BFGC19WriteDebugDumpStateEvE9DebugInfoSaIS1_EED2Ev";
  951. //"_ZNSt6vectorISsSaISsEE19_M_emplace_back_auxIJRKSsEEEvDpOT_";
  952. //"_ZSt4moveIRiEONSt16remove_referenceIT_E4typeEOS2_";
  953. //"_ZL10CStartProcPN6System9Threading6ThreadE";
  954. //"_ZNSt8_Rb_treeIPN6System9Threading6ThreadESt4pairIKS3_PS3_ESt10_Select1stIS7_ESt4lessIS3_ESaIS7_EE13_Rb_tree_implISB_Lb1EED2Ev";
  955. //Clang failure: (?) "__ZNSt16allocator_traitsISaISsEE9constructISsJRKSsEEEDTcl12_S_constructfp_fp0_spclsr3stdE7forwardIT0_Efp1_EEERS0_PT_DpOS5_";
  956. //"__ZNSt4pairIifEC2IKifvEERKS_IT_T0_E";
  957. //"__ZNSsaSEPKc";
  958. //"__ZN6System6String6ConcatEU6paramsPNS_6Array1INS_6ObjectEEE";
  959. //_ZNSt3mapI3HeyfSt4lessIiESaISt4pairIKifEEEixES_S0_S1_S2_S3_S4_S5_S6_
  960. String overrideDemangled;
  961. if (mangledName != overrideVal)
  962. {
  963. BfDemangler demangler;
  964. overrideDemangled = demangler.Demangle(overrideVal);
  965. }*/
  966. mMangledName = mangledName;
  967. String outStr;
  968. if (mangledName.length() < 3)
  969. return mangledName;
  970. if (strncmp(mangledName.c_str(), "_Z", 2) == 0)
  971. mCurIdx = 2;
  972. else if (strncmp(mangledName.c_str(), "__Z", 3) == 0)
  973. mCurIdx = 3;
  974. else
  975. {
  976. int dotIdx = (int)mangledName.IndexOf('.');
  977. if (dotIdx > 1)
  978. return mangledName.Substring(0, dotIdx) + ":" + Demangle(mangledName.Substring(dotIdx + 1));
  979. return mangledName;
  980. }
  981. /*int ePos = (int) mMangledName.rfind('E');
  982. if (ePos > 0)
  983. mMangledName = mMangledName.substr(0, mMangledName.length() - 1);*/
  984. int endPos = (int)mMangledName.length() - 1;
  985. while (endPos > 0)
  986. {
  987. char c = mMangledName[endPos];
  988. if (c == '@')
  989. {
  990. mMangledName = mMangledName.Substring(0, endPos);
  991. break;
  992. }
  993. bool isNum = (c >= '0') && (c <= '9');
  994. if (!isNum)
  995. break;
  996. endPos--;
  997. }
  998. bool mayHaveParams = false;
  999. char typeChar = SafeGetChar(mangledName, mCurIdx);
  1000. if (typeChar == 'T')
  1001. {
  1002. mCurIdx++;
  1003. char typeChar2 = SafeGetChar(mangledName, mCurIdx++);
  1004. if (typeChar2 == 'S')
  1005. {
  1006. // typeinfo
  1007. }
  1008. else if (typeChar2 == 'V')
  1009. {
  1010. // vtable
  1011. }
  1012. else
  1013. {
  1014. return mangledName;
  1015. }
  1016. }
  1017. else if (typeChar == 'S')
  1018. {
  1019. mayHaveParams = false;
  1020. }
  1021. else if (typeChar == 'L')
  1022. {
  1023. mayHaveParams = true;
  1024. mCurIdx++;
  1025. }
  1026. else if (typeChar == 'Z') // Static function-scoped field
  1027. mayHaveParams = false;
  1028. else
  1029. mayHaveParams = true;
  1030. bool wantsReturnValue = false;
  1031. StringT<256> outName;
  1032. if (mayHaveParams)
  1033. Require(DemangleFunction(outName));
  1034. else
  1035. Require(DemangleName(outName));
  1036. if (mFailed)
  1037. return mangledName;
  1038. //OutputDebugStrF("%s\n", outName.c_str());
  1039. return outName;
  1040. }
  1041. //////////////////////////////////////////////////////////////////////////
  1042. MsDemangler::MsDemangler()
  1043. {
  1044. mCurIdx = 0;
  1045. }
  1046. bool MsDemangler::DemangleString(StringImpl& outName)
  1047. {
  1048. while (true)
  1049. {
  1050. char c = SafeGetChar(mMangledName, mCurIdx++);
  1051. if ((c == '!') || (c == '?'))
  1052. return Failed();
  1053. if (c == '@')
  1054. break;
  1055. outName.Append(c);
  1056. }
  1057. //mSubstituteList.push_back(outName);
  1058. return true;
  1059. }
  1060. bool MsDemangler::DemangleTemplateName(StringImpl& outName, String* primaryName)
  1061. {
  1062. DemangleString(outName);
  1063. if (primaryName != NULL)
  1064. *primaryName = outName;
  1065. mSubstituteList.push_back(outName);
  1066. outName += "<";
  1067. for (int paramIdx = 0; true; paramIdx++)
  1068. {
  1069. String paramType;
  1070. if (!DemangleType(paramType))
  1071. break;
  1072. if (paramIdx > 0)
  1073. outName += ", ";
  1074. outName += paramType;
  1075. }
  1076. outName += ">";
  1077. return true;
  1078. }
  1079. bool MsDemangler::DemangleScopedName(StringImpl& outName, String* primaryName)
  1080. {
  1081. for (int nameIdx = 0; true; nameIdx++)
  1082. {
  1083. if (mFailed)
  1084. return false;
  1085. char c = SafeGetChar(mMangledName, mCurIdx++);
  1086. if (c == '@')
  1087. return true;
  1088. /*{
  1089. if (curScope.length() == 0)
  1090. return true;
  1091. if (nameIdx == 0)
  1092. {
  1093. if (primaryName != NULL)
  1094. *primaryName = curScope;
  1095. }
  1096. else
  1097. outName = "::" + outName;
  1098. outName = curScope + outName;
  1099. curScope.clear();
  1100. mSubstituteList.push_back(outName);
  1101. nameIdx++;
  1102. continue;
  1103. }*/
  1104. String namePart;
  1105. if (c == '?')
  1106. {
  1107. c = SafeGetChar(mMangledName, mCurIdx++);
  1108. if (c == '$')
  1109. {
  1110. SubstituteList oldSubList = mSubstituteList;
  1111. mSubstituteList.Clear();
  1112. DemangleTemplateName(namePart, /*primaryName*/NULL);
  1113. mSubstituteList = oldSubList;
  1114. }
  1115. else if (c == '?')
  1116. {
  1117. return Failed();
  1118. }
  1119. else
  1120. {
  1121. mCurIdx--;
  1122. int num = DemangleNumber();
  1123. outName = StrFormat("%d", num);
  1124. }
  1125. }
  1126. else if ((c >= '0') && (c <= '9'))
  1127. {
  1128. int subIdx = c - '0';
  1129. if (subIdx < mSubstituteList.size())
  1130. {
  1131. namePart = mSubstituteList[subIdx];
  1132. }
  1133. else
  1134. {
  1135. return Failed();
  1136. }
  1137. }
  1138. else
  1139. {
  1140. mCurIdx--;
  1141. Require(DemangleString(namePart));
  1142. }
  1143. if (nameIdx == 0)
  1144. {
  1145. //We moved this down so we get the template args for the ctor name
  1146. /*if ((primaryName != NULL) && (primaryName->empty()))
  1147. *primaryName = namePart;*/
  1148. outName = namePart;
  1149. if ((primaryName != NULL) && (primaryName->empty()))
  1150. *primaryName = namePart;
  1151. }
  1152. else if (mLanguage == DbgLanguage_Beef)
  1153. {
  1154. if ((mBeefFixed) && (namePart == "bf"))
  1155. namePart.Clear();
  1156. if (!namePart.IsEmpty())
  1157. outName = namePart + "." + outName;
  1158. }
  1159. else
  1160. {
  1161. outName = namePart + "::" + outName;
  1162. }
  1163. mSubstituteList.push_back(namePart);
  1164. }
  1165. }
  1166. bool MsDemangler::DemangleModifiedType(StringImpl& outName, bool isPtr)
  1167. {
  1168. String modifier;
  1169. DemangleCV(modifier);
  1170. char c = SafeGetChar(mMangledName, mCurIdx);
  1171. if (c == 'Y') // Sized array
  1172. {
  1173. String dimStr;
  1174. mCurIdx++;
  1175. int dimCount = DemangleNumber();
  1176. for (int dim = 0; dim < dimCount; dim++)
  1177. {
  1178. int dimSize = DemangleNumber();
  1179. dimStr += StrFormat("[%d]", dimSize);
  1180. }
  1181. DemangleType(outName);
  1182. outName += dimStr;
  1183. }
  1184. else
  1185. {
  1186. DemangleType(outName);
  1187. if (isPtr)
  1188. outName += "*";
  1189. }
  1190. if (!modifier.empty())
  1191. outName = modifier + " " + outName;
  1192. return true;
  1193. }
  1194. bool MsDemangler::DemangleType(StringImpl& outName)
  1195. {
  1196. char c = SafeGetChar(mMangledName, mCurIdx++);
  1197. if ((c == 0) || (c == '@'))
  1198. return false;
  1199. switch (c)
  1200. {
  1201. case '0':
  1202. case '1':
  1203. case '2':
  1204. case '3':
  1205. case '4':
  1206. case '5':
  1207. case '6':
  1208. case '7':
  1209. case '8':
  1210. case '9':
  1211. {
  1212. if (mFailed)
  1213. return false;
  1214. int subIdx = c - '0';
  1215. if ((subIdx < 0) || (subIdx >= (int)mSubstituteList.size()))
  1216. return Failed();
  1217. outName = mSubstituteList[subIdx];
  1218. return true;
  1219. }
  1220. break;
  1221. case '$':
  1222. {
  1223. char c = SafeGetChar(mMangledName, mCurIdx++);
  1224. switch (c)
  1225. {
  1226. case '0':
  1227. {
  1228. int64 val = 0;
  1229. bool doNeg = false;
  1230. auto nextChar = SafeGetChar(mMangledName, mCurIdx++);
  1231. if (nextChar == '?')
  1232. {
  1233. doNeg = true;
  1234. nextChar = SafeGetChar(mMangledName, mCurIdx++);
  1235. }
  1236. if ((nextChar >= '0') && (nextChar <= '9'))
  1237. {
  1238. val = (nextChar - '0') + 1;
  1239. }
  1240. else
  1241. {
  1242. while (true)
  1243. {
  1244. if (nextChar == 0)
  1245. return Failed();
  1246. if (nextChar == '@')
  1247. break;
  1248. val = (val * 0x10) + (nextChar - 'A');
  1249. nextChar = SafeGetChar(mMangledName, mCurIdx++);
  1250. }
  1251. }
  1252. if (doNeg)
  1253. val = -val;
  1254. if (mLanguage == DbgLanguage_Beef)
  1255. outName += StrFormat("const %d", val);
  1256. else
  1257. outName += StrFormat("%d", val);
  1258. return true;
  1259. }
  1260. break;
  1261. case 'D':
  1262. {
  1263. int templateParamNum = DemangleNumber();
  1264. return Failed();
  1265. }
  1266. break;
  1267. case 'F':
  1268. {
  1269. int param1 = DemangleNumber();
  1270. int param2 = DemangleNumber();
  1271. return Failed();
  1272. }
  1273. break;
  1274. case 'G':
  1275. {
  1276. int param1 = DemangleNumber();
  1277. int param2 = DemangleNumber();
  1278. int param3 = DemangleNumber();
  1279. return Failed();
  1280. }
  1281. break;
  1282. case 'Q':
  1283. {
  1284. int nonTypeTemplateParam = DemangleNumber();
  1285. return Failed();
  1286. }
  1287. break;
  1288. case '$':
  1289. {
  1290. char c = SafeGetChar(mMangledName, mCurIdx++);
  1291. if (c == 'C')
  1292. {
  1293. String modifier;
  1294. DemangleCV(modifier);
  1295. DemangleType(outName);
  1296. outName = modifier + " " + outName;
  1297. return true;
  1298. }
  1299. else if (c == 'Q')
  1300. {
  1301. String modifier;
  1302. DemangleCV(modifier);
  1303. DemangleType(outName);
  1304. outName = modifier + " " + outName;
  1305. return true;
  1306. }
  1307. }
  1308. break;
  1309. }
  1310. }
  1311. break;
  1312. case '_':
  1313. {
  1314. c = SafeGetChar(mMangledName, mCurIdx++);
  1315. switch (c)
  1316. {
  1317. case 'D':
  1318. outName = "int8";
  1319. return true;
  1320. case 'E':
  1321. outName = "uint8";
  1322. return true;
  1323. case 'F':
  1324. outName = "int16";
  1325. return true;
  1326. case 'G':
  1327. outName = "uint16";
  1328. return true;
  1329. case 'H':
  1330. outName = "int32";
  1331. return true;
  1332. case 'I':
  1333. outName = "uint32";
  1334. return true;
  1335. case 'J':
  1336. outName = "int64";
  1337. return true;
  1338. case 'K':
  1339. outName = "uint64";
  1340. return true;
  1341. case 'L':
  1342. outName = "int128";
  1343. return true;
  1344. case 'M':
  1345. outName = "float";
  1346. return true;
  1347. case 'W':
  1348. outName = "wchar_t";
  1349. return true;
  1350. case 'N':
  1351. outName = "bool";
  1352. return true;
  1353. default:
  1354. return Failed();
  1355. break;
  1356. }
  1357. }
  1358. break;
  1359. case 'A':
  1360. {
  1361. DemangleModifiedType(outName, false);
  1362. outName += "&";
  1363. }
  1364. return true;
  1365. case 'B':
  1366. DemangleModifiedType(outName, false);
  1367. outName = "volatile " + outName + "&";
  1368. return true;
  1369. case 'P':
  1370. DemangleModifiedType(outName, true);
  1371. return true;
  1372. case 'Q':
  1373. DemangleModifiedType(outName, true);
  1374. outName = "const " + outName;
  1375. return true;
  1376. case 'R':
  1377. DemangleModifiedType(outName, true);
  1378. outName = "volatile " + outName;
  1379. return true;
  1380. case 'S':
  1381. DemangleModifiedType(outName, true);
  1382. outName = "const volatile" + outName;
  1383. return true;
  1384. case 'T':
  1385. // union
  1386. DemangleScopedName(outName);
  1387. return true;
  1388. case 'U':
  1389. // struct
  1390. DemangleScopedName(outName);
  1391. return true;
  1392. case 'V':
  1393. // class
  1394. DemangleScopedName(outName);
  1395. return true;
  1396. case 'W':
  1397. // enum
  1398. c = SafeGetChar(mMangledName, mCurIdx++);
  1399. Require((c >= '0') && (c <= '8'));
  1400. DemangleScopedName(outName);
  1401. return true;
  1402. case 'C':
  1403. outName = "char";
  1404. return true;
  1405. case 'D':
  1406. if (mLanguage == DbgLanguage_Beef)
  1407. outName = "char8";
  1408. else
  1409. outName = "char";
  1410. return true;
  1411. case 'E':
  1412. if (mLanguage == DbgLanguage_Beef)
  1413. outName = "uint8";
  1414. else
  1415. outName = "uchar";
  1416. return true;
  1417. case 'F':
  1418. if (mLanguage == DbgLanguage_Beef)
  1419. outName = "int16";
  1420. else
  1421. outName = "short";
  1422. return true;
  1423. case 'G':
  1424. if (mLanguage == DbgLanguage_Beef)
  1425. outName = "uint16";
  1426. else
  1427. outName = "ushort";
  1428. return true;
  1429. case 'H':
  1430. if (mLanguage == DbgLanguage_Beef)
  1431. outName = "int32";
  1432. else
  1433. outName = "int";
  1434. return true;
  1435. case 'I':
  1436. if (mLanguage == DbgLanguage_Beef)
  1437. outName = "uint32";
  1438. else
  1439. outName = "uint";
  1440. return true;
  1441. case 'J':
  1442. outName = "long";
  1443. return true;
  1444. case 'K':
  1445. outName = "ulong";
  1446. return true;
  1447. case 'M':
  1448. outName = "float";
  1449. return true;
  1450. case 'N':
  1451. outName = "double";
  1452. return true;
  1453. case 'O':
  1454. outName = "long double";
  1455. return true;
  1456. case 'X':
  1457. outName += "void";
  1458. return true;
  1459. case '?':
  1460. if (mInArgs)
  1461. {
  1462. int num = DemangleNumber();
  1463. //
  1464. }
  1465. else
  1466. {
  1467. DemangleModifiedType(outName, false);
  1468. }
  1469. break;
  1470. default:
  1471. return Failed();
  1472. break;
  1473. }
  1474. return false;
  1475. }
  1476. int MsDemangler::DemangleNumber()
  1477. {
  1478. char c = SafeGetChar(mMangledName, mCurIdx++);
  1479. bool isSigned = false;
  1480. if (c == '?')
  1481. {
  1482. isSigned = true;
  1483. c = SafeGetChar(mMangledName, mCurIdx++);
  1484. }
  1485. if ((c >= '0') && (c <= '9'))
  1486. {
  1487. return c - '0' + 1;
  1488. }
  1489. int val = 0;
  1490. while ((c >= 'A') && (c <= 'P'))
  1491. {
  1492. val = (val * 0x10) + (c - 'A');
  1493. c = SafeGetChar(mMangledName, mCurIdx++);
  1494. }
  1495. if (c != '@')
  1496. Failed();
  1497. return val;
  1498. }
  1499. bool MsDemangler::DemangleCV(StringImpl& outName)
  1500. {
  1501. String modifier;
  1502. while (true)
  1503. {
  1504. char c = SafeGetChar(mMangledName, mCurIdx++);
  1505. if (c == 'E')
  1506. {
  1507. // __ptr64
  1508. }
  1509. else if (c == 'F')
  1510. {
  1511. // Unaligned
  1512. //BF_ASSERT("Unhandled");
  1513. }
  1514. else if (c == 'I')
  1515. {
  1516. // __restrict
  1517. }
  1518. else
  1519. break;
  1520. }
  1521. mCurIdx--;
  1522. //int modifier = DemangleConst();
  1523. char c = SafeGetChar(mMangledName, mCurIdx++);
  1524. int constVal = 0;
  1525. //BF_ASSERT((c >= 'A') && (c <= 'X'));
  1526. if ((c < 'A') || (c > 'X'))
  1527. {
  1528. return Failed();
  1529. }
  1530. constVal = c - 'A';
  1531. if ((constVal & 3) == 3)
  1532. outName = "const volatile";
  1533. else if ((constVal & 1) != 0)
  1534. outName = "const";
  1535. else if ((constVal & 2) != 0)
  1536. outName = "const";
  1537. /*switch (c)
  1538. {
  1539. case 'A':
  1540. case 'M':
  1541. case 'Q':
  1542. case 'U':
  1543. case 'Y':
  1544. case '2':
  1545. // None
  1546. break;
  1547. case 'B':
  1548. case 'J':
  1549. case 'R':
  1550. case 'V':
  1551. case 'Z':
  1552. case '3':
  1553. modifier = "const";
  1554. break;
  1555. case 'C':
  1556. case 'G':
  1557. case 'K':
  1558. case 'S':
  1559. case 'W':
  1560. case '0':
  1561. modifier = "volatile";
  1562. break;
  1563. case 'D':
  1564. case 'H':
  1565. case 'L':
  1566. modifier = "const volatile";
  1567. break;
  1568. default:
  1569. BF_ASSERT("Unhandled");
  1570. }*/
  1571. return true;
  1572. }
  1573. bool MsDemangler::DemangleName(StringImpl& outName)
  1574. {
  1575. bool appendRetType = false;
  1576. bool hasTemplateArgs = false;
  1577. char c = SafeGetChar(mMangledName, mCurIdx++);
  1578. if (c == '?')
  1579. {
  1580. c = SafeGetChar(mMangledName, mCurIdx++);
  1581. if (c == '$')
  1582. {
  1583. mCurIdx++;
  1584. c = SafeGetChar(mMangledName, mCurIdx++);
  1585. hasTemplateArgs = true;
  1586. }
  1587. String primaryName;
  1588. const char* funcName = NULL;
  1589. switch (c)
  1590. {
  1591. case '0':
  1592. // Ctor
  1593. Require(DemangleScopedName(outName, &primaryName));
  1594. if (mLanguage == DbgLanguage_Beef)
  1595. outName += ".this";
  1596. else
  1597. outName += "::" + primaryName;
  1598. break;
  1599. case '1':
  1600. // Dtor
  1601. Require(DemangleScopedName(outName, &primaryName));
  1602. if (mLanguage == DbgLanguage_Beef)
  1603. outName += ".~this";
  1604. else
  1605. outName += "::~" + primaryName;
  1606. break;
  1607. case '2': funcName = "operator new"; break;
  1608. case '3': funcName = "operator delete"; break;
  1609. case '4': funcName = "operator="; break;
  1610. case '5': funcName = "operator>>"; break;
  1611. case '6': funcName = "operator<<"; break;
  1612. case '7': funcName = "operator!"; break;
  1613. case '8': funcName = "operator=="; break;
  1614. case '9': funcName = "operator!="; break;
  1615. case 'A': funcName = "operator[]"; break;
  1616. case 'B':
  1617. funcName = "operator ";
  1618. appendRetType = true;
  1619. break;
  1620. case 'C': funcName = "operator->"; break;
  1621. case 'D': funcName = "operator*"; break;
  1622. case 'E': funcName = "operator++"; break;
  1623. case 'F': funcName = "operator--"; break;
  1624. case 'G': funcName = "operator-"; break;
  1625. case 'H': funcName = "operator+"; break;
  1626. case 'I': funcName = "operator&"; break;
  1627. case 'J': funcName = "operator->*"; break;
  1628. case 'K': funcName = "operator/"; break;
  1629. case 'L': funcName = "operator%"; break;
  1630. case 'M': funcName = "operator<"; break;
  1631. case 'N': funcName = "operator<="; break;
  1632. case 'O': funcName = "operator>"; break;
  1633. case 'P': funcName = "operator>="; break;
  1634. case 'Q': funcName = "operator,"; break;
  1635. case 'R': funcName = "operator()"; break;
  1636. case 'S': funcName = "operator~"; break;
  1637. case 'T': funcName = "operator^"; break;
  1638. case 'U': funcName = "operator|"; break;
  1639. case 'V': funcName = "operator&&"; break;
  1640. case 'W': funcName = "operator||"; break;
  1641. case 'X': funcName = "operator*="; break;
  1642. case 'Y': funcName = "operator+="; break;
  1643. case 'Z': funcName = "operator-="; break;
  1644. case '_':
  1645. {
  1646. c = SafeGetChar(mMangledName, mCurIdx++);
  1647. switch (c)
  1648. {
  1649. case '0': funcName = "operator/="; break;
  1650. case '1': funcName = "operator%="; break;
  1651. case '2': funcName = "operator>>="; break;
  1652. case '3': funcName = "operator<<="; break;
  1653. case '4': funcName = "operator&="; break;
  1654. case '5': funcName = "operator|="; break;
  1655. case '6': funcName = "operator^="; break;
  1656. case '7': funcName = "`vftable'"; break;
  1657. case '8': funcName = "`vbtable'"; break;
  1658. case '9': funcName = "`vcall'"; break;
  1659. case 'A': funcName = "`typeof'"; break;
  1660. case 'B': funcName = "`local static guard'"; break;
  1661. //case 'C': funcName = "`string'"; do_after = 4; break;
  1662. case 'D': funcName = "`vbase destructor'"; break;
  1663. case 'E': funcName = "`vector deleting destructor'"; break;
  1664. case 'F': funcName = "`default constructor closure'"; break;
  1665. case 'G': funcName = "`scalar deleting destructor'"; break;
  1666. case 'H': funcName = "`vector constructor iterator'"; break;
  1667. case 'I': funcName = "`vector destructor iterator'"; break;
  1668. case 'J': funcName = "`vector vbase constructor iterator'"; break;
  1669. case 'K': funcName = "`virtual displacement map'"; break;
  1670. case 'L': funcName = "`eh vector constructor iterator'"; break;
  1671. case 'M': funcName = "`eh vector destructor iterator'"; break;
  1672. case 'N': funcName = "`eh vector vbase constructor iterator'"; break;
  1673. case 'O': funcName = "`copy constructor closure'"; break;
  1674. case 'R':
  1675. c = SafeGetChar(mMangledName, mCurIdx++);
  1676. switch (c)
  1677. {
  1678. case 0: funcName = "`RTTI Type Descriptor'"; break;
  1679. case 1: funcName = "`RTTI Class Descriptor'"; break;
  1680. case '2': funcName = "`RTTI Base Class Array'"; break;
  1681. case '3': funcName = "`RTTI Class Hierarchy Descriptor'"; break;
  1682. case '4': funcName = "`RTTI Complete Object Locater"; break;
  1683. }
  1684. break;
  1685. case 'S': funcName = "`local vftable'"; break;
  1686. case 'T': funcName = "`local vftable constructor closure'"; break;
  1687. case 'U': funcName = "operator new[]"; break;
  1688. case 'V': funcName = "operator delete[]"; break;
  1689. case 'X': funcName = "`placement delete closure'"; break;
  1690. case 'Y': funcName = "`placement delete[] closure'"; break;
  1691. }
  1692. }
  1693. break;
  1694. default:
  1695. mCurIdx -= 2;
  1696. break;
  1697. }
  1698. if (funcName != NULL)
  1699. {
  1700. if (strcmp(funcName, "__BfCtor") == 0)
  1701. funcName = "this";
  1702. else if (strcmp(funcName, "__BfCtorClear") == 0)
  1703. funcName = "this$clear";
  1704. else if (strcmp(funcName, "__BfStaticCtor") == 0)
  1705. funcName = "this";
  1706. if (hasTemplateArgs)
  1707. {
  1708. outName += funcName;
  1709. outName += "<";
  1710. for (int paramIdx = 0; true; paramIdx++)
  1711. {
  1712. String paramType;
  1713. if (!DemangleType(paramType))
  1714. break;
  1715. if (paramType == "void")
  1716. break;
  1717. if (paramIdx > 0)
  1718. outName += ", ";
  1719. outName += paramType;
  1720. }
  1721. outName += ">";
  1722. mSubstituteList.Clear();
  1723. StringT<128> scopeName;
  1724. Require(DemangleScopedName(scopeName, &primaryName));
  1725. if (!scopeName.empty())
  1726. {
  1727. if (mLanguage == DbgLanguage_Beef)
  1728. {
  1729. scopeName += ".";
  1730. }
  1731. else
  1732. scopeName += "::";
  1733. outName.Insert(0, scopeName);
  1734. }
  1735. /*outName += "(";
  1736. for (int paramIdx = 0; true; paramIdx++)
  1737. {
  1738. String paramType;
  1739. if (!DemangleType(paramType))
  1740. break;
  1741. if (paramType == "void")
  1742. break;
  1743. if (paramIdx > 0)
  1744. outName += ", ";
  1745. outName += paramType;
  1746. }
  1747. outName += ")";*/
  1748. }
  1749. else
  1750. {
  1751. Require(DemangleScopedName(outName, &primaryName));
  1752. if (!primaryName.empty())
  1753. {
  1754. if (mLanguage == DbgLanguage_Beef)
  1755. outName += ".";
  1756. else
  1757. outName += "::";
  1758. }
  1759. outName += funcName;
  1760. }
  1761. }
  1762. else if (outName.empty())
  1763. {
  1764. if (hasTemplateArgs)
  1765. {
  1766. Require(DemangleString(outName));
  1767. primaryName = outName;
  1768. outName += "<";
  1769. for (int paramIdx = 0; true; paramIdx++)
  1770. {
  1771. String paramType;
  1772. if (!DemangleType(paramType))
  1773. break;
  1774. if (paramType == "void")
  1775. break;
  1776. if (paramIdx > 0)
  1777. outName += ", ";
  1778. outName += paramType;
  1779. }
  1780. outName += ">";
  1781. mSubstituteList.Clear();
  1782. String scopeName;
  1783. Require(DemangleScopedName(scopeName, &primaryName));
  1784. if (!scopeName.empty())
  1785. {
  1786. if (mLanguage == DbgLanguage_Beef)
  1787. scopeName += ".";
  1788. else
  1789. scopeName += "::";
  1790. outName.Insert(0, scopeName);
  1791. }
  1792. }
  1793. else
  1794. {
  1795. Require(DemangleScopedName(outName, &primaryName));
  1796. }
  1797. }
  1798. }
  1799. else
  1800. {
  1801. mCurIdx--;
  1802. Require(DemangleScopedName(outName));
  1803. }
  1804. c = SafeGetChar(mMangledName, mCurIdx++);
  1805. if ((c >= '0') && (c <= '9'))
  1806. {
  1807. if ((c == '2') || (c == '3'))
  1808. {
  1809. // Global variable / static member
  1810. String varType;
  1811. Require(DemangleType(varType));
  1812. c = SafeGetChar(mMangledName, mCurIdx++);
  1813. // 0 = private, 1 = protected, 2 = public
  1814. return true;
  1815. }
  1816. return true;
  1817. }
  1818. // Method attribute
  1819. if (c == 0)
  1820. return true;
  1821. struct
  1822. {
  1823. uint8 mUnused1 : 1;
  1824. uint8 mType : 2; // normal, static, virtual, thunk
  1825. uint8 mAccess : 3; // private, protected, public, non-member
  1826. uint8 mUnused2 : 2;
  1827. } methodData;
  1828. *((uint8*)&methodData) = (c - 'A');
  1829. //int funcTypeVal = c - 'A';
  1830. //int accessType = funcTypeVal >> 3;
  1831. //bool isNonMember = c == 'Y';
  1832. //bool isVirtual = (c == 'E') || (c == 'M') || (c == 'U');
  1833. //bool hasThis = isVirtual || (c == 'A') || (c == 'I') || (c == 'Q');
  1834. bool isNonMember = methodData.mAccess == 3;
  1835. bool hasThis = !isNonMember && ((methodData.mType == 0) || (methodData.mType == 2));
  1836. // CV qualifier
  1837. if (hasThis)
  1838. {
  1839. String cvQualifier;
  1840. if (!DemangleCV(cvQualifier))
  1841. return false;
  1842. // Ignore
  1843. }
  1844. // Calling convention
  1845. c = SafeGetChar(mMangledName, mCurIdx++);
  1846. union
  1847. {
  1848. uint8 mDllExport : 1;
  1849. uint8 mCallingConv : 7; // cdecl, pascal, thiscall, stdcall, fastcall
  1850. } callType;
  1851. *((uint8*)&callType) = (c - 'A');
  1852. if (callType.mCallingConv > 6)
  1853. return Failed();
  1854. String retType;
  1855. DemangleType(retType);
  1856. if (appendRetType)
  1857. outName += retType;
  1858. // This was needed for System.ValueType.Equals<_M0>(_M0, ValueType)
  1859. // Do we need to clear ALWAYS before param list though?
  1860. if (hasTemplateArgs)
  1861. mSubstituteList.Clear();
  1862. mInArgs = true;
  1863. outName += "(";
  1864. for (int paramIdx = 0; true; paramIdx++)
  1865. {
  1866. String paramType;
  1867. if (!DemangleType(paramType))
  1868. break;
  1869. if (paramType == "void")
  1870. break;
  1871. if (paramIdx > 0)
  1872. outName += ", ";
  1873. outName += paramType;
  1874. }
  1875. outName += ")";
  1876. return true;
  1877. }
  1878. String MsDemangler::Demangle(const StringImpl& mangledName)
  1879. {
  1880. StringT<256> outName;
  1881. mMangledName = mangledName;
  1882. char c = mangledName[mCurIdx++];
  1883. BF_ASSERT(c == '?');
  1884. DemangleName(outName);
  1885. if (mFailed)
  1886. return mangledName;
  1887. //return outName;
  1888. //return outName + " : " + mangledName;
  1889. return outName;
  1890. }
  1891. //////////////////////////////////////////////////////////////////////////
  1892. MsDemangleScanner::MsDemangleScanner()
  1893. {
  1894. mCurIdx = 0;
  1895. mIsData = false;
  1896. }
  1897. bool MsDemangleScanner::DemangleString()
  1898. {
  1899. while (true)
  1900. {
  1901. char c = SafeGetChar(mMangledName, mCurIdx++);
  1902. if ((c == '!') || (c == '?'))
  1903. return Failed();
  1904. if (c == '@')
  1905. break;
  1906. }
  1907. //mSubstituteList.push_back(outName);
  1908. return true;
  1909. }
  1910. bool MsDemangleScanner::DemangleTemplateName()
  1911. {
  1912. DemangleString();
  1913. for (int paramIdx = 0; true; paramIdx++)
  1914. {
  1915. if (!DemangleType())
  1916. break;
  1917. }
  1918. return true;
  1919. }
  1920. bool MsDemangleScanner::DemangleScopedName()
  1921. {
  1922. for (int nameIdx = 0; true; nameIdx++)
  1923. {
  1924. if (mFailed)
  1925. return false;
  1926. char c = SafeGetChar(mMangledName, mCurIdx++);
  1927. if (c == '@')
  1928. return true;
  1929. if (c == '?')
  1930. {
  1931. c = SafeGetChar(mMangledName, mCurIdx++);
  1932. if (c == '$')
  1933. {
  1934. DemangleTemplateName();
  1935. }
  1936. else if (c == '?')
  1937. {
  1938. return Failed();
  1939. }
  1940. else
  1941. {
  1942. mCurIdx--;
  1943. int num = DemangleNumber();
  1944. }
  1945. }
  1946. else if ((c >= '0') && (c <= '9'))
  1947. {
  1948. int subIdx = c - '0';
  1949. if (subIdx < mSubstituteList.size())
  1950. {
  1951. //
  1952. }
  1953. else
  1954. {
  1955. // Ignore error
  1956. }
  1957. }
  1958. else
  1959. {
  1960. mCurIdx--;
  1961. Require(DemangleString());
  1962. }
  1963. }
  1964. }
  1965. bool MsDemangleScanner::DemangleModifiedType(bool isPtr)
  1966. {
  1967. DemangleCV();
  1968. char c = SafeGetChar(mMangledName, mCurIdx);
  1969. if (c == 'Y') // Sized array
  1970. {
  1971. mCurIdx++;
  1972. int dimCount = DemangleNumber();
  1973. for (int dim = 0; dim < dimCount; dim++)
  1974. {
  1975. int dimSize = DemangleNumber();
  1976. }
  1977. DemangleType();
  1978. }
  1979. else
  1980. {
  1981. DemangleType();
  1982. }
  1983. return true;
  1984. }
  1985. bool MsDemangleScanner::DemangleType()
  1986. {
  1987. char c = SafeGetChar(mMangledName, mCurIdx++);
  1988. if ((c == 0) || (c == '@'))
  1989. return false;
  1990. switch (c)
  1991. {
  1992. case '0':
  1993. case '1':
  1994. case '2':
  1995. case '3':
  1996. case '4':
  1997. case '5':
  1998. case '6':
  1999. case '7':
  2000. case '8':
  2001. case '9':
  2002. {
  2003. if (mFailed)
  2004. return false;
  2005. int subIdx = c - '0';
  2006. if ((subIdx < 0) || (subIdx >= (int)mSubstituteList.size()))
  2007. return Failed();
  2008. return true;
  2009. }
  2010. break;
  2011. case '$':
  2012. {
  2013. char c = SafeGetChar(mMangledName, mCurIdx++);
  2014. switch (c)
  2015. {
  2016. case '0':
  2017. return Failed();
  2018. break;
  2019. case 'D':
  2020. {
  2021. int templateParamNum = DemangleNumber();
  2022. return Failed();
  2023. }
  2024. break;
  2025. case 'F':
  2026. {
  2027. int param1 = DemangleNumber();
  2028. int param2 = DemangleNumber();
  2029. return Failed();
  2030. }
  2031. break;
  2032. case 'G':
  2033. {
  2034. int param1 = DemangleNumber();
  2035. int param2 = DemangleNumber();
  2036. int param3 = DemangleNumber();
  2037. return Failed();
  2038. }
  2039. break;
  2040. case 'Q':
  2041. {
  2042. int nonTypeTemplateParam = DemangleNumber();
  2043. return Failed();
  2044. }
  2045. break;
  2046. case '$':
  2047. {
  2048. char c = SafeGetChar(mMangledName, mCurIdx++);
  2049. if (c == 'C')
  2050. {
  2051. DemangleCV();
  2052. DemangleType();
  2053. return true;
  2054. }
  2055. else if (c == 'Q')
  2056. {
  2057. DemangleCV();
  2058. DemangleType();
  2059. return true;
  2060. }
  2061. }
  2062. break;
  2063. }
  2064. }
  2065. break;
  2066. case '_':
  2067. {
  2068. c = SafeGetChar(mMangledName, mCurIdx++);
  2069. switch (c)
  2070. {
  2071. case 'D':
  2072. return true;
  2073. case 'E':
  2074. return true;
  2075. case 'F':
  2076. return true;
  2077. case 'G':
  2078. return true;
  2079. case 'H':
  2080. return true;
  2081. case 'I':
  2082. return true;
  2083. case 'J':
  2084. return true;
  2085. case 'K':
  2086. return true;
  2087. case 'L':
  2088. return true;
  2089. case 'M':
  2090. return true;
  2091. case 'W':
  2092. return true;
  2093. case 'N':
  2094. return true;
  2095. default:
  2096. return Failed();
  2097. break;
  2098. }
  2099. }
  2100. break;
  2101. case 'A':
  2102. {
  2103. DemangleModifiedType(false);
  2104. }
  2105. return true;
  2106. case 'B':
  2107. DemangleModifiedType(false);
  2108. return true;
  2109. case 'P':
  2110. DemangleModifiedType(true);
  2111. return true;
  2112. case 'Q':
  2113. DemangleModifiedType(true);
  2114. return true;
  2115. case 'R':
  2116. DemangleModifiedType(true);
  2117. return true;
  2118. case 'S':
  2119. DemangleModifiedType(true);
  2120. return true;
  2121. case 'T':
  2122. // union
  2123. DemangleScopedName();
  2124. return true;
  2125. case 'U':
  2126. // struct
  2127. DemangleScopedName();
  2128. return true;
  2129. case 'V':
  2130. // class
  2131. DemangleScopedName();
  2132. return true;
  2133. case 'W':
  2134. // enum
  2135. c = SafeGetChar(mMangledName, mCurIdx++);
  2136. Require((c >= '0') && (c <= '8'));
  2137. DemangleScopedName();
  2138. return true;
  2139. case 'C':
  2140. return true;
  2141. case 'D':
  2142. return true;
  2143. case 'E':
  2144. return true;
  2145. case 'F':
  2146. return true;
  2147. case 'G':
  2148. return true;
  2149. case 'H':
  2150. return true;
  2151. case 'I':
  2152. return true;
  2153. case 'J':
  2154. return true;
  2155. case 'K':
  2156. return true;
  2157. case 'M':
  2158. return true;
  2159. case 'N':
  2160. return true;
  2161. case 'O':
  2162. return true;
  2163. case 'X':
  2164. return true;
  2165. case '?':
  2166. if (mInArgs)
  2167. {
  2168. int num = DemangleNumber();
  2169. //
  2170. }
  2171. else
  2172. {
  2173. DemangleModifiedType(false);
  2174. }
  2175. break;
  2176. default:
  2177. return Failed();
  2178. break;
  2179. }
  2180. return false;
  2181. }
  2182. int MsDemangleScanner::DemangleNumber()
  2183. {
  2184. char c = SafeGetChar(mMangledName, mCurIdx++);
  2185. bool isSigned = false;
  2186. if (c == '?')
  2187. {
  2188. isSigned = true;
  2189. c = SafeGetChar(mMangledName, mCurIdx++);
  2190. }
  2191. if ((c >= '0') && (c <= '9'))
  2192. {
  2193. return c - '0' + 1;
  2194. }
  2195. int val = 0;
  2196. while ((c >= 'A') && (c <= 'P'))
  2197. {
  2198. val = (val * 10) + (c - 'A');
  2199. c = SafeGetChar(mMangledName, mCurIdx++);
  2200. }
  2201. if (c != '@')
  2202. Failed();
  2203. return val;
  2204. }
  2205. bool MsDemangleScanner::DemangleCV()
  2206. {
  2207. while (true)
  2208. {
  2209. char c = SafeGetChar(mMangledName, mCurIdx++);
  2210. if (c == 'E')
  2211. {
  2212. // __ptr64
  2213. }
  2214. else if (c == 'F')
  2215. {
  2216. // Unaligned
  2217. //BF_ASSERT("Unhandled");
  2218. }
  2219. else if (c == 'I')
  2220. {
  2221. // __restrict
  2222. }
  2223. else
  2224. break;
  2225. }
  2226. mCurIdx--;
  2227. char c = SafeGetChar(mMangledName, mCurIdx++);
  2228. int constVal = 0;
  2229. if ((c < 'A') || (c > 'X'))
  2230. {
  2231. return Failed();
  2232. }
  2233. constVal = c - 'A';
  2234. return true;
  2235. }
  2236. bool MsDemangleScanner::DemangleName()
  2237. {
  2238. bool appendRetType = false;
  2239. bool hasTemplateArgs = false;
  2240. char c = SafeGetChar(mMangledName, mCurIdx++);
  2241. if (c == '?')
  2242. {
  2243. // A ?? is always a function
  2244. return true;
  2245. }
  2246. else
  2247. {
  2248. mCurIdx--;
  2249. Require(DemangleScopedName());
  2250. }
  2251. c = SafeGetChar(mMangledName, mCurIdx++);
  2252. if ((c >= '0') && (c <= '9'))
  2253. {
  2254. // Global variable / static member
  2255. mIsData = true;
  2256. return true;
  2257. }
  2258. // Not data
  2259. return true;
  2260. }
  2261. void MsDemangleScanner::Process(const StringImpl& mangledName)
  2262. {
  2263. mMangledName = mangledName;
  2264. char c = mangledName[mCurIdx++];
  2265. BF_ASSERT(c == '?');
  2266. DemangleName();
  2267. if (mFailed)
  2268. {
  2269. mIsData = false;
  2270. }
  2271. }
  2272. //////////////////////////////////////////////////////////////////////////
  2273. String BfDemangler::Demangle(const StringImpl& mangledName, DbgLanguage language, Flags flags)
  2274. {
  2275. if (mangledName.IsEmpty())
  2276. return "";
  2277. if (mangledName[0] == '?')
  2278. {
  2279. MsDemangler demangler;
  2280. demangler.mLanguage = language;
  2281. demangler.mBeefFixed = (flags & BfDemangler::Flag_BeefFixed) != 0;
  2282. return demangler.Demangle(mangledName);
  2283. }
  2284. else
  2285. {
  2286. DwDemangler demangler;
  2287. demangler.mLanguage = language;
  2288. demangler.mCaptureTargetType = (flags & BfDemangler::Flag_CaptureTargetType) != 0;
  2289. demangler.mRawDemangle = (flags & BfDemangler::Flag_RawDemangle) != 0;
  2290. demangler.mBeefFixed = (flags & BfDemangler::Flag_BeefFixed) != 0;
  2291. return demangler.Demangle(mangledName);
  2292. }
  2293. }
  2294. bool BfDemangler::IsData(const StringImpl& mangledName)
  2295. {
  2296. if (mangledName[0] == '?')
  2297. {
  2298. MsDemangleScanner demangler;
  2299. demangler.Process(mangledName);
  2300. return demangler.mIsData;
  2301. }
  2302. return false;
  2303. }