BfMangler.cpp 59 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191
  1. #include "BfMangler.h"
  2. #include "BfDemangler.h"
  3. #include "BfCompiler.h"
  4. #pragma warning(disable:4996)
  5. USING_NS_BF;
  6. int BfGNUMangler::ParseSubIdx(StringImpl& name, int strIdx)
  7. {
  8. const char* charPtr = name.c_str() + strIdx + 1;
  9. if (*charPtr == '_')
  10. return 0;
  11. int idx = atoi(charPtr) + 1;
  12. return idx;
  13. }
  14. void BfGNUMangler::AddSubIdx(StringImpl& name, int subIdx)
  15. {
  16. name += 'S';
  17. if (subIdx != 0)
  18. {
  19. int showIdx = subIdx - 1;
  20. if (showIdx > 36)
  21. {
  22. name += '0' + (showIdx / 36);
  23. showIdx %= 36;
  24. }
  25. if (showIdx < 10)
  26. name += '0' + showIdx;
  27. else
  28. name += 'A' + (showIdx - 10);
  29. }
  30. name += '_';
  31. }
  32. void BfGNUMangler::AddSizedString(StringImpl& name, const StringImpl& addStr)
  33. {
  34. char str[16];
  35. itoa((int)addStr.length(), str, 10);
  36. name += str;
  37. name += addStr;
  38. }
  39. BfTypeCode BfGNUMangler::GetPrimTypeAt(MangleContext& mangleContext, StringImpl& name, int strIdx)
  40. {
  41. char startChar = name[strIdx];
  42. auto module = mangleContext.mModule;
  43. switch (startChar)
  44. {
  45. case 'v': return BfTypeCode_None;
  46. case 'b': return BfTypeCode_Boolean;
  47. case 'a': return BfTypeCode_Int8;
  48. case 'h': return BfTypeCode_UInt8;
  49. case 's': return BfTypeCode_Int16;
  50. case 't': return BfTypeCode_UInt16;
  51. case 'i': return BfTypeCode_Int32;
  52. case 'j': return BfTypeCode_UInt32;
  53. case 'l': return BfTypeCode_Int64;
  54. case 'm': return BfTypeCode_UInt64;
  55. case 'x': return BfTypeCode_Int64;
  56. case 'y': return BfTypeCode_UInt64;
  57. case 'u':
  58. if (name[strIdx + 1] == '3')
  59. return BfTypeCode_IntPtr;
  60. if (name[strIdx + 1] == '4')
  61. return BfTypeCode_UIntPtr;
  62. break;
  63. case 'c': return BfTypeCode_Char8;
  64. case 'D':
  65. if (name[strIdx + 1] == 'i')
  66. return BfTypeCode_Char32;
  67. else if (name[strIdx + 1] == 's')
  68. return BfTypeCode_Char16;
  69. break;
  70. case 'f': return BfTypeCode_Single;
  71. case 'd': return BfTypeCode_Double;
  72. }
  73. return (BfTypeCode)-1;
  74. }
  75. void BfGNUMangler::AddPrefix(MangleContext& mangleContext, StringImpl& name, int startIdx, const char* prefix)
  76. {
  77. int subIdx;
  78. char startChar = name[startIdx];
  79. if (startChar == 'S')
  80. {
  81. subIdx = ParseSubIdx(name, startIdx);
  82. for (int matchIdx = subIdx + 1; matchIdx < (int)mangleContext.mSubstituteList.size(); matchIdx++)
  83. {
  84. auto& entry = mangleContext.mSubstituteList[matchIdx];
  85. if ((entry.mKind == NameSubstitute::Kind_Prefix) && (entry.mExtendsIdx == subIdx) && (entry.mPrefix == prefix))
  86. {
  87. BF_ASSERT(name.EndsWith('_'));
  88. name.RemoveToEnd(startIdx);
  89. AddSubIdx(name, matchIdx);
  90. return;
  91. }
  92. }
  93. }
  94. else
  95. {
  96. auto typeCode = GetPrimTypeAt(mangleContext, name, startIdx);
  97. if (typeCode != (BfTypeCode)-1)
  98. {
  99. for (int matchIdx = 0; matchIdx < (int)mangleContext.mSubstituteList.size(); matchIdx++)
  100. {
  101. auto& entry = mangleContext.mSubstituteList[matchIdx];
  102. if ((entry.mKind == NameSubstitute::Kind_PrimitivePrefix) && (entry.mExtendsTypeCode == typeCode) && (entry.mPrefix == prefix))
  103. {
  104. name.RemoveToEnd(startIdx);
  105. AddSubIdx(name, matchIdx);
  106. return;
  107. }
  108. }
  109. NameSubstitute nameSub;
  110. nameSub.mKind = NameSubstitute::Kind_PrimitivePrefix;
  111. nameSub.mExtendsTypeCode = typeCode;
  112. nameSub.mPrefix = prefix;
  113. mangleContext.mSubstituteList.push_back(nameSub);
  114. name.Insert(startIdx, prefix);
  115. return;
  116. }
  117. else
  118. {
  119. // Applies to last-added one
  120. subIdx = (int)mangleContext.mSubstituteList.size() - 1;
  121. BF_ASSERT(isdigit(startChar) || (startChar == 'A') || (startChar == 'N') || (startChar == 'P') || (startChar == 'R') || (startChar == 'U'));
  122. }
  123. }
  124. NameSubstitute nameSub;
  125. nameSub.mKind = NameSubstitute::Kind_Prefix;
  126. nameSub.mExtendsIdx = subIdx;
  127. nameSub.mPrefix = prefix;
  128. mangleContext.mSubstituteList.push_back(nameSub);
  129. name.Insert(startIdx, prefix);
  130. }
  131. void BfGNUMangler::FindOrCreateNameSub(MangleContext& mangleContext, StringImpl& name, const NameSubstitute& newNameSub)
  132. {
  133. int curMatchIdx = -1;
  134. bool matchFailed = false;
  135. FindOrCreateNameSub(mangleContext, name, newNameSub, curMatchIdx, matchFailed);
  136. if (!matchFailed)
  137. AddSubIdx(name, curMatchIdx);
  138. }
  139. void BfGNUMangler::FindOrCreateNameSub(MangleContext& mangleContext, StringImpl& name, const NameSubstitute& newNameSub, int& curMatchIdx, bool& matchFailed)
  140. {
  141. int parentIdx = curMatchIdx;
  142. if (!matchFailed)
  143. {
  144. curMatchIdx++;
  145. for ( ; curMatchIdx < (int)mangleContext.mSubstituteList.size(); curMatchIdx++)
  146. {
  147. auto& entry = mangleContext.mSubstituteList[curMatchIdx];
  148. if ((entry.mExtendsIdx == parentIdx) && (entry.mKind == newNameSub.mKind) && (entry.mParam == newNameSub.mParam))
  149. {
  150. return;
  151. }
  152. }
  153. matchFailed = true;
  154. if (newNameSub.mKind != BfGNUMangler::NameSubstitute::Kind_GenericParam)
  155. name += "N";
  156. if (parentIdx != -1)
  157. AddSubIdx(name, parentIdx);
  158. }
  159. if (newNameSub.mKind == NameSubstitute::Kind_NamespaceAtom)
  160. {
  161. AddSizedString(name, newNameSub.mAtom->mString.mPtr);
  162. }
  163. else if (newNameSub.mKind == NameSubstitute::Kind_TypeInstName)
  164. {
  165. auto typeDef = newNameSub.mTypeInst->mTypeDef;
  166. // Mixing this in could create linking errors since the references to the "correct" version won't necessarily be recompiled
  167. // when we remove the "incorrect" version. I believe this is no longer needed since our compilation model has changed
  168. /*if (typeDef->mDupDetectedRevision != -1)
  169. {
  170. char str[64];
  171. sprintf(str, "_%p", typeDef);
  172. name += str;
  173. }*/
  174. if ((typeDef->mIsDelegate) && (newNameSub.mTypeInst->IsClosure()))
  175. {
  176. auto closureType = (BfClosureType*)newNameSub.mTypeInst;
  177. if (!closureType->mCreatedTypeDef)
  178. name += closureType->mNameAdd;
  179. }
  180. AddSizedString(name, typeDef->mName->mString.mPtr);
  181. }
  182. else if (newNameSub.mKind == BfGNUMangler::NameSubstitute::Kind_TypeGenericArgs)
  183. {
  184. int genericParamStart = 0;
  185. if (newNameSub.mTypeInst->mTypeDef->mOuterType != NULL)
  186. genericParamStart = (int)newNameSub.mTypeInst->mTypeDef->mOuterType->mGenericParamDefs.size();
  187. name += "I";
  188. auto typeDef = newNameSub.mTypeInst->mTypeDef;
  189. BfType* checkType = newNameSub.mTypeInst;
  190. if (checkType->IsClosure())
  191. {
  192. checkType = ((BfClosureType*)checkType)->mSrcDelegate;
  193. }
  194. BF_ASSERT(checkType->IsGenericTypeInstance());
  195. BfGenericTypeInstance* genericTypeInstance = (BfGenericTypeInstance*)checkType;
  196. for (int genericParamIdx = genericParamStart; genericParamIdx < (int) typeDef->mGenericParamDefs.size(); genericParamIdx++)
  197. {
  198. auto genericParam = genericTypeInstance->mTypeGenericArguments[genericParamIdx];
  199. Mangle(mangleContext, name, genericParam);
  200. }
  201. name += "E";
  202. }
  203. else if (newNameSub.mKind == BfGNUMangler::NameSubstitute::Kind_GenericParam)
  204. {
  205. auto genericParamType = (BfGenericParamType*)newNameSub.mType;
  206. char str[16];
  207. if (genericParamType->mGenericParamIdx < 10)
  208. name += "3";
  209. else
  210. name += "4";
  211. if (genericParamType->mGenericParamKind == BfGenericParamKind_Method)
  212. name += "`M";
  213. else
  214. name += "`T";
  215. itoa(genericParamType->mGenericParamIdx, str, 10);
  216. name += str;
  217. }
  218. curMatchIdx = (int)mangleContext.mSubstituteList.size();
  219. mangleContext.mSubstituteList.push_back(newNameSub);
  220. auto& nameSubRef = mangleContext.mSubstituteList.back();
  221. nameSubRef.mExtendsIdx = parentIdx;
  222. }
  223. void BfGNUMangler::FindOrCreateNameSub(MangleContext& mangleContext, StringImpl& name, BfTypeInstance* typeInst, int& curMatchIdx, bool& matchFailed)
  224. {
  225. auto typeDef = typeInst->mTypeDef;
  226. if (typeDef->IsGlobalsContainer())
  227. return;
  228. int numOuterGenericParams = 0;
  229. if (typeDef->mOuterType != NULL)
  230. {
  231. numOuterGenericParams = (int)typeDef->mOuterType->mGenericParamDefs.size();
  232. auto useModule = typeInst->mModule;
  233. if (useModule == NULL)
  234. useModule = mangleContext.mModule;
  235. auto outerType = useModule->GetOuterType(typeInst);
  236. FindOrCreateNameSub(mangleContext, name, outerType, curMatchIdx, matchFailed);
  237. }
  238. FindOrCreateNameSub(mangleContext, name, NameSubstitute(NameSubstitute::Kind_TypeInstName, typeInst), curMatchIdx, matchFailed);
  239. if (typeDef->mGenericParamDefs.size() != numOuterGenericParams)
  240. {
  241. FindOrCreateNameSub(mangleContext, name, NameSubstitute(NameSubstitute::Kind_TypeGenericArgs, typeInst), curMatchIdx, matchFailed);
  242. }
  243. }
  244. void BfGNUMangler::MangleTypeInst(MangleContext& mangleContext, StringImpl& name, BfTypeInstance* typeInst, BfTypeInstance* postfixTypeInstance, bool* isEndOpen)
  245. {
  246. static int sCallCount = 0;
  247. sCallCount++;
  248. if (typeInst->IsTuple())
  249. {
  250. auto tupleType = (BfTupleType*)typeInst;
  251. name += "N7__TUPLEI";
  252. mangleContext.mSubstituteList.push_back(NameSubstitute(BfGNUMangler::NameSubstitute::Kind_None, NULL)); // Insert entry for '__TUPLE'
  253. for (int fieldIdx = 0; fieldIdx < (int)tupleType->mFieldInstances.size(); fieldIdx++)
  254. {
  255. BfFieldInstance* fieldInstance = &tupleType->mFieldInstances[fieldIdx];
  256. BfFieldDef* fieldDef = fieldInstance->GetFieldDef();
  257. String fieldName = fieldDef->mName;
  258. if ((fieldName[0] < '0') || (fieldName[0] > '9'))
  259. name += StrFormat("U%d`%s", fieldName.length() + 1, fieldName.c_str());
  260. Mangle(mangleContext, name, fieldInstance->mResolvedType, postfixTypeInstance);
  261. }
  262. name += "E";
  263. mangleContext.mSubstituteList.push_back(NameSubstitute(BfGNUMangler::NameSubstitute::Kind_None, NULL)); // Insert entry for '__TUPLE<T>'
  264. if (isEndOpen != NULL)
  265. *isEndOpen = true;
  266. else
  267. name += "E";
  268. return;
  269. }
  270. else if ((typeInst->IsDelegateFromTypeRef()) || (typeInst->IsFunctionFromTypeRef()))
  271. {
  272. auto invokeMethodInst = mangleContext.mModule->GetDelegateInvokeMethod(typeInst);
  273. if (typeInst->IsDelegate())
  274. name += "N8delegateI";
  275. else
  276. name += "N8functionI";
  277. BfTypeVector typeVec;
  278. typeVec.push_back(invokeMethodInst->mReturnType);
  279. for (int paramIdx = 0; paramIdx < (int)invokeMethodInst->mParams.size(); paramIdx++)
  280. {
  281. name += "_";
  282. name += invokeMethodInst->GetParamName(paramIdx);
  283. typeVec.Add(invokeMethodInst->GetParamType(paramIdx));
  284. }
  285. for (auto type : typeVec)
  286. Mangle(mangleContext, name, type, postfixTypeInstance);
  287. mangleContext.mSubstituteList.push_back(NameSubstitute(BfGNUMangler::NameSubstitute::Kind_None, NULL)); // Insert entry for 'Delegate'
  288. name += "E";
  289. mangleContext.mSubstituteList.push_back(NameSubstitute(BfGNUMangler::NameSubstitute::Kind_None, NULL)); // Insert entry for 'Delegate<T>'
  290. if (isEndOpen != NULL)
  291. *isEndOpen = true;
  292. else
  293. name += "E";
  294. name += "E";
  295. }
  296. else if (typeInst->IsBoxed())
  297. {
  298. auto boxedType = (BfBoxedType*)typeInst;
  299. name += "N3BoxI";
  300. mangleContext.mSubstituteList.push_back(NameSubstitute(BfGNUMangler::NameSubstitute::Kind_None, NULL)); // Insert entry for 'Box'
  301. Mangle(mangleContext, name, boxedType->GetModifiedElementType(), postfixTypeInstance);
  302. name += "E";
  303. mangleContext.mSubstituteList.push_back(NameSubstitute(BfGNUMangler::NameSubstitute::Kind_None, NULL)); // Insert entry for 'Box<T>'
  304. if (isEndOpen != NULL)
  305. *isEndOpen = true;
  306. else
  307. name += "E";
  308. return;
  309. }
  310. int curMatchIdx = -1;
  311. bool matchFailed = false;
  312. for (int typeIdx = 0; typeIdx < 2; typeIdx++)
  313. {
  314. BfTypeInstance* useTypeInst = typeInst;
  315. if (typeIdx == 1)
  316. {
  317. if (postfixTypeInstance == NULL)
  318. break;
  319. useTypeInst = postfixTypeInstance;
  320. }
  321. auto typeDef = useTypeInst->mTypeDef;
  322. FindOrCreateNameSub(mangleContext, name, NameSubstitute(NameSubstitute::Kind_NamespaceAtom, typeInst->mModule->mSystem->mBfAtom), curMatchIdx, matchFailed);
  323. for (int i = 0; i < typeDef->mNamespace.mSize; i++)
  324. FindOrCreateNameSub(mangleContext, name, NameSubstitute(NameSubstitute::Kind_NamespaceAtom, typeDef->mNamespace.mParts[i]), curMatchIdx, matchFailed);
  325. FindOrCreateNameSub(mangleContext, name, useTypeInst, curMatchIdx, matchFailed);
  326. }
  327. if (isEndOpen != NULL)
  328. {
  329. if (!matchFailed)
  330. {
  331. if (curMatchIdx != -1)
  332. {
  333. name += "N";
  334. AddSubIdx(name, curMatchIdx);
  335. *isEndOpen = true;
  336. }
  337. else
  338. *isEndOpen = false;
  339. }
  340. else
  341. *isEndOpen = true;
  342. return;
  343. }
  344. if (matchFailed)
  345. {
  346. name += "E";
  347. }
  348. else
  349. {
  350. AddSubIdx(name, curMatchIdx);
  351. }
  352. }
  353. void BfGNUMangler::Mangle(MangleContext& mangleContext, StringImpl& name, BfType* type, BfType* postfixType)
  354. {
  355. static int sCallCount = 0;
  356. sCallCount++;
  357. if (type->IsPrimitiveType())
  358. {
  359. auto primType = (BfPrimitiveType*)type;
  360. switch (primType->mTypeDef->mTypeCode)
  361. {
  362. case BfTypeCode_NullPtr:
  363. {
  364. auto pointerType = (BfPointerType*)type;
  365. int startIdx = (int)name.length();
  366. name += "v";
  367. AddPrefix(mangleContext, name, startIdx, "P");
  368. }
  369. return;
  370. case BfTypeCode_Dot:
  371. name += "U3dot";
  372. return;
  373. case BfTypeCode_None:
  374. if ((mangleContext.mCCompat) || (mangleContext.mInArgs))
  375. name += "v";
  376. else
  377. name += "U4void";
  378. return;
  379. case BfTypeCode_Var:
  380. if ((mangleContext.mCCompat) || (mangleContext.mInArgs))
  381. name += "v";
  382. else
  383. name += "U3var";
  384. return;
  385. case BfTypeCode_Self:
  386. if ((mangleContext.mCCompat) || (mangleContext.mInArgs))
  387. name += "U8concrete";
  388. else
  389. name += "U4self";
  390. return;
  391. case BfTypeCode_Boolean:
  392. name += "b"; return;
  393. case BfTypeCode_Int8:
  394. name += "a"; return;
  395. case BfTypeCode_UInt8:
  396. name += "h"; return;
  397. case BfTypeCode_Int16:
  398. name += "s"; return;
  399. case BfTypeCode_UInt16:
  400. name += "t"; return;
  401. case BfTypeCode_Int32:
  402. name += "i"; return;
  403. case BfTypeCode_UInt32:
  404. name += "j"; return;
  405. case BfTypeCode_Int64:
  406. if (mangleContext.mModule->mCompiler->mOptions.mCLongSize == 8)
  407. name += "l";
  408. else
  409. name += "x";
  410. return;
  411. case BfTypeCode_UInt64:
  412. if (mangleContext.mModule->mCompiler->mOptions.mCLongSize == 8)
  413. name += "m";
  414. else
  415. name += "y";
  416. return;
  417. case BfTypeCode_UIntPtr:
  418. if ((mangleContext.mCCompat) || (mangleContext.mInArgs))
  419. {
  420. if (mangleContext.mModule->mCompiler->mOptions.mCLongSize == 8)
  421. name += (primType->mSize == 8) ? "m" : "j";
  422. else
  423. name += (primType->mSize == 8) ? "y" : "j";
  424. return;
  425. }
  426. name += "u4uint";
  427. return;
  428. case BfTypeCode_IntPtr:
  429. if ((mangleContext.mCCompat) || (mangleContext.mInArgs))
  430. {
  431. if (mangleContext.mModule->mCompiler->mOptions.mCLongSize == 8)
  432. name += (primType->mSize == 8) ? "l" : "i";
  433. else
  434. name += (primType->mSize == 8) ? "x" : "i";
  435. return;
  436. }
  437. name += "u3int";
  438. return;
  439. case BfTypeCode_Char8:
  440. name += "c"; return;
  441. case BfTypeCode_Char16:
  442. name += "Ds"; return;
  443. case BfTypeCode_Char32:
  444. name += "Di"; return;
  445. case BfTypeCode_Single:
  446. name += "f"; return;
  447. case BfTypeCode_Double:
  448. name += "d"; return;
  449. default: break;
  450. }
  451. name += "?"; return;
  452. //name += Mangle(primType->mTypeDef, NULL, addName, NULL, substituteList);
  453. }
  454. else if (type->IsTypeInstance())
  455. {
  456. BfTypeInstance* postfixTypeInst = NULL;
  457. if (postfixType != NULL)
  458. postfixTypeInst = postfixType->ToTypeInstance();
  459. auto typeInstance = (BfTypeInstance*)type;
  460. int startIdx = (int)name.length();
  461. MangleTypeInst(mangleContext, name, typeInstance, postfixTypeInst);
  462. if ((type->IsObjectOrInterface()) && (mangleContext.mPrefixObjectPointer))
  463. AddPrefix(mangleContext, name, startIdx, "P");
  464. }
  465. else if (type->IsGenericParam())
  466. {
  467. FindOrCreateNameSub(mangleContext, name, NameSubstitute(NameSubstitute::Kind_GenericParam, type));
  468. }
  469. else if (type->IsPointer())
  470. {
  471. auto pointerType = (BfPointerType*)type;
  472. int startIdx = (int)name.length();
  473. Mangle(mangleContext, name, pointerType->mElementType);
  474. AddPrefix(mangleContext, name, startIdx, "P");
  475. return;
  476. }
  477. else if (type->IsRef())
  478. {
  479. BfRefType* refType = (BfRefType*)type;
  480. if ((refType->mRefKind == BfRefType::RefKind_Mut) && (!mangleContext.mCCompat))
  481. {
  482. name += "U3mut";
  483. Mangle(mangleContext, name, refType->mElementType);
  484. return;
  485. }
  486. else if ((refType->mRefKind == BfRefType::RefKind_Out) && (!mangleContext.mCCompat))
  487. {
  488. name += "U3out";
  489. Mangle(mangleContext, name, refType->mElementType);
  490. return;
  491. }
  492. int startIdx = (int)name.length();
  493. Mangle(mangleContext, name, refType->mElementType);
  494. AddPrefix(mangleContext, name, startIdx, "R");
  495. return;
  496. }
  497. else if (type->IsRetTypeType())
  498. {
  499. BfRetTypeType* retTypeType = (BfRetTypeType*)type;
  500. name += "U7rettype";
  501. Mangle(mangleContext, name, retTypeType->mElementType);
  502. return;
  503. }
  504. else if (type->IsConcreteInterfaceType())
  505. {
  506. BfConcreteInterfaceType* concreteInterfaceType = (BfConcreteInterfaceType*)type;
  507. name += "U8concrete";
  508. Mangle(mangleContext, name, concreteInterfaceType->mInterface);
  509. return;
  510. }
  511. else if (type->IsSizedArray())
  512. {
  513. BfSizedArrayType* arrayType = (BfSizedArrayType*)type;
  514. name += StrFormat("A%d_");
  515. Mangle(mangleContext, name, arrayType->mElementType);
  516. return;
  517. }
  518. else if (type->IsMethodRef())
  519. {
  520. auto methodRefType = (BfMethodRefType*)type;
  521. String mrefName = "mref_";
  522. String mangleName;
  523. BfMethodInstance* methodInstance = methodRefType->mMethodRef;
  524. if (methodInstance == NULL)
  525. {
  526. BF_ASSERT(!methodRefType->mMangledMethodName.IsEmpty());
  527. mangleName = methodRefType->mMangledMethodName;
  528. }
  529. else
  530. {
  531. if (methodInstance->mIsAutocompleteMethod)
  532. name += "AUTOCOMPLETE";
  533. auto module = methodInstance->GetOwner()->mModule;
  534. if (module->mCompiler->mIsResolveOnly)
  535. {
  536. // There are cases where we will reprocess a method in ResolveOnly for things like
  537. // GetSymbolReferences, so we will have duplicate live local methodInstances in those cases
  538. mrefName += HashEncode64((uint64)methodRefType->mMethodRef);
  539. }
  540. else
  541. {
  542. mangleName = Mangle(methodInstance);
  543. methodRefType->mMangledMethodName = mangleName;
  544. }
  545. }
  546. if (!mangleName.IsEmpty())
  547. {
  548. Val128 val128 = Hash128(mangleName.c_str(), (int)mangleName.length());
  549. mrefName += HashEncode128(val128);
  550. }
  551. //TODO: Make a 'U' name?
  552. name += mrefName;
  553. }
  554. else if (type->IsConstExprValue())
  555. {
  556. BfConstExprValueType* constExprValueType = (BfConstExprValueType*)type;
  557. int64 val = constExprValueType->mValue.mInt64;
  558. if ((!constExprValueType->mType->IsPrimitiveType()) ||
  559. (((BfPrimitiveType*)constExprValueType->mType)->mTypeDef->mTypeCode != BfTypeCode_IntPtr))
  560. {
  561. Mangle(mangleContext, name, constExprValueType->mType);
  562. }
  563. name += "$0";
  564. if (val < 0)
  565. {
  566. name += "?";
  567. val = -val;
  568. }
  569. if ((val >= 1) && (val < 10))
  570. {
  571. val += (char)('0' + val - 1);
  572. }
  573. else
  574. {
  575. char str[64];
  576. char* strP = str + 63;
  577. *strP = 0;
  578. while (val > 0)
  579. {
  580. *(strP--) = (char)((val % 0x10) + 'A');
  581. val /= 0x10;
  582. }
  583. name += strP;
  584. name += '`';
  585. }
  586. }
  587. else
  588. {
  589. BF_FATAL("Not handled");
  590. }
  591. }
  592. String BfGNUMangler::Mangle(BfType* type, BfModule* module)
  593. {
  594. StringT<256> name;
  595. name += "_ZTS";
  596. MangleContext mangleContext;
  597. mangleContext.mModule = module;
  598. Mangle(mangleContext, name, type);
  599. return name;
  600. }
  601. String BfGNUMangler::Mangle(BfMethodInstance* methodInst)
  602. {
  603. StringT<256> name;
  604. if ((methodInst->mMethodDef->mCLink) && (!methodInst->mMangleWithIdx))
  605. {
  606. return methodInst->mMethodDef->mName;
  607. }
  608. MangleContext mangleContext;
  609. mangleContext.mModule = methodInst->GetOwner()->mModule;
  610. mangleContext.mCCompat = methodInst->mMethodDef->mIsExtern;
  611. //auto substituteListPtr = doSubstitute ? &mangleContext.mSubstituteList : NULL;
  612. auto typeInst = methodInst->GetOwner();
  613. auto methodDef = methodInst->mMethodDef;
  614. bool mangledMethodIdx = false;
  615. bool prefixLen = false;
  616. bool isNameOpen = false;
  617. name += "_Z";
  618. MangleTypeInst(mangleContext, name, methodInst->mMethodInstanceGroup->mOwner, methodInst->GetExplicitInterface(), &isNameOpen);
  619. if (methodInst->GetForeignType() != NULL)
  620. {
  621. // This won't demangle correctly. TODO: Do this 'correctly'
  622. MangleTypeInst(mangleContext, name, methodInst->GetForeignType());
  623. }
  624. mangleContext.mPrefixObjectPointer = true;
  625. String methodName = methodInst->mMethodDef->mName;
  626. if (methodInst->mMethodDef->mIsOperator)
  627. {
  628. auto operatorDef = (BfOperatorDef*)methodInst->mMethodDef;
  629. if (operatorDef->mOperatorDeclaration->mIsConvOperator)
  630. {
  631. methodName = "cv";
  632. Mangle(mangleContext, methodName, methodInst->mReturnType);
  633. }
  634. else
  635. {
  636. switch (operatorDef->mOperatorDeclaration->mBinOp)
  637. {
  638. case BfBinaryOp_Add:
  639. methodName = "pl";
  640. break;
  641. case BfBinaryOp_Subtract:
  642. methodName = "mi";
  643. break;
  644. case BfBinaryOp_Multiply:
  645. methodName = "ml";
  646. break;
  647. case BfBinaryOp_Divide:
  648. methodName = "dv";
  649. break;
  650. case BfBinaryOp_Modulus:
  651. methodName = "rm";
  652. break;
  653. case BfBinaryOp_BitwiseAnd:
  654. methodName = "an";
  655. break;
  656. case BfBinaryOp_BitwiseOr:
  657. methodName = "or";
  658. break;
  659. case BfBinaryOp_ExclusiveOr:
  660. methodName = "eo";
  661. break;
  662. case BfBinaryOp_LeftShift:
  663. methodName = "ls";
  664. break;
  665. case BfBinaryOp_RightShift:
  666. methodName = "rs";
  667. break;
  668. case BfBinaryOp_Equality:
  669. methodName = "eq";
  670. break;
  671. case BfBinaryOp_InEquality:
  672. methodName = "ne";
  673. break;
  674. case BfBinaryOp_GreaterThan:
  675. methodName = "gt";
  676. break;
  677. case BfBinaryOp_LessThan:
  678. methodName = "lt";
  679. break;
  680. case BfBinaryOp_GreaterThanOrEqual:
  681. methodName = "ge";
  682. break;
  683. case BfBinaryOp_LessThanOrEqual:
  684. methodName = "le";
  685. break;
  686. case BfBinaryOp_ConditionalAnd:
  687. methodName = "aa";
  688. break;
  689. case BfBinaryOp_ConditionalOr:
  690. methodName = "oo";
  691. break;
  692. case BfBinaryOp_NullCoalesce:
  693. methodName = "2nc";
  694. break;
  695. case BfBinaryOp_Is:
  696. methodName = "2is";
  697. break;
  698. case BfBinaryOp_As:
  699. methodName = "2as";
  700. break;
  701. default: break;
  702. }
  703. switch (operatorDef->mOperatorDeclaration->mUnaryOp)
  704. {
  705. case BfUnaryOp_AddressOf:
  706. methodName = "ad";
  707. break;
  708. case BfUnaryOp_Dereference:
  709. methodName = "de";
  710. break;
  711. case BfUnaryOp_Negate:
  712. methodName = "ng";
  713. break;
  714. case BfUnaryOp_Not:
  715. methodName = "nt";
  716. break;
  717. case BfUnaryOp_Positive:
  718. methodName = "ps";
  719. break;
  720. case BfUnaryOp_InvertBits:
  721. methodName = "co";
  722. break;
  723. case BfUnaryOp_Increment:
  724. methodName = "pp";
  725. break;
  726. case BfUnaryOp_Decrement:
  727. methodName = "mm";
  728. break;
  729. case BfUnaryOp_PostIncrement:
  730. methodName = "pp";
  731. break;
  732. case BfUnaryOp_PostDecrement:
  733. methodName = "mm";
  734. break;
  735. case BfUnaryOp_Ref:
  736. methodName = "3ref";
  737. break;
  738. case BfUnaryOp_Mut:
  739. methodName = "3mut";
  740. break;
  741. case BfUnaryOp_Out:
  742. methodName = "3out";
  743. break;
  744. default: break;
  745. }
  746. }
  747. }
  748. else if (methodInst->mMethodDef->mMethodType == BfMethodType_Ctor)
  749. {
  750. if (methodInst->mMethodDef->mIsStatic)
  751. {
  752. methodName = "__BfStaticCtor";
  753. prefixLen = true;
  754. }
  755. else
  756. methodName = "C1";
  757. }
  758. else if (methodInst->mMethodDef->mMethodType == BfMethodType_Dtor)
  759. {
  760. if (methodInst->mMethodDef->mIsStatic)
  761. {
  762. methodName = "__BfStaticDtor";
  763. prefixLen = true;
  764. }
  765. else
  766. methodName = "D1";
  767. }
  768. else
  769. {
  770. if (methodInst->mMangleWithIdx)
  771. {
  772. methodName += StrFormat("`%d", methodInst->mMethodDef->mIdx);
  773. mangledMethodIdx = true;
  774. }
  775. prefixLen = true;
  776. }
  777. if (methodDef->mCheckedKind == BfCheckedKind_Checked)
  778. name += "`CHK";
  779. else if (methodDef->mCheckedKind == BfCheckedKind_Unchecked)
  780. name += "`UCHK";
  781. if ((methodInst->mMethodDef->mDeclaringType->mPartialIdx != -1) && (!methodInst->mIsForeignMethodDef))
  782. {
  783. auto declType = methodInst->mMethodDef->mDeclaringType;
  784. BF_ASSERT(methodInst->GetOwner()->mTypeDef->mIsCombinedPartial);
  785. auto declProject = declType->mProject;
  786. bool addProjectName = (declProject != typeInst->mTypeDef->mProject);
  787. bool addIndex = true;
  788. if (typeInst->mTypeDef->IsGlobalsContainer())
  789. {
  790. addProjectName = true;
  791. if ((methodInst->mMethodDef->mCallingConvention == BfCallingConvention_Cdecl) ||
  792. (methodInst->mMethodDef->mCallingConvention == BfCallingConvention_Stdcall))
  793. {
  794. addProjectName = false;
  795. addIndex = false;
  796. }
  797. }
  798. if (addProjectName)
  799. {
  800. name += declProject->mName;
  801. name += "$";
  802. }
  803. if (addIndex)
  804. name += StrFormat("%d$", declType->mPartialIdx);
  805. }
  806. if ((methodInst->mMangleWithIdx) && (!mangledMethodIdx))
  807. {
  808. methodName += StrFormat("`%d", methodInst->mMethodDef->mIdx);
  809. }
  810. //
  811. if ((prefixLen) && (methodInst->mMethodInstanceGroup->mOwner->mTypeDef->IsGlobalsContainer()) && (methodInst->mMethodDef->mMethodDeclaration == NULL))
  812. {
  813. methodName += '`';
  814. methodName += methodInst->mMethodInstanceGroup->mOwner->mTypeDef->mProject->mName;
  815. }
  816. if (prefixLen)
  817. AddSizedString(name, methodName);
  818. else
  819. name += methodName;
  820. if (methodInst->GetNumGenericArguments() != 0)
  821. {
  822. auto& methodGenericArguments = methodInst->mMethodInfoEx->mMethodGenericArguments;
  823. NameSubstitute nameSub(NameSubstitute::Kind_MethodName, methodInst);
  824. nameSub.mExtendsIdx = (int)mangleContext.mSubstituteList.size() - 1;
  825. mangleContext.mSubstituteList.push_back(nameSub);
  826. name += 'I';
  827. for (auto genericArg : methodGenericArguments)
  828. Mangle(mangleContext, name, genericArg);
  829. name += 'E';
  830. }
  831. else if (methodInst->mMethodDef->mGenericParams.size() != 0)
  832. {
  833. NameSubstitute nameSub(NameSubstitute::Kind_MethodName, methodInst);
  834. nameSub.mExtendsIdx = (int)mangleContext.mSubstituteList.size() - 1;
  835. mangleContext.mSubstituteList.push_back(nameSub);
  836. name += 'I';
  837. for (auto genericArg : methodInst->mMethodDef->mGenericParams)
  838. name += 'v';
  839. name += 'E';
  840. }
  841. if (isNameOpen)
  842. name += 'E';
  843. if (methodInst->mMethodDef->mGenericParams.size() != 0)
  844. Mangle(mangleContext, name, methodInst->mReturnType);
  845. mangleContext.mInArgs = true;
  846. bool doExplicitThis = (!methodDef->mIsStatic) && (typeInst->IsTypedPrimitive());
  847. if (doExplicitThis) // Explicit "_this"
  848. Mangle(mangleContext, name, typeInst->GetUnderlyingType());
  849. for (int paramIdx = 0; paramIdx < (int)methodInst->GetParamCount(); paramIdx++)
  850. {
  851. BfType* paramType = methodInst->GetParamType(paramIdx);
  852. auto paramKind = methodInst->GetParamKind(paramIdx);
  853. if (paramKind == BfParamKind_Params)
  854. name += "U6params";
  855. else if (paramKind == BfParamKind_DelegateParam)
  856. name += "U5param";
  857. Mangle(mangleContext, name, paramType);
  858. }
  859. if ((methodInst->GetParamCount() == 0) && (!doExplicitThis))
  860. name += 'v';
  861. return name;
  862. }
  863. String BfGNUMangler::MangleMethodName(BfTypeInstance* type, const StringImpl& methodName)
  864. {
  865. MangleContext mangleContext;
  866. mangleContext.mModule = type->mModule;
  867. StringT<256> name = "_Z";
  868. auto typeInst = type->ToTypeInstance();
  869. BF_ASSERT(typeInst != NULL);
  870. bool isNameOpen;
  871. MangleTypeInst(mangleContext, name, typeInst, NULL, &isNameOpen);
  872. AddSizedString(name, methodName);
  873. if (isNameOpen)
  874. name += "E";
  875. name += "v";
  876. return name;
  877. }
  878. String BfGNUMangler::MangleStaticFieldName(BfTypeInstance* type, const StringImpl& fieldName)
  879. {
  880. auto typeInst = type->ToTypeInstance();
  881. auto typeDef = typeInst->mTypeDef;
  882. if ((typeDef->IsGlobalsContainer()) && (typeDef->mNamespace.IsEmpty()))
  883. return fieldName;
  884. MangleContext mangleContext;
  885. mangleContext.mModule = type->mModule;
  886. StringT<256> name = "_Z";
  887. bool isNameOpen;
  888. MangleTypeInst(mangleContext, name, typeInst, NULL, &isNameOpen);
  889. AddSizedString(name, fieldName);
  890. if (isNameOpen)
  891. name += "E";
  892. return name;
  893. }
  894. //////////////////////////////////////////////////////////////////////////
  895. BfModule* BfMSMangler::MangleContext::GetUnreifiedModule()
  896. {
  897. if (mModule == NULL)
  898. return NULL;
  899. return mModule->mContext->mUnreifiedModule;
  900. }
  901. //////////////////////////////////////////////////////////////////////////
  902. void BfMSMangler::AddGenericArgs(MangleContext& mangleContext, StringImpl& name, const SizedArrayImpl<BfType*>& genericArgs, int numOuterGenericParams)
  903. {
  904. if (numOuterGenericParams == (int)genericArgs.size())
  905. return;
  906. auto prevSubList = mangleContext.mSubstituteList;
  907. auto prevSubTypeList = mangleContext.mSubstituteTypeList;
  908. mangleContext.mSubstituteList.clear();
  909. for (int genericIdx = numOuterGenericParams; genericIdx < (int)genericArgs.size(); genericIdx++)
  910. Mangle(mangleContext, name, genericArgs[genericIdx]);
  911. mangleContext.mSubstituteList = prevSubList;
  912. mangleContext.mSubstituteTypeList = prevSubTypeList;
  913. }
  914. void BfMSMangler::AddStr(MangleContext& mangleContext, StringImpl& name, const StringImpl& str)
  915. {
  916. if ((int)mangleContext.mSubstituteList.size() < 10)
  917. {
  918. // Add NULL entry... shouldn't match anything
  919. mangleContext.mSubstituteList.push_back(NameSubstitute(NameSubstitute::Kind_None, NULL));
  920. }
  921. name += str;
  922. name += '@';
  923. }
  924. void BfMSMangler::AddSubIdx(StringImpl& name, int strIdx)
  925. {
  926. //TODO: BF_ASSERT(strIdx < 10);
  927. char str[16];
  928. itoa(strIdx, str, 10);
  929. name += str;
  930. }
  931. void BfMSMangler::AddTypeStart(MangleContext& mangleContext, StringImpl& name, BfType* type)
  932. {
  933. if (mangleContext.mIsSafeMangle)
  934. {
  935. name += "V"; // Mangle everything as a struct so we don't need to require the type to be populated
  936. return;
  937. }
  938. if (!type->IsDeclared())
  939. {
  940. if (mangleContext.mModule != NULL)
  941. {
  942. auto unreifiedModule = mangleContext.GetUnreifiedModule();
  943. if (unreifiedModule != NULL)
  944. unreifiedModule->PopulateType(type, BfPopulateType_Declaration);
  945. }
  946. else
  947. {
  948. BF_FATAL("No module");
  949. }
  950. }
  951. if ((type->IsEnum()) && (type->IsTypedPrimitive()))
  952. {
  953. auto unreifiedModule = mangleContext.GetUnreifiedModule();
  954. if (unreifiedModule != NULL)
  955. unreifiedModule->PopulateType(type, BfPopulateType_Data);
  956. BF_ASSERT(type->mSize >= 0);
  957. // The enum size is supposed to be encoded, but VC always uses '4'
  958. //name += "W";
  959. //name += ('0' + type->mSize);
  960. name += "W4";
  961. return;
  962. }
  963. name += type->IsStruct() ? "U" : "V";
  964. }
  965. bool BfMSMangler::FindOrCreateNameSub(MangleContext& mangleContext, StringImpl& name, const NameSubstitute& newNameSub)
  966. {
  967. for (int curMatchIdx = 0; curMatchIdx < (int)mangleContext.mSubstituteList.size(); curMatchIdx++)
  968. {
  969. auto& entry = mangleContext.mSubstituteList[curMatchIdx];
  970. if ((entry.mKind == newNameSub.mKind) && (entry.mParam == newNameSub.mParam) && (entry.mExtendsTypeId == newNameSub.mExtendsTypeId))
  971. {
  972. AddSubIdx(name, curMatchIdx);
  973. return true;
  974. }
  975. }
  976. if (newNameSub.mKind == NameSubstitute::Kind_NamespaceAtom)
  977. {
  978. name += newNameSub.mAtom->mString;
  979. name += '@';
  980. }
  981. else if (newNameSub.mKind == NameSubstitute::Kind_TypeInstName)
  982. {
  983. if (mangleContext.mWantsGroupStart)
  984. {
  985. AddTypeStart(mangleContext, name, newNameSub.mTypeInst);
  986. mangleContext.mWantsGroupStart = false;
  987. }
  988. if (newNameSub.mTypeInst->IsTuple())
  989. {
  990. auto tupleType = (BfTupleType*)newNameSub.mType;
  991. name += "?$__TUPLE";
  992. BfTypeVector typeVec;
  993. for (auto& fieldInst : tupleType->mFieldInstances)
  994. {
  995. BfFieldDef* fieldDef = fieldInst.GetFieldDef();
  996. String fieldName = fieldDef->mName;
  997. if ((fieldName[0] < '0') || (fieldName[0] > '9'))
  998. name += StrFormat("_%s", fieldName.c_str());
  999. typeVec.push_back(fieldInst.mResolvedType);
  1000. }
  1001. name += '@';
  1002. if (!typeVec.empty())
  1003. AddGenericArgs(mangleContext, name, typeVec);
  1004. name += '@';
  1005. }
  1006. else if ((newNameSub.mTypeInst->IsDelegateFromTypeRef()) || (newNameSub.mTypeInst->IsFunctionFromTypeRef()))
  1007. {
  1008. BF_ASSERT(newNameSub.mTypeInst->mTypeDef->mMethods[0]->mName == "Invoke");
  1009. //
  1010. {
  1011. auto methodDef = newNameSub.mTypeInst->mTypeDef->mMethods[0];
  1012. if (newNameSub.mTypeInst->IsDelegate())
  1013. name += "?$delegate";
  1014. else
  1015. name += "?$function";
  1016. BfTypeVector typeVec;
  1017. typeVec.push_back(BfNodeDynCast<BfDirectTypeReference>(methodDef->mReturnTypeRef)->mType);
  1018. for (int paramIdx = 0; paramIdx < (int)methodDef->mParams.size(); paramIdx++)
  1019. {
  1020. name += "_";
  1021. name += methodDef->mParams[paramIdx]->mName;
  1022. typeVec.push_back(BfNodeDynCast<BfDirectTypeReference>(methodDef->mParams[paramIdx]->mTypeRef)->mType);
  1023. }
  1024. name += '@';
  1025. if (!typeVec.empty())
  1026. AddGenericArgs(mangleContext, name, typeVec);
  1027. name += '@';
  1028. }
  1029. // auto invokeMethodInst = mangleContext.mModule->GetDelegateInvokeMethod(newNameSub.mTypeInst);
  1030. // if (newNameSub.mTypeInst->IsDelegate())
  1031. // name += "?$delegate";
  1032. // else
  1033. // name += "?$function";
  1034. // BfTypeVector typeVec;
  1035. // typeVec.push_back(invokeMethodInst->mReturnType);
  1036. // for (int paramIdx = 0; paramIdx < (int)invokeMethodInst->mParams.size(); paramIdx++)
  1037. // {
  1038. // name += "_";
  1039. // name += invokeMethodInst->GetParamName(paramIdx);
  1040. // typeVec.push_back(invokeMethodInst->GetParamType(paramIdx));
  1041. // }
  1042. // name += '@';
  1043. // if (!typeVec.empty())
  1044. // AddGenericArgs(mangleContext, name, typeVec);
  1045. // name += '@';
  1046. }
  1047. else if (newNameSub.mTypeInst->IsBoxed())
  1048. {
  1049. auto boxedType = (BfBoxedType*)newNameSub.mTypeInst;
  1050. name += "?$Box@";
  1051. BfTypeVector typeVec;
  1052. typeVec.push_back(boxedType->GetModifiedElementType());
  1053. AddGenericArgs(mangleContext, name, typeVec);
  1054. name += '@';
  1055. }
  1056. else
  1057. {
  1058. auto typeDef = newNameSub.mTypeInst->mTypeDef;
  1059. BfGenericTypeInstance* genericTypeInst = NULL;
  1060. if (newNameSub.mTypeInst->IsGenericTypeInstance())
  1061. genericTypeInst = (BfGenericTypeInstance*)newNameSub.mTypeInst;
  1062. int numOuterGenericParams = 0;
  1063. if ((!mangleContext.mIsSafeMangle) && (typeDef->mOuterType != NULL))
  1064. {
  1065. numOuterGenericParams = (int)typeDef->mOuterType->mGenericParamDefs.size();
  1066. }
  1067. if (genericTypeInst != NULL)
  1068. {
  1069. // If we don't have our own generic params then don't treat us as a generic
  1070. if ((int)typeDef->mGenericParamDefs.size() == numOuterGenericParams)
  1071. genericTypeInst = NULL;
  1072. }
  1073. if (genericTypeInst != NULL)
  1074. {
  1075. name += "?$";
  1076. mangleContext.mWantsGroupStart = false;
  1077. }
  1078. // name += *typeDef->mName->mString;
  1079. // if ((typeDef->mIsDelegate) && (newNameSub.mTypeInst->IsClosure()))
  1080. // {
  1081. // auto closureType = (BfClosureType*)newNameSub.mTypeInst;
  1082. // if (!closureType->mCreatedTypeDef)
  1083. // name += closureType->mNameAdd;
  1084. // }
  1085. if (newNameSub.mTypeInst->IsClosure())
  1086. {
  1087. auto closureType = (BfClosureType*)newNameSub.mTypeInst;
  1088. name += closureType->mSrcDelegate->mTypeDef->mName->mString;
  1089. name += closureType->mNameAdd;
  1090. }
  1091. else
  1092. {
  1093. name += typeDef->mName->mString;
  1094. }
  1095. name += '@';
  1096. if (genericTypeInst != NULL)
  1097. {
  1098. AddGenericArgs(mangleContext, name, genericTypeInst->mTypeGenericArguments, numOuterGenericParams);
  1099. name += '@';
  1100. }
  1101. }
  1102. }
  1103. else if (newNameSub.mKind == BfGNUMangler::NameSubstitute::Kind_GenericParam)
  1104. {
  1105. name += "U"; // Struct
  1106. auto genericParamType = (BfGenericParamType*)newNameSub.mType;
  1107. if (genericParamType->mGenericParamKind == BfGenericParamKind_Method)
  1108. name += "_M";
  1109. else
  1110. name += "_T";
  1111. char str[16];
  1112. itoa(genericParamType->mGenericParamIdx, str, 10);
  1113. name += str;
  1114. name += '@';
  1115. name += '@';
  1116. }
  1117. mangleContext.mSubstituteList.push_back(newNameSub);
  1118. return false;
  1119. }
  1120. void BfMSMangler::Mangle(MangleContext& mangleContext, StringImpl& name, BfTypeInstance* typeInstance, bool isAlreadyStarted, bool isOuterType)
  1121. {
  1122. BfGenericTypeInstance* genericTypeInst = NULL;
  1123. if (typeInstance->IsGenericTypeInstance())
  1124. {
  1125. genericTypeInst = (BfGenericTypeInstance*)typeInstance;
  1126. }
  1127. auto typeDef = typeInstance->mTypeDef;
  1128. bool hasNamespace = typeDef->mNamespace.mSize != 0;
  1129. if (!isAlreadyStarted)
  1130. {
  1131. if ((hasNamespace) || (typeDef->mOuterType != NULL))
  1132. {
  1133. AddTypeStart(mangleContext, name, typeInstance);
  1134. }
  1135. else
  1136. {
  1137. if (typeDef->IsGlobalsContainer())
  1138. return;
  1139. mangleContext.mWantsGroupStart = true;
  1140. }
  1141. }
  1142. if (!typeDef->IsGlobalsContainer())
  1143. FindOrCreateNameSub(mangleContext, name, NameSubstitute(BfMangler::NameSubstitute::Kind_TypeInstName, typeInstance));
  1144. mangleContext.mWantsGroupStart = false;
  1145. auto useModule = typeInstance->mModule;
  1146. if (useModule == NULL)
  1147. useModule = mangleContext.mModule;
  1148. if ((typeDef->mOuterType != NULL) && (!typeInstance->IsBoxed()))
  1149. {
  1150. if (mangleContext.mIsSafeMangle)
  1151. {
  1152. auto outerType = typeDef->mOuterType;
  1153. while (outerType != NULL)
  1154. {
  1155. name += ":";
  1156. name += outerType->mFullName.ToString();
  1157. outerType = outerType->mOuterType;
  1158. }
  1159. }
  1160. else
  1161. {
  1162. auto outerType = useModule->GetOuterType(typeInstance);
  1163. Mangle(mangleContext, name, outerType, true, true);
  1164. }
  1165. }
  1166. if (!isOuterType)
  1167. {
  1168. if (!typeInstance->IsBoxed())
  1169. {
  1170. for (int namespaceIdx = (int)typeDef->mNamespace.mSize - 1; namespaceIdx >= 0; namespaceIdx--)
  1171. {
  1172. auto namePart = typeDef->mNamespace.mParts[namespaceIdx];
  1173. FindOrCreateNameSub(mangleContext, name, NameSubstitute(BfMangler::NameSubstitute::Kind_NamespaceAtom, namePart));
  1174. }
  1175. FindOrCreateNameSub(mangleContext, name, NameSubstitute(BfMangler::NameSubstitute::Kind_NamespaceAtom, useModule->mSystem->mBfAtom));
  1176. }
  1177. name += '@';
  1178. }
  1179. }
  1180. void BfMSMangler::MangleConst(MangleContext & mangleContext, StringImpl & name, int64 val)
  1181. {
  1182. name += "$0";
  1183. if (val < 0)
  1184. {
  1185. name += "?";
  1186. val = -val;
  1187. }
  1188. if ((val > 0) && (val <= 10))
  1189. {
  1190. name += (char)('0' + val - 1);
  1191. }
  1192. else
  1193. {
  1194. char str[64];
  1195. char* strP = str + 63;
  1196. *strP = 0;
  1197. while (val > 0)
  1198. {
  1199. *(--strP) = (char)((val % 0x10) + 'A');
  1200. val /= 0x10;
  1201. }
  1202. name += strP;
  1203. name += '@';
  1204. }
  1205. }
  1206. void BfMSMangler::AddPrefix(MangleContext& mangleContext, StringImpl& name, int startIdx, const char* prefix)
  1207. {
  1208. int subIdx;
  1209. char startChar = name[startIdx];
  1210. if ((startChar >= '0') && (startChar <= '9'))
  1211. {
  1212. //subIdx = ParseSubIdx(name, startIdx);
  1213. subIdx = startChar - '0';
  1214. for (int matchIdx = subIdx + 1; matchIdx < (int)mangleContext.mSubstituteList.size(); matchIdx++)
  1215. {
  1216. auto& entry = mangleContext.mSubstituteList[matchIdx];
  1217. if ((entry.mKind == NameSubstitute::Kind_Prefix) && (entry.mExtendsIdx == subIdx) && (entry.mPrefix == prefix))
  1218. {
  1219. BF_ASSERT(name.EndsWith('_'));
  1220. name.RemoveToEnd(startIdx);
  1221. AddSubIdx(name, matchIdx);
  1222. return;
  1223. }
  1224. }
  1225. }
  1226. else
  1227. {
  1228. //auto typeCode = GetPrimTypeAt(mangleContext, name, startIdx);
  1229. auto typeCode = BfTypeCode_None;
  1230. if (typeCode != (BfTypeCode)-1)
  1231. {
  1232. for (int matchIdx = 0; matchIdx < (int)mangleContext.mSubstituteList.size(); matchIdx++)
  1233. {
  1234. auto& entry = mangleContext.mSubstituteList[matchIdx];
  1235. if ((entry.mKind == NameSubstitute::Kind_PrimitivePrefix) && (entry.mExtendsTypeCode == typeCode) && (entry.mPrefix == prefix))
  1236. {
  1237. name.RemoveToEnd(startIdx);
  1238. AddSubIdx(name, matchIdx);
  1239. return;
  1240. }
  1241. }
  1242. NameSubstitute nameSub;
  1243. nameSub.mKind = NameSubstitute::Kind_PrimitivePrefix;
  1244. nameSub.mExtendsTypeCode = typeCode;
  1245. nameSub.mPrefix = prefix;
  1246. mangleContext.mSubstituteList.push_back(nameSub);
  1247. name.Insert(startIdx, prefix);
  1248. return;
  1249. }
  1250. else
  1251. {
  1252. // Applies to last-added one
  1253. subIdx = (int)mangleContext.mSubstituteList.size() - 1;
  1254. BF_ASSERT(isdigit(startChar) || (startChar == 'N') || (startChar == 'P') || (startChar == 'R'));
  1255. }
  1256. }
  1257. NameSubstitute nameSub;
  1258. nameSub.mKind = NameSubstitute::Kind_Prefix;
  1259. nameSub.mExtendsIdx = subIdx;
  1260. nameSub.mPrefix = prefix;
  1261. mangleContext.mSubstituteList.push_back(nameSub);
  1262. name.Insert(startIdx, prefix);
  1263. }
  1264. void BfMSMangler::Mangle(MangleContext& mangleContext, StringImpl& name, BfType* type, bool useTypeList)
  1265. {
  1266. bool isLongPrim = false;
  1267. if (type->IsPrimitiveType())
  1268. {
  1269. auto primType = (BfPrimitiveType*)type;
  1270. switch (primType->mTypeDef->mTypeCode)
  1271. {
  1272. case BfTypeCode_NullPtr:
  1273. {
  1274. name += "P";
  1275. if (mangleContext.mIs64Bit)
  1276. name += "E";
  1277. name += "AV";
  1278. name += "v";
  1279. }
  1280. return;
  1281. case BfTypeCode_None:
  1282. name += "X"; return;
  1283. case BfTypeCode_Dot:
  1284. name += "Tdot@@"; return;
  1285. case BfTypeCode_Var:
  1286. if ((mangleContext.mCCompat) || (mangleContext.mInArgs))
  1287. name += "X";
  1288. else
  1289. name += "Tvar@@";
  1290. return;
  1291. case BfTypeCode_Self:
  1292. if ((mangleContext.mCCompat) || (mangleContext.mInArgs))
  1293. name += "X";
  1294. else
  1295. name += "Tself@@";
  1296. return;
  1297. case BfTypeCode_Int8:
  1298. name += "C"; return;
  1299. case BfTypeCode_UInt8:
  1300. name += "E"; return;
  1301. case BfTypeCode_Int16:
  1302. name += "F"; return;
  1303. case BfTypeCode_UInt16:
  1304. name += "G"; return;
  1305. case BfTypeCode_Int32:
  1306. name += "H"; return;
  1307. case BfTypeCode_UInt32:
  1308. name += "I"; return;
  1309. case BfTypeCode_Char8:
  1310. name += "D"; return;
  1311. case BfTypeCode_Char16:
  1312. name += "_S"; return; //char16_t
  1313. case BfTypeCode_Single:
  1314. name += "M"; return;
  1315. case BfTypeCode_Double:
  1316. name += "N"; return;
  1317. case BfTypeCode_Int64:
  1318. case BfTypeCode_UInt64:
  1319. case BfTypeCode_Boolean:
  1320. case BfTypeCode_Char32:
  1321. isLongPrim = true;
  1322. break;
  1323. case BfTypeCode_IntPtr:
  1324. if ((primType->mSize == 4) && (mangleContext.mCCompat))
  1325. {
  1326. name += "H";
  1327. return;
  1328. }
  1329. isLongPrim = true;
  1330. break;
  1331. case BfTypeCode_UIntPtr:
  1332. if ((primType->mSize == 4) && (mangleContext.mCCompat))
  1333. {
  1334. name += "I";
  1335. return;
  1336. }
  1337. isLongPrim = true;
  1338. break;
  1339. default:
  1340. name += "?"; return;
  1341. }
  1342. }
  1343. if (useTypeList)
  1344. {
  1345. for (int checkIdx = 0; checkIdx < (int)mangleContext.mSubstituteTypeList.size(); checkIdx++)
  1346. {
  1347. if (mangleContext.mSubstituteTypeList[checkIdx] == type)
  1348. {
  1349. name += ('0' + checkIdx);
  1350. return;
  1351. }
  1352. }
  1353. }
  1354. if (isLongPrim)
  1355. {
  1356. auto primType = (BfPrimitiveType*)type;
  1357. switch (primType->mTypeDef->mTypeCode)
  1358. {
  1359. case BfTypeCode_Boolean:
  1360. name += "_N"; break;
  1361. case BfTypeCode_Int64:
  1362. name += "_J"; break;
  1363. case BfTypeCode_UInt64:
  1364. name += "_K"; break;
  1365. case BfTypeCode_UIntPtr:
  1366. if (primType->mSize == 4)
  1367. name += "_I";
  1368. else if (mangleContext.mCCompat)
  1369. name += "_K";
  1370. else
  1371. name += "Tuint@@";
  1372. break;
  1373. case BfTypeCode_IntPtr:
  1374. if (primType->mSize == 4)
  1375. name += "_H";
  1376. else if (mangleContext.mCCompat)
  1377. name += "_J";
  1378. else
  1379. name += "Tint@@";
  1380. break;
  1381. case BfTypeCode_Char32:
  1382. name += "_U"; break;
  1383. default: break;
  1384. }
  1385. }
  1386. else if (type->IsTypeInstance())
  1387. {
  1388. auto typeInstance = (BfTypeInstance*)type;
  1389. auto typeDef = typeInstance->mTypeDef;
  1390. if (type->IsObjectOrInterface())
  1391. {
  1392. name += "P";
  1393. if (mangleContext.mIs64Bit)
  1394. name += "E";
  1395. name += "A";
  1396. }
  1397. else if (((type->IsGenericTypeInstance()) || (type->IsTuple()) || (type->IsEnum())) && (mangleContext.mInRet))
  1398. name += "?A";
  1399. Mangle(mangleContext, name, typeInstance, false);
  1400. }
  1401. else if (type->IsGenericParam())
  1402. {
  1403. FindOrCreateNameSub(mangleContext, name, NameSubstitute(BfMangler::NameSubstitute::Kind_GenericParam, type));
  1404. }
  1405. else if (type->IsPointer())
  1406. {
  1407. auto pointerType = (BfPointerType*)type;
  1408. const char* strAdd = mangleContext.mIs64Bit ? "PEA" : "PA";
  1409. //if (!FindOrCreateNameSub(mangleContext, name, NameSubstitute(BfMangler::NameSubstitute::Kind_Prefix, strAdd, pointerType->mTypeId)))
  1410. {
  1411. name += strAdd;
  1412. Mangle(mangleContext, name, pointerType->mElementType);
  1413. }
  1414. }
  1415. else if (type->IsRef())
  1416. {
  1417. auto refType = (BfRefType*)type;
  1418. name += "A";
  1419. if (mangleContext.mIs64Bit)
  1420. name += "E";
  1421. name += "A";
  1422. if (refType->mRefKind == BfRefType::RefKind_Mut)
  1423. name += "mut$";
  1424. else if (refType->mRefKind == BfRefType::RefKind_Out)
  1425. name += "out$";
  1426. Mangle(mangleContext, name, refType->mElementType);
  1427. }
  1428. else if (type->IsRetTypeType())
  1429. {
  1430. auto retType = (BfRetTypeType*)type;
  1431. name += "rettype$";
  1432. Mangle(mangleContext, name, retType->mElementType);
  1433. }
  1434. else if (type->IsConcreteInterfaceType())
  1435. {
  1436. auto concreteType = (BfConcreteInterfaceType*)type;
  1437. name += "concrete$";
  1438. Mangle(mangleContext, name, concreteType->mInterface);
  1439. }
  1440. else if (type->IsSizedArray())
  1441. {
  1442. if (type->IsUnknownSizedArray())
  1443. {
  1444. auto arrType = (BfUnknownSizedArrayType*)type;
  1445. name += StrFormat("arr_$", arrType->mSize);
  1446. Mangle(mangleContext, name, arrType->mElementType);
  1447. name += "$";
  1448. Mangle(mangleContext, name, arrType->mElementCountSource);
  1449. }
  1450. else
  1451. {
  1452. // We can't use MS mangling of "_O" because it isn't size-specific
  1453. auto arrType = (BfSizedArrayType*)type;
  1454. //name += StrFormat("arr_%d$", arrType->mSize);
  1455. //Mangle(mangleContext, name, arrType->mElementType);
  1456. name += "?$_ARRAY@";
  1457. Mangle(mangleContext, name, arrType->mElementType);
  1458. MangleConst(mangleContext, name, arrType->mSize);
  1459. name += '@';
  1460. }
  1461. }
  1462. else if (type->IsMethodRef())
  1463. {
  1464. auto methodRefType = (BfMethodRefType*)type;
  1465. name += "Tmref_";
  1466. StringT<128> mangleName;
  1467. BfMethodInstance* methodInstance = methodRefType->mMethodRef;
  1468. if (methodInstance == NULL)
  1469. {
  1470. BF_ASSERT(!methodRefType->mMangledMethodName.IsEmpty());
  1471. mangleName = methodRefType->mMangledMethodName;
  1472. }
  1473. else
  1474. {
  1475. if (methodInstance->mIsAutocompleteMethod)
  1476. name += "AUTOCOMPLETE";
  1477. auto module = methodInstance->GetOwner()->mModule;
  1478. if (module->mCompiler->mIsResolveOnly)
  1479. {
  1480. // There are cases where we will reprocess a method in ResolveOnly for things like
  1481. // GetSymbolReferences, so we will have duplicate live local methodInstances in those cases
  1482. name += HashEncode64((uint64)methodRefType->mMethodRef);
  1483. }
  1484. else
  1485. {
  1486. Mangle(mangleName, mangleContext.mIs64Bit, methodInstance);
  1487. methodRefType->mMangledMethodName = mangleName;
  1488. }
  1489. }
  1490. if (!mangleName.IsEmpty())
  1491. {
  1492. Val128 val128 = Hash128(mangleName.c_str(), (int)mangleName.length());
  1493. name += HashEncode128(val128);
  1494. }
  1495. // if (methodInstance->mIsAutocompleteMethod)
  1496. // name += "AUTOCOMPLETE";
  1497. //
  1498. // String mangleAdd = Mangle(mangleContext.mIs64Bit, methodInstance);
  1499. //
  1500. // auto module = methodInstance->GetOwner()->mModule;
  1501. // if (module->mCompiler->mIsResolveOnly)
  1502. // {
  1503. // // There are cases where we will reprocess a method in ResolveOnly for things like
  1504. // // GetSymbolReferences, so we will have duplicate live local methodInstances in those cases
  1505. // name += HashEncode64((uint64)methodRefType->mMethodRef);
  1506. // }
  1507. // else
  1508. // {
  1509. // Val128 val128 = Hash128(mangleAdd.c_str(), (int)mangleAdd.length());
  1510. // name += HashEncode128(val128);
  1511. // }
  1512. name += "@@";
  1513. }
  1514. else if (type->IsConstExprValue())
  1515. {
  1516. BfConstExprValueType* constExprValueType = (BfConstExprValueType*)type;
  1517. int64 val = constExprValueType->mValue.mInt64;
  1518. if ((!constExprValueType->mType->IsPrimitiveType()) ||
  1519. (((BfPrimitiveType*)constExprValueType->mType)->mTypeDef->mTypeCode != BfTypeCode_IntPtr))
  1520. {
  1521. Mangle(mangleContext, name, constExprValueType->mType);
  1522. name += "$";
  1523. }
  1524. MangleConst(mangleContext, name, val);
  1525. }
  1526. else
  1527. {
  1528. BF_ASSERT("Unhandled");
  1529. }
  1530. if ((useTypeList) && (!mangleContext.mInRet) && ((int)mangleContext.mSubstituteTypeList.size() < 10))
  1531. mangleContext.mSubstituteTypeList.push_back(type);
  1532. }
  1533. void BfMSMangler::Mangle(StringImpl& name, bool is64Bit, BfType* type, BfModule* module)
  1534. {
  1535. if (type->IsTypeAlias())
  1536. {
  1537. auto typeAlias = (BfTypeAliasType*)type;
  1538. name += "__ALIAS_";
  1539. name += typeAlias->mTypeDef->mName->ToString();
  1540. name += '@';
  1541. Mangle(name, is64Bit, typeAlias->mAliasToType, module);
  1542. return;
  1543. }
  1544. MangleContext mangleContext;
  1545. mangleContext.mIs64Bit = is64Bit;
  1546. mangleContext.mModule = module;
  1547. auto typeInst = type->ToTypeInstance();
  1548. if ((typeInst != NULL) && (typeInst->mModule != NULL))
  1549. mangleContext.mModule = typeInst->mModule;
  1550. if (typeInst != NULL)
  1551. Mangle(mangleContext, name, typeInst, true);
  1552. else
  1553. Mangle(mangleContext, name, type);
  1554. while ((name.length() > 0) && (name[name.length() - 1] == '@'))
  1555. name.Remove(name.length() - 1);
  1556. }
  1557. void BfMSMangler::Mangle(StringImpl& name, bool is64Bit, BfMethodInstance* methodInst)
  1558. {
  1559. static int mangleIdx = 0;
  1560. mangleIdx++;
  1561. if ((methodInst->mMethodDef->mCLink) && (!methodInst->mMangleWithIdx))
  1562. {
  1563. name += methodInst->mMethodDef->mName;
  1564. return;
  1565. }
  1566. auto methodDef = methodInst->mMethodDef;
  1567. auto typeInst = methodInst->GetOwner();
  1568. auto typeDef = typeInst->mTypeDef;
  1569. MangleContext mangleContext;
  1570. mangleContext.mIs64Bit = is64Bit;
  1571. mangleContext.mModule = methodInst->GetOwner()->mModule;
  1572. mangleContext.mCCompat = methodInst->mMethodDef->mIsExtern;
  1573. auto customAttributes = methodInst->GetCustomAttributes();
  1574. if (customAttributes != NULL)
  1575. {
  1576. auto linkNameAttr = customAttributes->Get(typeInst->mModule->mCompiler->mLinkNameAttributeTypeDef);
  1577. if (linkNameAttr != NULL)
  1578. {
  1579. if (linkNameAttr->mCtorArgs.size() == 1)
  1580. {
  1581. if (typeInst->mModule->TryGetConstString(typeInst->mConstHolder, linkNameAttr->mCtorArgs[0], name))
  1582. return;
  1583. }
  1584. }
  1585. }
  1586. name += '?';
  1587. if (methodInst->GetNumGenericArguments() != 0)
  1588. {
  1589. name += "?$";
  1590. }
  1591. bool isSpecialFunc = false;
  1592. if (methodInst->mMethodDef->mIsOperator)
  1593. {
  1594. String methodName;
  1595. auto operatorDef = (BfOperatorDef*)methodInst->mMethodDef;
  1596. if (operatorDef->mOperatorDeclaration->mIsConvOperator)
  1597. {
  1598. name += "?B";
  1599. }
  1600. else
  1601. {
  1602. switch (operatorDef->mOperatorDeclaration->mBinOp)
  1603. {
  1604. case BfBinaryOp_Add:
  1605. name += "?H";
  1606. break;
  1607. case BfBinaryOp_Subtract:
  1608. name += "?G";
  1609. break;
  1610. case BfBinaryOp_Multiply:
  1611. name += "?D";
  1612. break;
  1613. case BfBinaryOp_Divide:
  1614. name += "?K";
  1615. break;
  1616. case BfBinaryOp_Modulus:
  1617. name += "?L";
  1618. break;
  1619. case BfBinaryOp_BitwiseAnd:
  1620. name += "?I";
  1621. break;
  1622. case BfBinaryOp_BitwiseOr:
  1623. name += "?U";
  1624. break;
  1625. case BfBinaryOp_ExclusiveOr:
  1626. name += "?T";
  1627. break;
  1628. case BfBinaryOp_LeftShift:
  1629. name += "?6";
  1630. break;
  1631. case BfBinaryOp_RightShift:
  1632. name += "?5";
  1633. break;
  1634. case BfBinaryOp_Equality:
  1635. name += "?8";
  1636. break;
  1637. case BfBinaryOp_InEquality:
  1638. name += "?9";
  1639. break;
  1640. case BfBinaryOp_GreaterThan:
  1641. name += "?O";
  1642. break;
  1643. case BfBinaryOp_LessThan:
  1644. name += "?M";
  1645. break;
  1646. case BfBinaryOp_GreaterThanOrEqual:
  1647. name += "?P";
  1648. break;
  1649. case BfBinaryOp_LessThanOrEqual:
  1650. name += "?N";
  1651. break;
  1652. case BfBinaryOp_Compare:
  1653. name += "__cmp__";
  1654. break;
  1655. case BfBinaryOp_ConditionalAnd:
  1656. name += "?V";
  1657. break;
  1658. case BfBinaryOp_ConditionalOr:
  1659. name += "?W";
  1660. break;
  1661. case BfBinaryOp_NullCoalesce:
  1662. methodName = "__nc__";
  1663. break;
  1664. case BfBinaryOp_Is:
  1665. methodName = "__is__";
  1666. break;
  1667. case BfBinaryOp_As:
  1668. methodName = "__as__";
  1669. break;
  1670. default: break;
  1671. }
  1672. switch (operatorDef->mOperatorDeclaration->mUnaryOp)
  1673. {
  1674. case BfUnaryOp_AddressOf:
  1675. name += "?I";
  1676. break;
  1677. case BfUnaryOp_Dereference:
  1678. name += "?D";
  1679. break;
  1680. case BfUnaryOp_Negate:
  1681. name += "?G";
  1682. break;
  1683. case BfUnaryOp_Not:
  1684. name += "?7";
  1685. break;
  1686. case BfUnaryOp_Positive:
  1687. name += "?H";
  1688. break;
  1689. case BfUnaryOp_InvertBits:
  1690. name += "?S";
  1691. break;
  1692. case BfUnaryOp_Increment:
  1693. name += "?E";
  1694. break;
  1695. case BfUnaryOp_Decrement:
  1696. name += "?F";
  1697. break;
  1698. case BfUnaryOp_PostIncrement:
  1699. methodName = "__pi__";
  1700. break;
  1701. case BfUnaryOp_PostDecrement:
  1702. methodName = "__pd__";
  1703. break;
  1704. case BfUnaryOp_Ref:
  1705. methodName = "__ref__";
  1706. break;
  1707. case BfUnaryOp_Out:
  1708. methodName = "__out__";
  1709. break;
  1710. default: break;
  1711. }
  1712. switch (operatorDef->mOperatorDeclaration->mAssignOp)
  1713. {
  1714. case BfAssignmentOp_Assign:
  1715. methodName += "__a__";
  1716. break;
  1717. case BfAssignmentOp_Add:
  1718. methodName += "__a_add__";
  1719. break;
  1720. case BfAssignmentOp_Subtract:
  1721. methodName += "__a_sub__";
  1722. break;
  1723. case BfAssignmentOp_Multiply:
  1724. methodName += "__a_mul__";
  1725. break;
  1726. case BfAssignmentOp_Divide:
  1727. methodName += "__a_div__";
  1728. break;
  1729. case BfAssignmentOp_Modulus:
  1730. methodName += "__a_mod__";
  1731. break;
  1732. case BfAssignmentOp_ShiftLeft:
  1733. methodName += "__a_shl__";
  1734. break;
  1735. case BfAssignmentOp_ShiftRight:
  1736. methodName += "__a_shr__";
  1737. break;
  1738. case BfAssignmentOp_BitwiseAnd:
  1739. methodName += "__a_bwa__";
  1740. break;
  1741. case BfAssignmentOp_BitwiseOr:
  1742. methodName += "__a_bwo__";
  1743. break;
  1744. case BfAssignmentOp_ExclusiveOr:
  1745. methodName += "__a_xor__";
  1746. break;
  1747. default: break;
  1748. }
  1749. }
  1750. if (!methodName.empty())
  1751. {
  1752. AddStr(mangleContext, name, methodName);
  1753. }
  1754. }
  1755. /*else if ((methodDef->mMethodType == BfMethodType_Ctor) && (!methodDef->mIsStatic))
  1756. {
  1757. isSpecialFunc = true;
  1758. name += "?0";
  1759. //AddAtomStr(mangleContext, name, typeDef->mName);
  1760. }
  1761. else if ((methodDef->mMethodType == BfMethodType_Dtor) && (!methodDef->mIsStatic))
  1762. {
  1763. isSpecialFunc = true;
  1764. name += "?1";
  1765. //AddAtomStr(mangleContext, name, typeDef->mName);
  1766. }*/
  1767. else if (methodInst->GetNumGenericArguments() != 0)
  1768. {
  1769. AddStr(mangleContext, name, methodDef->mName);
  1770. AddGenericArgs(mangleContext, name, methodInst->mMethodInfoEx->mMethodGenericArguments);
  1771. name += '@';
  1772. }
  1773. else
  1774. {
  1775. AddStr(mangleContext, name, methodDef->mName);
  1776. }
  1777. if ((methodInst->mMethodDef->mDeclaringType->mPartialIdx != -1) && (!methodInst->mIsForeignMethodDef))
  1778. {
  1779. auto declType = methodInst->mMethodDef->mDeclaringType;
  1780. BF_ASSERT(methodInst->GetOwner()->mTypeDef->mIsCombinedPartial);
  1781. auto declProject = declType->mProject;
  1782. bool addProjectName = (declProject != typeInst->mTypeDef->mProject);
  1783. bool addIndex = true;
  1784. if (typeInst->mTypeDef->IsGlobalsContainer())
  1785. {
  1786. addProjectName = true;
  1787. if ((methodInst->mMethodDef->mCallingConvention == BfCallingConvention_Cdecl) ||
  1788. (methodInst->mMethodDef->mCallingConvention == BfCallingConvention_Stdcall))
  1789. {
  1790. addProjectName = false;
  1791. addIndex = false;
  1792. }
  1793. }
  1794. if (addProjectName)
  1795. {
  1796. name += declProject->mName;
  1797. name += '$';
  1798. }
  1799. if (addIndex)
  1800. name += StrFormat("%d$", declType->mPartialIdx);
  1801. }
  1802. if (methodInst->mMangleWithIdx)
  1803. name += StrFormat("i%d$", methodInst->mMethodDef->mIdx);
  1804. if (methodDef->mCheckedKind == BfCheckedKind_Checked)
  1805. name += "CHK$";
  1806. else if (methodDef->mCheckedKind == BfCheckedKind_Unchecked)
  1807. name += "UCHK$";
  1808. /*if ((methodInst->mMethodInstanceGroup->mOwner->mTypeDef->IsGlobalsContainer()) && (methodInst->mMethodDef->mMethodDeclaration == NULL))
  1809. {
  1810. name += methodInst->mMethodInstanceGroup->mOwner->mTypeDef->mProject->mName;
  1811. name += "$";
  1812. }*/
  1813. if (methodInst->GetForeignType() != NULL)
  1814. Mangle(mangleContext, name, methodInst->GetForeignType(), true);
  1815. if (methodInst->GetExplicitInterface() != NULL)
  1816. Mangle(mangleContext, name, methodInst->GetExplicitInterface(), true);
  1817. Mangle(mangleContext, name, methodInst->GetOwner(), true);
  1818. /*bool isCppDecl = false;
  1819. if (!isCppDecl)
  1820. {
  1821. if (name.EndsWith("@"))
  1822. name.Remove(name.length() - 1);
  1823. FindOrCreateNameSub(mangleContext, name, NameSubstitute(BfMangler::NameSubstitute::Kind_NamespaceAtom, typeInst->mModule->mSystem->mBfAtom));
  1824. name += '@';
  1825. }*/
  1826. //QEA AXXZ
  1827. char attrib ='A';
  1828. if (methodDef->mProtection == BfProtection_Protected)
  1829. attrib = 'I';
  1830. else if (methodDef->mProtection == BfProtection_Public)
  1831. attrib = 'Q';
  1832. bool doExplicitThis = (!methodDef->mIsStatic) && (typeInst->IsTypedPrimitive());
  1833. if ((methodDef->mIsStatic) || (doExplicitThis))
  1834. attrib += 2;
  1835. attrib += (methodDef->mIsVirtual ? 4 : 0);
  1836. name += attrib;
  1837. auto bfSystem = methodInst->GetOwner()->mModule->mSystem;
  1838. if ((!methodDef->mIsStatic) && (!doExplicitThis))
  1839. {
  1840. /*char cvQualifier = 'A';
  1841. if (mangleContext.mIs64Bit)
  1842. cvQualifier = 'E';
  1843. name += cvQualifier;*/
  1844. if (mangleContext.mIs64Bit)
  1845. name += "E";
  1846. char qualifier = 'A'; // const / volatile
  1847. name += qualifier;
  1848. }
  1849. char callingConv = 'A';
  1850. if (methodDef->mCallingConvention == BfCallingConvention_Stdcall)
  1851. callingConv = 'G';
  1852. else if ((!mangleContext.mIs64Bit) && (!methodDef->mIsStatic))
  1853. callingConv = 'E';
  1854. name += callingConv;
  1855. if (isSpecialFunc)
  1856. name += '@';
  1857. //
  1858. if (!isSpecialFunc)
  1859. {
  1860. mangleContext.mInRet = true;
  1861. Mangle(mangleContext, name, methodInst->mReturnType);
  1862. mangleContext.mInRet = false;
  1863. }
  1864. if ((methodInst->mParams.size() == 0) && (!doExplicitThis))
  1865. {
  1866. name += 'X';
  1867. }
  1868. else
  1869. {
  1870. // Is this right?
  1871. if (methodInst->GetNumGenericArguments() != 0)
  1872. mangleContext.mSubstituteList.clear();
  1873. mangleContext.mInArgs = true;
  1874. if (doExplicitThis)
  1875. {
  1876. Mangle(mangleContext, name, typeInst->GetUnderlyingType(), true);
  1877. }
  1878. for (auto& param : methodInst->mParams)
  1879. Mangle(mangleContext, name, param.mResolvedType, true);
  1880. name += '@';
  1881. }
  1882. name += 'Z';
  1883. bool wantLog = false;
  1884. if (wantLog)
  1885. {
  1886. BfLog2("Mangling #%d : %s -> %s\n", mangleIdx, mangleContext.mModule->MethodToString(methodInst).c_str(), name.c_str());
  1887. if (!methodInst->mIsUnspecialized)
  1888. {
  1889. String demangled = BfDemangler::Demangle(name, DbgLanguage_Beef);
  1890. BfLog2(" Demangled %d: %s\n", mangleIdx, demangled.c_str());
  1891. }
  1892. }
  1893. }
  1894. void BfMSMangler::Mangle(StringImpl& name, bool is64Bit, BfFieldInstance* fieldInstance)
  1895. {
  1896. auto fieldDef = fieldInstance->GetFieldDef();
  1897. if (fieldDef->mFieldDeclaration != NULL)
  1898. {
  1899. auto module = fieldInstance->mOwner->mModule;
  1900. if ((fieldInstance->mCustomAttributes != NULL) && (fieldInstance->mCustomAttributes->Contains(module->mCompiler->mCLinkAttributeTypeDef)))
  1901. {
  1902. name += fieldDef->mName;
  1903. return;
  1904. }
  1905. }
  1906. BF_ASSERT(fieldDef->mIsStatic);
  1907. MangleContext mangleContext;
  1908. mangleContext.mIs64Bit = is64Bit;
  1909. mangleContext.mModule = fieldInstance->mOwner->mModule;
  1910. name += '?';
  1911. AddStr(mangleContext, name, fieldDef->mName);
  1912. Mangle(mangleContext, name, fieldInstance->mOwner, true);
  1913. name += '2'; //TODO: Don't always mark as 'public'
  1914. Mangle(mangleContext, name, fieldInstance->mResolvedType);
  1915. name += ('A' + /*(fieldDef->mIsConst ? 1 : 0) +*/ (fieldDef->mIsVolatile ? 2 : 0));
  1916. }
  1917. void BfMSMangler::MangleMethodName(StringImpl& name, bool is64Bit, BfTypeInstance* type, const StringImpl& methodName)
  1918. {
  1919. MangleContext mangleContext;
  1920. mangleContext.mIs64Bit = is64Bit;
  1921. mangleContext.mModule = type->GetModule();
  1922. name += '?';
  1923. AddStr(mangleContext, name, methodName);
  1924. Mangle(mangleContext, name, type);
  1925. name += "@@";
  1926. }
  1927. void BfMSMangler::MangleStaticFieldName(StringImpl& name, bool is64Bit, BfTypeInstance* owner, const StringImpl& fieldName, BfType* fieldType)
  1928. {
  1929. MangleContext mangleContext;
  1930. mangleContext.mIs64Bit = is64Bit;
  1931. mangleContext.mModule = owner->GetModule();
  1932. name += '?';
  1933. AddStr(mangleContext, name, fieldName);
  1934. Mangle(mangleContext, name, owner, true);
  1935. //name += "@@";
  1936. name += '2'; // public
  1937. if (fieldType == NULL)
  1938. name += 'H';
  1939. else
  1940. Mangle(mangleContext, name, fieldType);
  1941. name += "A"; // static
  1942. }
  1943. //////////////////////////////////////////////////////////////////////////
  1944. String BfSafeMangler::Mangle(BfType* type, BfModule* module)
  1945. {
  1946. MangleContext mangleContext;
  1947. mangleContext.mIs64Bit = true;
  1948. mangleContext.mModule = module;
  1949. mangleContext.mIsSafeMangle = true;
  1950. auto typeInst = type->ToTypeInstance();
  1951. String name;
  1952. if (typeInst != NULL)
  1953. BfMSMangler::Mangle(mangleContext, name, typeInst, true);
  1954. else
  1955. BfMSMangler::Mangle(mangleContext, name, type);
  1956. return name;
  1957. }
  1958. //////////////////////////////////////////////////////////////////////////
  1959. void BfMangler::Mangle(StringImpl& outStr, MangleKind mangleKind, BfType* type, BfModule* module)
  1960. {
  1961. if (mangleKind == BfMangler::MangleKind_GNU)
  1962. outStr += BfGNUMangler::Mangle(type, module);
  1963. else
  1964. BfMSMangler::Mangle(outStr, mangleKind == BfMangler::MangleKind_Microsoft_64, type, module);
  1965. }
  1966. void BfMangler::Mangle(StringImpl& outStr, MangleKind mangleKind, BfMethodInstance* methodInst)
  1967. {
  1968. if (mangleKind == BfMangler::MangleKind_GNU)
  1969. outStr += BfGNUMangler::Mangle(methodInst);
  1970. else
  1971. BfMSMangler::Mangle(outStr, mangleKind == BfMangler::MangleKind_Microsoft_64, methodInst);
  1972. }
  1973. void BfMangler::Mangle(StringImpl& outStr, MangleKind mangleKind, BfFieldInstance* fieldInstance)
  1974. {
  1975. if (mangleKind == BfMangler::MangleKind_GNU)
  1976. outStr += BfGNUMangler::MangleStaticFieldName(fieldInstance->mOwner, fieldInstance->GetFieldDef()->mName);
  1977. else
  1978. BfMSMangler::Mangle(outStr, mangleKind == BfMangler::MangleKind_Microsoft_64, fieldInstance);
  1979. }
  1980. void BfMangler::MangleMethodName(StringImpl& outStr, MangleKind mangleKind, BfTypeInstance* type, const StringImpl& methodName)
  1981. {
  1982. if (mangleKind == BfMangler::MangleKind_GNU)
  1983. outStr += BfGNUMangler::MangleMethodName(type, methodName);
  1984. else
  1985. BfMSMangler::MangleMethodName(outStr, mangleKind == BfMangler::MangleKind_Microsoft_64, type, methodName);
  1986. }
  1987. void BfMangler::MangleStaticFieldName(StringImpl& outStr, MangleKind mangleKind, BfTypeInstance* type, const StringImpl& fieldName, BfType* fieldType)
  1988. {
  1989. if (mangleKind == BfMangler::MangleKind_GNU)
  1990. outStr += BfGNUMangler::MangleStaticFieldName(type, fieldName);
  1991. else
  1992. BfMSMangler::MangleStaticFieldName(outStr, mangleKind == BfMangler::MangleKind_Microsoft_64, type, fieldName, fieldType);
  1993. }