BfMangler.cpp 67 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460
  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_Float;
  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. BfTypeInstance* genericTypeInstance = (BfTypeInstance*)checkType;
  196. for (int genericParamIdx = genericParamStart; genericParamIdx < (int) typeDef->mGenericParamDefs.size(); genericParamIdx++)
  197. {
  198. auto genericParam = genericTypeInstance->mGenericTypeInfo->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. if (outerType != NULL)
  237. FindOrCreateNameSub(mangleContext, name, outerType, curMatchIdx, matchFailed);
  238. else
  239. useModule->Fail("Failed to mangle name in BfGNUMangler::FindOrCreateNameSub");
  240. }
  241. FindOrCreateNameSub(mangleContext, name, NameSubstitute(NameSubstitute::Kind_TypeInstName, typeInst), curMatchIdx, matchFailed);
  242. if (typeDef->mGenericParamDefs.size() != numOuterGenericParams)
  243. {
  244. FindOrCreateNameSub(mangleContext, name, NameSubstitute(NameSubstitute::Kind_TypeGenericArgs, typeInst), curMatchIdx, matchFailed);
  245. }
  246. }
  247. void BfGNUMangler::MangleTypeInst(MangleContext& mangleContext, StringImpl& name, BfTypeInstance* typeInst, BfTypeInstance* postfixTypeInstance, bool* isEndOpen)
  248. {
  249. static int sCallCount = 0;
  250. sCallCount++;
  251. if (typeInst->IsTuple())
  252. {
  253. auto tupleType = (BfTypeInstance*)typeInst;
  254. name += "N7__TUPLEI";
  255. mangleContext.mSubstituteList.push_back(NameSubstitute(BfGNUMangler::NameSubstitute::Kind_None, NULL)); // Insert entry for '__TUPLE'
  256. for (int fieldIdx = 0; fieldIdx < (int)tupleType->mFieldInstances.size(); fieldIdx++)
  257. {
  258. BfFieldInstance* fieldInstance = &tupleType->mFieldInstances[fieldIdx];
  259. BfFieldDef* fieldDef = fieldInstance->GetFieldDef();
  260. String fieldName = fieldDef->mName;
  261. if ((fieldName[0] < '0') || (fieldName[0] > '9'))
  262. name += StrFormat("U%d`%s", fieldName.length() + 1, fieldName.c_str());
  263. Mangle(mangleContext, name, fieldInstance->mResolvedType, postfixTypeInstance);
  264. }
  265. name += "E";
  266. mangleContext.mSubstituteList.push_back(NameSubstitute(BfGNUMangler::NameSubstitute::Kind_None, NULL)); // Insert entry for '__TUPLE<T>'
  267. if (isEndOpen != NULL)
  268. *isEndOpen = true;
  269. else
  270. name += "E";
  271. return;
  272. }
  273. else if ((typeInst->IsDelegateFromTypeRef()) || (typeInst->IsFunctionFromTypeRef()))
  274. {
  275. BF_ASSERT(typeInst->mTypeDef->mMethods[0]->mName == "Invoke");
  276. auto delegateInfo = typeInst->GetDelegateInfo();
  277. auto methodDef = typeInst->mTypeDef->mMethods[0];
  278. if (typeInst->IsDelegate())
  279. name += "N8delegateI";
  280. else
  281. name += "N8functionI";
  282. SizedArray<BfType*, 8> typeVec;
  283. typeVec.push_back(BfNodeDynCast<BfDirectTypeReference>(methodDef->mReturnTypeRef)->mType);
  284. if (methodDef->mIsMutating)
  285. name += "_mut_";
  286. if (delegateInfo->mCallingConvention == BfCallingConvention_Cdecl)
  287. name += "_cdecl_";
  288. else if (delegateInfo->mCallingConvention == BfCallingConvention_Stdcall)
  289. name += "_stdcall_";
  290. else if (delegateInfo->mCallingConvention == BfCallingConvention_Fastcall)
  291. name += "_fastcall_";
  292. for (int paramIdx = 0; paramIdx < (int)methodDef->mParams.size(); paramIdx++)
  293. {
  294. name += "_";
  295. name += methodDef->mParams[paramIdx]->mName;
  296. if (methodDef->mParams[paramIdx]->mParamKind == BfParamKind_VarArgs)
  297. {
  298. name += "__varargs";
  299. continue;
  300. }
  301. if (methodDef->mParams[paramIdx]->mParamKind == BfParamKind_Params)
  302. name += "_params_";
  303. typeVec.push_back(BfNodeDynCast<BfDirectTypeReference>(methodDef->mParams[paramIdx]->mTypeRef)->mType);
  304. }
  305. for (auto type : typeVec)
  306. Mangle(mangleContext, name, type, postfixTypeInstance);
  307. mangleContext.mSubstituteList.push_back(NameSubstitute(BfGNUMangler::NameSubstitute::Kind_None, NULL)); // Insert entry for 'Delegate'
  308. name += "E";
  309. mangleContext.mSubstituteList.push_back(NameSubstitute(BfGNUMangler::NameSubstitute::Kind_None, NULL)); // Insert entry for 'Delegate<T>'
  310. if (isEndOpen != NULL)
  311. *isEndOpen = true;
  312. else
  313. name += "E";
  314. name += "E";
  315. }
  316. else if (typeInst->IsBoxed())
  317. {
  318. auto boxedType = (BfBoxedType*)typeInst;
  319. name += "N3BoxI";
  320. mangleContext.mSubstituteList.push_back(NameSubstitute(BfGNUMangler::NameSubstitute::Kind_None, NULL)); // Insert entry for 'Box'
  321. Mangle(mangleContext, name, boxedType->GetModifiedElementType(), postfixTypeInstance);
  322. name += "E";
  323. mangleContext.mSubstituteList.push_back(NameSubstitute(BfGNUMangler::NameSubstitute::Kind_None, NULL)); // Insert entry for 'Box<T>'
  324. if (isEndOpen != NULL)
  325. *isEndOpen = true;
  326. else
  327. name += "E";
  328. return;
  329. }
  330. int curMatchIdx = -1;
  331. bool matchFailed = false;
  332. for (int typeIdx = 0; typeIdx < 2; typeIdx++)
  333. {
  334. BfTypeInstance* useTypeInst = typeInst;
  335. if (typeIdx == 1)
  336. {
  337. if (postfixTypeInstance == NULL)
  338. break;
  339. useTypeInst = postfixTypeInstance;
  340. }
  341. auto typeDef = useTypeInst->mTypeDef;
  342. if (!mangleContext.mCPPMangle)
  343. FindOrCreateNameSub(mangleContext, name, NameSubstitute(NameSubstitute::Kind_NamespaceAtom, typeInst->mModule->mSystem->mBfAtom), curMatchIdx, matchFailed);
  344. for (int i = 0; i < typeDef->mNamespace.mSize; i++)
  345. FindOrCreateNameSub(mangleContext, name, NameSubstitute(NameSubstitute::Kind_NamespaceAtom, typeDef->mNamespace.mParts[i]), curMatchIdx, matchFailed);
  346. FindOrCreateNameSub(mangleContext, name, useTypeInst, curMatchIdx, matchFailed);
  347. }
  348. if (isEndOpen != NULL)
  349. {
  350. if (!matchFailed)
  351. {
  352. if (curMatchIdx != -1)
  353. {
  354. name += "N";
  355. AddSubIdx(name, curMatchIdx);
  356. *isEndOpen = true;
  357. }
  358. else
  359. *isEndOpen = false;
  360. }
  361. else
  362. *isEndOpen = true;
  363. return;
  364. }
  365. if (matchFailed)
  366. {
  367. name += "E";
  368. }
  369. else
  370. {
  371. AddSubIdx(name, curMatchIdx);
  372. }
  373. }
  374. void BfGNUMangler::Mangle(MangleContext& mangleContext, StringImpl& name, BfType* type, BfType* postfixType, bool isConst)
  375. {
  376. static int sCallCount = 0;
  377. sCallCount++;
  378. if (type->IsPrimitiveType())
  379. {
  380. auto primType = (BfPrimitiveType*)type;
  381. switch (primType->mTypeDef->mTypeCode)
  382. {
  383. case BfTypeCode_NullPtr:
  384. {
  385. auto pointerType = (BfPointerType*)type;
  386. int startIdx = (int)name.length();
  387. name += "v";
  388. AddPrefix(mangleContext, name, startIdx, "P");
  389. }
  390. return;
  391. case BfTypeCode_Dot:
  392. name += "U3dot";
  393. return;
  394. case BfTypeCode_None:
  395. if ((mangleContext.mCCompat) || (mangleContext.mInArgs))
  396. name += "v";
  397. else
  398. name += "U4void";
  399. return;
  400. case BfTypeCode_Self:
  401. if ((mangleContext.mCCompat) || (mangleContext.mInArgs))
  402. name += "U8concrete";
  403. else
  404. name += "U4self";
  405. return;
  406. case BfTypeCode_Boolean:
  407. name += "b"; return;
  408. case BfTypeCode_Int8:
  409. name += "a"; return;
  410. case BfTypeCode_UInt8:
  411. name += "h"; return;
  412. case BfTypeCode_Int16:
  413. name += "s"; return;
  414. case BfTypeCode_UInt16:
  415. name += "t"; return;
  416. case BfTypeCode_Int32:
  417. name += "i"; return;
  418. case BfTypeCode_UInt32:
  419. name += "j"; return;
  420. case BfTypeCode_Int64:
  421. if ((mangleContext.mModule == NULL) || (mangleContext.mModule->mCompiler->mOptions.mCLongSize == 8))
  422. name += "l";
  423. else
  424. name += "x";
  425. return;
  426. case BfTypeCode_UInt64:
  427. if ((mangleContext.mModule == NULL) || (mangleContext.mModule->mCompiler->mOptions.mCLongSize == 8))
  428. name += "m";
  429. else
  430. name += "y";
  431. return;
  432. case BfTypeCode_UIntPtr:
  433. if ((mangleContext.mCCompat) || (mangleContext.mInArgs))
  434. {
  435. if ((mangleContext.mModule == NULL) || (mangleContext.mModule->mCompiler->mOptions.mCLongSize == 8))
  436. name += (primType->mSize == 8) ? "m" : "j";
  437. else
  438. name += (primType->mSize == 8) ? "y" : "j";
  439. return;
  440. }
  441. name += "u4uint";
  442. return;
  443. case BfTypeCode_IntPtr:
  444. if ((mangleContext.mCCompat) || (mangleContext.mInArgs))
  445. {
  446. if ((mangleContext.mModule == NULL) || (mangleContext.mModule->mCompiler->mOptions.mCLongSize == 8))
  447. name += (primType->mSize == 8) ? "l" : "i";
  448. else
  449. name += (primType->mSize == 8) ? "x" : "i";
  450. return;
  451. }
  452. name += "u3int";
  453. return;
  454. case BfTypeCode_Char8:
  455. name += "c"; return;
  456. case BfTypeCode_Char16:
  457. name += "Ds"; return;
  458. case BfTypeCode_Char32:
  459. name += "Di"; return;
  460. case BfTypeCode_Float:
  461. name += "f"; return;
  462. case BfTypeCode_Double:
  463. name += "d"; return;
  464. case BfTypeCode_Var:
  465. if ((mangleContext.mCCompat) || (mangleContext.mInArgs))
  466. name += "v";
  467. else
  468. name += "U3var";
  469. return;
  470. case BfTypeCode_Let:
  471. name += "U3let"; return;
  472. case BfTypeCode_IntUnknown:
  473. name += "U4iunk"; return;
  474. case BfTypeCode_UIntUnknown:
  475. name += "U4uunk"; return;
  476. default: break;
  477. }
  478. name += "?"; return;
  479. //name += Mangle(primType->mTypeDef, NULL, addName, NULL, substituteList);
  480. }
  481. else if (type->IsTypeInstance())
  482. {
  483. BfTypeInstance* postfixTypeInst = NULL;
  484. if (postfixType != NULL)
  485. postfixTypeInst = postfixType->ToTypeInstance();
  486. auto typeInstance = (BfTypeInstance*)type;
  487. int startIdx = (int)name.length();
  488. MangleTypeInst(mangleContext, name, typeInstance, postfixTypeInst);
  489. if ((type->IsObjectOrInterface()) && (mangleContext.mPrefixObjectPointer))
  490. AddPrefix(mangleContext, name, startIdx, "P");
  491. }
  492. else if (type->IsGenericParam())
  493. {
  494. FindOrCreateNameSub(mangleContext, name, NameSubstitute(NameSubstitute::Kind_GenericParam, type));
  495. }
  496. else if (type->IsPointer())
  497. {
  498. auto pointerType = (BfPointerType*)type;
  499. int startIdx = (int)name.length();
  500. Mangle(mangleContext, name, pointerType->mElementType);
  501. AddPrefix(mangleContext, name, startIdx, "P");
  502. return;
  503. }
  504. else if (type->IsRef())
  505. {
  506. BfRefType* refType = (BfRefType*)type;
  507. if (refType->mRefKind == BfRefType::RefKind_In)
  508. {
  509. isConst = true;
  510. }
  511. else if ((refType->mRefKind == BfRefType::RefKind_Mut) && (!mangleContext.mCCompat))
  512. {
  513. name += "U3mut";
  514. Mangle(mangleContext, name, refType->mElementType);
  515. return;
  516. }
  517. else if ((refType->mRefKind == BfRefType::RefKind_Out) && (!mangleContext.mCCompat))
  518. {
  519. name += "U3out";
  520. Mangle(mangleContext, name, refType->mElementType);
  521. return;
  522. }
  523. int startIdx = (int)name.length();
  524. Mangle(mangleContext, name, refType->mElementType);
  525. AddPrefix(mangleContext, name, startIdx, isConst ? "RK" : "R");
  526. return;
  527. }
  528. else if (type->IsModifiedTypeType())
  529. {
  530. BfModifiedTypeType* retTypeType = (BfModifiedTypeType*)type;
  531. if (retTypeType->mModifiedKind == BfToken_RetType)
  532. name += "U7rettype";
  533. else if (retTypeType->mModifiedKind == BfToken_AllocType)
  534. name += "U5alloc";
  535. else if (retTypeType->mModifiedKind == BfToken_Nullable)
  536. name += "U8nullable";
  537. else if (retTypeType->mModifiedKind == BfToken_Params)
  538. name += "U6params";
  539. else
  540. BF_FATAL("Unhandled");
  541. Mangle(mangleContext, name, retTypeType->mElementType);
  542. return;
  543. }
  544. else if (type->IsConcreteInterfaceType())
  545. {
  546. BfConcreteInterfaceType* concreteInterfaceType = (BfConcreteInterfaceType*)type;
  547. name += "U8concrete";
  548. Mangle(mangleContext, name, concreteInterfaceType->mInterface);
  549. return;
  550. }
  551. else if (type->IsSizedArray())
  552. {
  553. if (type->IsUnknownSizedArrayType())
  554. {
  555. BfUnknownSizedArrayType* arrayType = (BfUnknownSizedArrayType*)type;
  556. name += "A_";
  557. Mangle(mangleContext, name, arrayType->mElementType);
  558. name += "_";
  559. Mangle(mangleContext, name, arrayType->mElementCountSource);
  560. return;
  561. }
  562. else
  563. {
  564. BfSizedArrayType* arrayType = (BfSizedArrayType*)type;
  565. name += StrFormat("A%d_", arrayType->mElementCount);
  566. Mangle(mangleContext, name, arrayType->mElementType);
  567. return;
  568. }
  569. }
  570. else if (type->IsMethodRef())
  571. {
  572. auto methodRefType = (BfMethodRefType*)type;
  573. String mrefName = "mref_";
  574. String mangleName;
  575. BfMethodInstance* methodInstance = methodRefType->mMethodRef;
  576. if (methodInstance == NULL)
  577. {
  578. BF_ASSERT(!methodRefType->mMangledMethodName.IsEmpty());
  579. mangleName = methodRefType->mMangledMethodName;
  580. }
  581. else
  582. {
  583. if (methodInstance->mIsAutocompleteMethod)
  584. name += "AUTOCOMPLETE";
  585. auto module = methodInstance->GetOwner()->mModule;
  586. if (module->mCompiler->mIsResolveOnly)
  587. {
  588. // There are cases where we will reprocess a method in ResolveOnly for things like
  589. // GetSymbolReferences, so we will have duplicate live local methodInstances in those cases
  590. mrefName += HashEncode64((uint64)methodRefType->mMethodRef);
  591. }
  592. else
  593. {
  594. mangleName = Mangle(methodInstance);
  595. methodRefType->mMangledMethodName = mangleName;
  596. }
  597. }
  598. if (!mangleName.IsEmpty())
  599. {
  600. Val128 val128 = Hash128(mangleName.c_str(), (int)mangleName.length());
  601. mrefName += HashEncode128(val128);
  602. }
  603. //TODO: Make a 'U' name?
  604. name += mrefName;
  605. }
  606. else if (type->IsConstExprValue())
  607. {
  608. BfConstExprValueType* constExprValueType = (BfConstExprValueType*)type;
  609. int64 val = constExprValueType->mValue.mInt64;
  610. if ((!constExprValueType->mType->IsPrimitiveType()) ||
  611. (((BfPrimitiveType*)constExprValueType->mType)->mTypeDef->mTypeCode != BfTypeCode_IntPtr))
  612. {
  613. Mangle(mangleContext, name, constExprValueType->mType);
  614. }
  615. name += "$0";
  616. if (val < 0)
  617. {
  618. name += "?";
  619. val = -val;
  620. }
  621. if ((val >= 1) && (val < 10))
  622. {
  623. name += (char)('0' + val - 1);
  624. }
  625. else
  626. {
  627. char str[64];
  628. char* strP = str + 63;
  629. *strP = 0;
  630. while (val > 0)
  631. {
  632. *(--strP) = (char)((val % 0x10) + 'A');
  633. val /= 0x10;
  634. }
  635. name += strP;
  636. name += '`';
  637. }
  638. if (constExprValueType->mValue.mTypeCode == BfTypeCode_Let)
  639. name += "Undef";
  640. }
  641. else
  642. {
  643. BF_FATAL("Not handled");
  644. }
  645. }
  646. String BfGNUMangler::Mangle(BfType* type, BfModule* module)
  647. {
  648. StringT<256> name;
  649. name += "_ZTS";
  650. MangleContext mangleContext;
  651. mangleContext.mModule = module;
  652. Mangle(mangleContext, name, type);
  653. return name;
  654. }
  655. String BfGNUMangler::Mangle(BfMethodInstance* methodInst)
  656. {
  657. StringT<256> name;
  658. if ((methodInst->mMethodDef->mCLink) && (!methodInst->mMangleWithIdx))
  659. {
  660. return methodInst->mMethodDef->mName;
  661. }
  662. auto methodDef = methodInst->mMethodDef;
  663. auto methodDeclaration = BfNodeDynCastExact<BfMethodDeclaration>(methodDef->mMethodDeclaration);
  664. auto typeInst = methodInst->GetOwner();
  665. auto typeDef = typeInst->mTypeDef;
  666. MangleContext mangleContext;
  667. mangleContext.mModule = methodInst->GetOwner()->mModule;
  668. if (methodInst->mCallingConvention != BfCallingConvention_Unspecified)
  669. mangleContext.mCCompat = true;
  670. bool isCMangle = false;
  671. HandleCustomAttributes(methodInst->GetCustomAttributes(), typeInst->mConstHolder, mangleContext.mModule, name, isCMangle, mangleContext.mCPPMangle);
  672. if (isCMangle)
  673. name += methodInst->mMethodDef->mName;
  674. if (!name.IsEmpty())
  675. return name;
  676. bool mangledMethodIdx = false;
  677. bool prefixLen = false;
  678. bool isNameOpen = false;
  679. name += "_Z";
  680. MangleTypeInst(mangleContext, name, methodInst->mMethodInstanceGroup->mOwner, methodInst->GetExplicitInterface(), &isNameOpen);
  681. if (methodInst->GetForeignType() != NULL)
  682. {
  683. // This won't demangle correctly. TODO: Do this 'correctly'
  684. MangleTypeInst(mangleContext, name, methodInst->GetForeignType());
  685. }
  686. mangleContext.mPrefixObjectPointer = true;
  687. StringT<128> methodName = methodInst->mMethodDef->mName;
  688. for (int i = 0; i < (int)methodName.length(); i++)
  689. {
  690. if (methodName[i] == '@')
  691. methodName[i] = '$';
  692. }
  693. if ((!mangleContext.mCPPMangle) && (!methodDef->mIsMutating) && (!methodDef->mIsStatic) && (methodInst->GetOwner()->IsValueType()))
  694. methodName += "__im";
  695. if (methodInst->mMethodDef->mIsOperator)
  696. {
  697. auto operatorDef = (BfOperatorDef*)methodInst->mMethodDef;
  698. if (operatorDef->mOperatorDeclaration->mIsConvOperator)
  699. {
  700. methodName = "cv";
  701. Mangle(mangleContext, methodName, methodInst->mReturnType);
  702. }
  703. else
  704. {
  705. switch (operatorDef->mOperatorDeclaration->mBinOp)
  706. {
  707. case BfBinaryOp_Add:
  708. methodName = "pl";
  709. break;
  710. case BfBinaryOp_Subtract:
  711. methodName = "mi";
  712. break;
  713. case BfBinaryOp_Multiply:
  714. methodName = "ml";
  715. break;
  716. case BfBinaryOp_OverflowAdd:
  717. methodName = "opl";
  718. break;
  719. case BfBinaryOp_OverflowSubtract:
  720. methodName = "omi";
  721. break;
  722. case BfBinaryOp_OverflowMultiply:
  723. methodName = "oml";
  724. break;
  725. case BfBinaryOp_Divide:
  726. methodName = "dv";
  727. break;
  728. case BfBinaryOp_Modulus:
  729. methodName = "rm";
  730. break;
  731. case BfBinaryOp_BitwiseAnd:
  732. methodName = "an";
  733. break;
  734. case BfBinaryOp_BitwiseOr:
  735. methodName = "or";
  736. break;
  737. case BfBinaryOp_ExclusiveOr:
  738. methodName = "eo";
  739. break;
  740. case BfBinaryOp_LeftShift:
  741. methodName = "ls";
  742. break;
  743. case BfBinaryOp_RightShift:
  744. methodName = "rs";
  745. break;
  746. case BfBinaryOp_Equality:
  747. methodName = "eq";
  748. break;
  749. case BfBinaryOp_InEquality:
  750. methodName = "ne";
  751. break;
  752. case BfBinaryOp_GreaterThan:
  753. methodName = "gt";
  754. break;
  755. case BfBinaryOp_LessThan:
  756. methodName = "lt";
  757. break;
  758. case BfBinaryOp_GreaterThanOrEqual:
  759. methodName = "ge";
  760. break;
  761. case BfBinaryOp_LessThanOrEqual:
  762. methodName = "le";
  763. break;
  764. case BfBinaryOp_ConditionalAnd:
  765. methodName = "aa";
  766. break;
  767. case BfBinaryOp_ConditionalOr:
  768. methodName = "oo";
  769. break;
  770. case BfBinaryOp_NullCoalesce:
  771. methodName = "2nc";
  772. break;
  773. case BfBinaryOp_Is:
  774. methodName = "2is";
  775. break;
  776. case BfBinaryOp_As:
  777. methodName = "2as";
  778. break;
  779. default: break;
  780. }
  781. switch (operatorDef->mOperatorDeclaration->mUnaryOp)
  782. {
  783. case BfUnaryOp_AddressOf:
  784. methodName = "ad";
  785. break;
  786. case BfUnaryOp_Dereference:
  787. methodName = "de";
  788. break;
  789. case BfUnaryOp_Negate:
  790. methodName = "ng";
  791. break;
  792. case BfUnaryOp_Not:
  793. methodName = "nt";
  794. break;
  795. case BfUnaryOp_Positive:
  796. methodName = "ps";
  797. break;
  798. case BfUnaryOp_InvertBits:
  799. methodName = "co";
  800. break;
  801. case BfUnaryOp_Increment:
  802. methodName = "pp";
  803. break;
  804. case BfUnaryOp_Decrement:
  805. methodName = "mm";
  806. break;
  807. case BfUnaryOp_PostIncrement:
  808. methodName = "pp";
  809. break;
  810. case BfUnaryOp_PostDecrement:
  811. methodName = "mm";
  812. break;
  813. case BfUnaryOp_Ref:
  814. methodName = "3ref";
  815. break;
  816. case BfUnaryOp_Mut:
  817. methodName = "3mut";
  818. break;
  819. case BfUnaryOp_Out:
  820. methodName = "3out";
  821. break;
  822. default: break;
  823. }
  824. }
  825. }
  826. else if (methodInst->mMethodDef->mMethodType == BfMethodType_Ctor)
  827. {
  828. if (methodInst->mMethodDef->mIsStatic)
  829. {
  830. methodName = "__BfStaticCtor";
  831. prefixLen = true;
  832. }
  833. else
  834. methodName = "C1";
  835. }
  836. else if (methodInst->mMethodDef->mMethodType == BfMethodType_Dtor)
  837. {
  838. if (methodInst->mMethodDef->mIsStatic)
  839. {
  840. methodName = "__BfStaticDtor";
  841. prefixLen = true;
  842. }
  843. else
  844. methodName = "D1";
  845. }
  846. else
  847. {
  848. if (methodInst->mMangleWithIdx)
  849. {
  850. methodName += StrFormat("`%d", methodInst->mMethodDef->mIdx);
  851. mangledMethodIdx = true;
  852. }
  853. prefixLen = true;
  854. }
  855. if (!mangleContext.mCPPMangle)
  856. {
  857. if (methodDef->mCheckedKind == BfCheckedKind_Checked)
  858. name += "`CHK";
  859. else if (methodDef->mCheckedKind == BfCheckedKind_Unchecked)
  860. name += "`UCHK";
  861. if (methodDef->mHasComptime)
  862. name += "`COMPTIME";
  863. }
  864. if (((methodInst->GetOwner()->mTypeDef->IsGlobalsContainer()) &&
  865. ((methodDef->mMethodType == BfMethodType_Ctor) || (methodDef->mMethodType == BfMethodType_Dtor) || (methodDef->mName == BF_METHODNAME_MARKMEMBERS_STATIC))) ||
  866. ((methodInst->mMethodDef->mDeclaringType->mPartialIdx != -1) && (methodInst->mMethodDef->mDeclaringType->IsExtension()) &&
  867. (!methodInst->mIsForeignMethodDef) && (!methodInst->mMethodDef->mIsExtern) &&
  868. ((!methodInst->mMethodDef->mIsOverride) || (methodDef->mName == BF_METHODNAME_MARKMEMBERS) || (methodDef->mMethodType == BfMethodType_Dtor))))
  869. {
  870. auto declType = methodInst->mMethodDef->mDeclaringType;
  871. BF_ASSERT(methodInst->GetOwner()->mTypeDef->mIsCombinedPartial);
  872. auto declProject = declType->mProject;
  873. bool addProjectName = (declProject != typeInst->mTypeDef->mProject);
  874. bool addIndex = true;
  875. if (typeInst->mTypeDef->IsGlobalsContainer())
  876. {
  877. addProjectName = true;
  878. if ((methodInst->mCallingConvention == BfCallingConvention_Cdecl) ||
  879. (methodInst->mCallingConvention == BfCallingConvention_Stdcall))
  880. {
  881. addProjectName = false;
  882. addIndex = false;
  883. }
  884. }
  885. if (addProjectName)
  886. {
  887. name += declProject->mName;
  888. name += "$";
  889. }
  890. if (addIndex)
  891. name += StrFormat("%d$", declType->mPartialIdx);
  892. }
  893. if ((methodInst->mMangleWithIdx) && (!mangledMethodIdx))
  894. {
  895. methodName += StrFormat("`%d", methodInst->mMethodDef->mIdx);
  896. }
  897. //
  898. if ((prefixLen) && (methodInst->mMethodInstanceGroup->mOwner->mTypeDef->IsGlobalsContainer()) && (methodInst->mMethodDef->mMethodDeclaration == NULL))
  899. {
  900. methodName += '`';
  901. methodName += methodInst->mMethodInstanceGroup->mOwner->mTypeDef->mProject->mName;
  902. }
  903. if (prefixLen)
  904. AddSizedString(name, methodName);
  905. else
  906. name += methodName;
  907. if (methodInst->GetNumGenericArguments() != 0)
  908. {
  909. auto& methodGenericArguments = methodInst->mMethodInfoEx->mMethodGenericArguments;
  910. NameSubstitute nameSub(NameSubstitute::Kind_MethodName, methodInst);
  911. nameSub.mExtendsIdx = (int)mangleContext.mSubstituteList.size() - 1;
  912. mangleContext.mSubstituteList.push_back(nameSub);
  913. name += 'I';
  914. for (auto genericArg : methodGenericArguments)
  915. Mangle(mangleContext, name, genericArg);
  916. name += 'E';
  917. }
  918. else if (methodInst->mMethodDef->mGenericParams.size() != 0)
  919. {
  920. NameSubstitute nameSub(NameSubstitute::Kind_MethodName, methodInst);
  921. nameSub.mExtendsIdx = (int)mangleContext.mSubstituteList.size() - 1;
  922. mangleContext.mSubstituteList.push_back(nameSub);
  923. name += 'I';
  924. for (auto genericArg : methodInst->mMethodDef->mGenericParams)
  925. name += 'v';
  926. name += 'E';
  927. }
  928. if (isNameOpen)
  929. name += 'E';
  930. if (methodInst->mMethodDef->mGenericParams.size() != 0)
  931. Mangle(mangleContext, name, methodInst->mReturnType);
  932. mangleContext.mInArgs = true;
  933. bool doExplicitThis = (!methodDef->mIsStatic) && (typeInst->IsTypedPrimitive());
  934. if (doExplicitThis) // Explicit "_this"
  935. Mangle(mangleContext, name, typeInst->GetUnderlyingType());
  936. for (int paramIdx = 0; paramIdx < (int)methodInst->GetParamCount(); paramIdx++)
  937. {
  938. BfType* paramType = methodInst->GetParamType(paramIdx);
  939. bool isConst = false;
  940. if ((methodDeclaration != NULL) && (paramIdx < methodDeclaration->mParams.mSize))
  941. {
  942. auto paramDecl = methodDeclaration->mParams[paramIdx];
  943. HandleParamCustomAttributes(paramDecl->mAttributes, false, isConst);
  944. }
  945. if (!mangleContext.mCPPMangle)
  946. {
  947. auto paramKind = methodInst->GetParamKind(paramIdx);
  948. if (paramKind == BfParamKind_Params)
  949. name += "U6params";
  950. else if (paramKind == BfParamKind_DelegateParam)
  951. name += "U5param";
  952. }
  953. if ((paramType->IsVoid()) && (methodInst->GetParamCount() == 1))
  954. {
  955. // Avoid collision between 'Method()' and 'Method(void)'
  956. name += "U4void";
  957. }
  958. else
  959. Mangle(mangleContext, name, paramType, NULL, isConst);
  960. }
  961. if ((methodInst->GetParamCount() == 0) && (!doExplicitThis))
  962. name += 'v';
  963. return name;
  964. }
  965. String BfGNUMangler::MangleMethodName(BfTypeInstance* type, const StringImpl& methodName)
  966. {
  967. MangleContext mangleContext;
  968. mangleContext.mModule = type->mModule;
  969. StringT<256> name = "_Z";
  970. auto typeInst = type->ToTypeInstance();
  971. BF_ASSERT(typeInst != NULL);
  972. bool isNameOpen;
  973. MangleTypeInst(mangleContext, name, typeInst, NULL, &isNameOpen);
  974. AddSizedString(name, methodName);
  975. if (isNameOpen)
  976. name += "E";
  977. name += "v";
  978. return name;
  979. }
  980. String BfGNUMangler::MangleStaticFieldName(BfTypeInstance* type, const StringImpl& fieldName)
  981. {
  982. MangleContext mangleContext;
  983. mangleContext.mModule = type->mModule;
  984. auto typeInst = type->ToTypeInstance();
  985. auto typeDef = typeInst->mTypeDef;
  986. if ((typeDef->IsGlobalsContainer()) && (typeDef->mNamespace.IsEmpty()))
  987. return fieldName;
  988. StringT<256> name = "_Z";
  989. bool isNameOpen;
  990. MangleTypeInst(mangleContext, name, typeInst, NULL, &isNameOpen);
  991. AddSizedString(name, fieldName);
  992. if (isNameOpen)
  993. name += "E";
  994. return name;
  995. }
  996. String BfGNUMangler::Mangle(BfFieldInstance* fieldInstance)
  997. {
  998. StringT<256> name;
  999. MangleContext mangleContext;
  1000. mangleContext.mModule = fieldInstance->mOwner->mModule;
  1001. bool isCMangle = false;
  1002. HandleCustomAttributes(fieldInstance->mCustomAttributes, fieldInstance->mOwner->mConstHolder, mangleContext.mModule, name, isCMangle, mangleContext.mCPPMangle);
  1003. if (isCMangle)
  1004. name += fieldInstance->GetFieldDef()->mName;
  1005. if (!name.IsEmpty())
  1006. return name;
  1007. auto typeInst = fieldInstance->mOwner->ToTypeInstance();
  1008. auto typeDef = typeInst->mTypeDef;
  1009. if ((typeDef->IsGlobalsContainer()) && (typeDef->mNamespace.IsEmpty()))
  1010. return fieldInstance->GetFieldDef()->mName;
  1011. name += "_Z";
  1012. bool isNameOpen;
  1013. MangleTypeInst(mangleContext, name, typeInst, NULL, &isNameOpen);
  1014. AddSizedString(name, fieldInstance->GetFieldDef()->mName);
  1015. if (isNameOpen)
  1016. name += "E";
  1017. return name;
  1018. }
  1019. //////////////////////////////////////////////////////////////////////////
  1020. BfModule* BfMSMangler::MangleContext::GetUnreifiedModule()
  1021. {
  1022. if (mModule == NULL)
  1023. return NULL;
  1024. return mModule->mContext->mUnreifiedModule;
  1025. }
  1026. //////////////////////////////////////////////////////////////////////////
  1027. void BfMSMangler::AddGenericArgs(MangleContext& mangleContext, StringImpl& name, const SizedArrayImpl<BfType*>& genericArgs, int numOuterGenericParams)
  1028. {
  1029. if (numOuterGenericParams == (int)genericArgs.size())
  1030. return;
  1031. auto prevSubList = mangleContext.mSubstituteList;
  1032. auto prevSubTypeList = mangleContext.mSubstituteTypeList;
  1033. mangleContext.mSubstituteList.clear();
  1034. for (int genericIdx = numOuterGenericParams; genericIdx < (int)genericArgs.size(); genericIdx++)
  1035. Mangle(mangleContext, name, genericArgs[genericIdx]);
  1036. mangleContext.mSubstituteList = prevSubList;
  1037. mangleContext.mSubstituteTypeList = prevSubTypeList;
  1038. }
  1039. void BfMSMangler::AddStr(MangleContext& mangleContext, StringImpl& name, const StringImpl& str)
  1040. {
  1041. if ((int)mangleContext.mSubstituteList.size() < 10)
  1042. {
  1043. // Add NULL entry... shouldn't match anything
  1044. mangleContext.mSubstituteList.push_back(NameSubstitute(NameSubstitute::Kind_None, NULL));
  1045. }
  1046. name += str;
  1047. name += '@';
  1048. }
  1049. void BfMSMangler::AddSubIdx(StringImpl& name, int strIdx)
  1050. {
  1051. //TODO: BF_ASSERT(strIdx < 10);
  1052. char str[16];
  1053. itoa(strIdx, str, 10);
  1054. name += str;
  1055. }
  1056. void BfMSMangler::AddTypeStart(MangleContext& mangleContext, StringImpl& name, BfType* type)
  1057. {
  1058. if (mangleContext.mIsSafeMangle)
  1059. {
  1060. name += "V"; // Mangle everything as a struct so we don't need to require the type to be populated
  1061. return;
  1062. }
  1063. if (!type->IsDeclared())
  1064. {
  1065. if (mangleContext.mModule != NULL)
  1066. {
  1067. auto unreifiedModule = mangleContext.GetUnreifiedModule();
  1068. if (unreifiedModule != NULL)
  1069. unreifiedModule->PopulateType(type, BfPopulateType_Declaration);
  1070. }
  1071. else
  1072. {
  1073. BF_FATAL("No module");
  1074. }
  1075. }
  1076. if ((type->IsEnum()) && (type->IsTypedPrimitive()))
  1077. {
  1078. auto unreifiedModule = mangleContext.GetUnreifiedModule();
  1079. if (type->mDefineState >= BfTypeDefineState_Defined)
  1080. {
  1081. BF_ASSERT(type->mSize >= 0);
  1082. }
  1083. // The enum size is supposed to be encoded, but VC always uses '4'
  1084. //name += "W";
  1085. //name += ('0' + type->mSize);
  1086. name += "W4";
  1087. return;
  1088. }
  1089. name += type->IsStruct() ? "U" : "V";
  1090. }
  1091. bool BfMSMangler::FindOrCreateNameSub(MangleContext& mangleContext, StringImpl& name, const NameSubstitute& newNameSub)
  1092. {
  1093. for (int curMatchIdx = 0; curMatchIdx < (int)mangleContext.mSubstituteList.size(); curMatchIdx++)
  1094. {
  1095. auto& entry = mangleContext.mSubstituteList[curMatchIdx];
  1096. if ((entry.mKind == newNameSub.mKind) && (entry.mParam == newNameSub.mParam) && (entry.mExtendsTypeId == newNameSub.mExtendsTypeId))
  1097. {
  1098. AddSubIdx(name, curMatchIdx);
  1099. return true;
  1100. }
  1101. }
  1102. if (newNameSub.mKind == NameSubstitute::Kind_NamespaceAtom)
  1103. {
  1104. name += newNameSub.mAtom->mString;
  1105. name += '@';
  1106. }
  1107. else if (newNameSub.mKind == NameSubstitute::Kind_TypeInstName)
  1108. {
  1109. if (mangleContext.mWantsGroupStart)
  1110. {
  1111. AddTypeStart(mangleContext, name, newNameSub.mTypeInst);
  1112. mangleContext.mWantsGroupStart = false;
  1113. }
  1114. if (newNameSub.mTypeInst->IsTuple())
  1115. {
  1116. auto tupleType = (BfTypeInstance*)newNameSub.mType;
  1117. name += "?$__TUPLE";
  1118. SizedArray<BfType*, 8> typeVec;
  1119. for (auto& fieldInst : tupleType->mFieldInstances)
  1120. {
  1121. BfFieldDef* fieldDef = fieldInst.GetFieldDef();
  1122. String fieldName = fieldDef->mName;
  1123. if ((fieldName[0] < '0') || (fieldName[0] > '9'))
  1124. name += StrFormat("_%s", fieldName.c_str());
  1125. typeVec.push_back(fieldInst.mResolvedType);
  1126. }
  1127. name += '@';
  1128. if (!typeVec.empty())
  1129. AddGenericArgs(mangleContext, name, typeVec);
  1130. name += '@';
  1131. }
  1132. else if ((newNameSub.mTypeInst->IsDelegateFromTypeRef()) || (newNameSub.mTypeInst->IsFunctionFromTypeRef()))
  1133. {
  1134. BF_ASSERT(newNameSub.mTypeInst->mTypeDef->mMethods[0]->mName == "Invoke");
  1135. auto delegateInfo = newNameSub.mTypeInst->GetDelegateInfo();
  1136. auto methodDef = newNameSub.mTypeInst->mTypeDef->mMethods[0];
  1137. if (newNameSub.mTypeInst->IsDelegate())
  1138. name += "?$delegate";
  1139. else
  1140. name += "?$function";
  1141. if (methodDef->mIsMutating)
  1142. name += "_mut_";
  1143. if (delegateInfo->mCallingConvention == BfCallingConvention_Cdecl)
  1144. name += "_cdecl_";
  1145. else if (delegateInfo->mCallingConvention == BfCallingConvention_Stdcall)
  1146. name += "_stdcall_";
  1147. else if (delegateInfo->mCallingConvention == BfCallingConvention_Fastcall)
  1148. name += "_fastcall_";
  1149. SizedArray<BfType*, 8> typeVec;
  1150. typeVec.push_back(BfNodeDynCast<BfDirectTypeReference>(methodDef->mReturnTypeRef)->mType);
  1151. for (int paramIdx = 0; paramIdx < (int)methodDef->mParams.size(); paramIdx++)
  1152. {
  1153. name += "_";
  1154. name += methodDef->mParams[paramIdx]->mName;
  1155. if (methodDef->mParams[paramIdx]->mParamKind == BfParamKind_VarArgs)
  1156. {
  1157. name += "__varargs";
  1158. continue;
  1159. }
  1160. if (methodDef->mParams[paramIdx]->mParamKind == BfParamKind_Params)
  1161. name += "_params_";
  1162. typeVec.push_back(BfNodeDynCast<BfDirectTypeReference>(methodDef->mParams[paramIdx]->mTypeRef)->mType);
  1163. }
  1164. name += '@';
  1165. if (!typeVec.empty())
  1166. AddGenericArgs(mangleContext, name, typeVec);
  1167. name += '@';
  1168. }
  1169. else if (newNameSub.mTypeInst->IsBoxed())
  1170. {
  1171. auto boxedType = (BfBoxedType*)newNameSub.mTypeInst;
  1172. name += "?$Box@";
  1173. SizedArray<BfType*, 8> typeVec;
  1174. typeVec.push_back(boxedType->GetModifiedElementType());
  1175. AddGenericArgs(mangleContext, name, typeVec);
  1176. name += '@';
  1177. }
  1178. else
  1179. {
  1180. auto typeDef = newNameSub.mTypeInst->mTypeDef;
  1181. BfTypeInstance* genericTypeInst = NULL;
  1182. if (newNameSub.mTypeInst->IsGenericTypeInstance())
  1183. genericTypeInst = (BfTypeInstance*)newNameSub.mTypeInst;
  1184. int numOuterGenericParams = 0;
  1185. if ((!mangleContext.mIsSafeMangle) && (typeDef->mOuterType != NULL))
  1186. {
  1187. numOuterGenericParams = (int)typeDef->mOuterType->mGenericParamDefs.size();
  1188. }
  1189. if (genericTypeInst != NULL)
  1190. {
  1191. // If we don't have our own generic params then don't treat us as a generic
  1192. if ((int)typeDef->mGenericParamDefs.size() == numOuterGenericParams)
  1193. genericTypeInst = NULL;
  1194. }
  1195. if (genericTypeInst != NULL)
  1196. {
  1197. name += "?$";
  1198. mangleContext.mWantsGroupStart = false;
  1199. }
  1200. // name += *typeDef->mName->mString;
  1201. // if ((typeDef->mIsDelegate) && (newNameSub.mTypeInst->IsClosure()))
  1202. // {
  1203. // auto closureType = (BfClosureType*)newNameSub.mTypeInst;
  1204. // if (!closureType->mCreatedTypeDef)
  1205. // name += closureType->mNameAdd;
  1206. // }
  1207. if (newNameSub.mTypeInst->IsClosure())
  1208. {
  1209. auto closureType = (BfClosureType*)newNameSub.mTypeInst;
  1210. name += closureType->mSrcDelegate->mTypeDef->mName->mString;
  1211. name += closureType->mNameAdd;
  1212. }
  1213. else
  1214. {
  1215. name += typeDef->mName->mString;
  1216. }
  1217. name += '@';
  1218. if (genericTypeInst != NULL)
  1219. {
  1220. AddGenericArgs(mangleContext, name, genericTypeInst->mGenericTypeInfo->mTypeGenericArguments, numOuterGenericParams);
  1221. name += '@';
  1222. }
  1223. }
  1224. }
  1225. else if (newNameSub.mKind == BfGNUMangler::NameSubstitute::Kind_GenericParam)
  1226. {
  1227. name += "U"; // Struct
  1228. auto genericParamType = (BfGenericParamType*)newNameSub.mType;
  1229. if (genericParamType->mGenericParamKind == BfGenericParamKind_Method)
  1230. name += "_M";
  1231. else
  1232. name += "_T";
  1233. char str[16];
  1234. itoa(genericParamType->mGenericParamIdx, str, 10);
  1235. name += str;
  1236. name += '@';
  1237. name += '@';
  1238. }
  1239. mangleContext.mSubstituteList.push_back(newNameSub);
  1240. return false;
  1241. }
  1242. void BfMSMangler::Mangle(MangleContext& mangleContext, StringImpl& name, BfTypeInstance* typeInstance, bool isAlreadyStarted, bool isOuterType)
  1243. {
  1244. BfTypeInstance* genericTypeInst = NULL;
  1245. if (typeInstance->IsGenericTypeInstance())
  1246. {
  1247. genericTypeInst = (BfTypeInstance*)typeInstance;
  1248. }
  1249. auto typeDef = typeInstance->mTypeDef;
  1250. bool hasNamespace = typeDef->mNamespace.mSize != 0;
  1251. if (!isAlreadyStarted)
  1252. {
  1253. if ((hasNamespace) || (typeDef->mOuterType != NULL))
  1254. {
  1255. AddTypeStart(mangleContext, name, typeInstance);
  1256. }
  1257. else
  1258. {
  1259. if (typeDef->IsGlobalsContainer())
  1260. return;
  1261. mangleContext.mWantsGroupStart = true;
  1262. }
  1263. }
  1264. if (!typeDef->IsGlobalsContainer())
  1265. FindOrCreateNameSub(mangleContext, name, NameSubstitute(BfMangler::NameSubstitute::Kind_TypeInstName, typeInstance));
  1266. mangleContext.mWantsGroupStart = false;
  1267. auto useModule = typeInstance->mModule;
  1268. if (useModule == NULL)
  1269. useModule = mangleContext.mModule;
  1270. if ((typeDef->mOuterType != NULL) && (!typeInstance->IsBoxed()))
  1271. {
  1272. if (mangleContext.mIsSafeMangle)
  1273. {
  1274. auto outerType = typeDef->mOuterType;
  1275. while (outerType != NULL)
  1276. {
  1277. name += ":";
  1278. name += outerType->mFullName.ToString();
  1279. outerType = outerType->mOuterType;
  1280. }
  1281. }
  1282. else
  1283. {
  1284. auto unreifiedModule = useModule->mContext->mUnreifiedModule;
  1285. auto outerType = unreifiedModule->GetOuterType(typeInstance);
  1286. if (outerType != NULL)
  1287. Mangle(mangleContext, name, outerType, true, true);
  1288. else
  1289. useModule->Fail("Failed to mangle name in BfMSMangler::Mangle");
  1290. }
  1291. }
  1292. if (!isOuterType)
  1293. {
  1294. if (!typeInstance->IsBoxed())
  1295. {
  1296. for (int namespaceIdx = (int)typeDef->mNamespace.mSize - 1; namespaceIdx >= 0; namespaceIdx--)
  1297. {
  1298. auto namePart = typeDef->mNamespace.mParts[namespaceIdx];
  1299. FindOrCreateNameSub(mangleContext, name, NameSubstitute(BfMangler::NameSubstitute::Kind_NamespaceAtom, namePart));
  1300. }
  1301. if (!mangleContext.mCPPMangle)
  1302. FindOrCreateNameSub(mangleContext, name, NameSubstitute(BfMangler::NameSubstitute::Kind_NamespaceAtom, useModule->mSystem->mBfAtom));
  1303. }
  1304. name += '@';
  1305. }
  1306. }
  1307. void BfMSMangler::MangleConst(MangleContext & mangleContext, StringImpl & name, int64 val)
  1308. {
  1309. name += "$0";
  1310. if (val < 0)
  1311. {
  1312. name += "?";
  1313. val = -val;
  1314. }
  1315. if ((val > 0) && (val <= 10))
  1316. {
  1317. name += (char)('0' + val - 1);
  1318. }
  1319. else
  1320. {
  1321. char str[64];
  1322. char* strP = str + 63;
  1323. *strP = 0;
  1324. while (val > 0)
  1325. {
  1326. *(--strP) = (char)((val % 0x10) + 'A');
  1327. val /= 0x10;
  1328. }
  1329. name += strP;
  1330. name += '@';
  1331. }
  1332. }
  1333. void BfMSMangler::AddPrefix(MangleContext& mangleContext, StringImpl& name, int startIdx, const char* prefix)
  1334. {
  1335. int subIdx;
  1336. char startChar = name[startIdx];
  1337. if ((startChar >= '0') && (startChar <= '9'))
  1338. {
  1339. //subIdx = ParseSubIdx(name, startIdx);
  1340. subIdx = startChar - '0';
  1341. for (int matchIdx = subIdx + 1; matchIdx < (int)mangleContext.mSubstituteList.size(); matchIdx++)
  1342. {
  1343. auto& entry = mangleContext.mSubstituteList[matchIdx];
  1344. if ((entry.mKind == NameSubstitute::Kind_Prefix) && (entry.mExtendsIdx == subIdx) && (entry.mPrefix == prefix))
  1345. {
  1346. BF_ASSERT(name.EndsWith('_'));
  1347. name.RemoveToEnd(startIdx);
  1348. AddSubIdx(name, matchIdx);
  1349. return;
  1350. }
  1351. }
  1352. }
  1353. else
  1354. {
  1355. //auto typeCode = GetPrimTypeAt(mangleContext, name, startIdx);
  1356. auto typeCode = BfTypeCode_None;
  1357. if (typeCode != (BfTypeCode)-1)
  1358. {
  1359. for (int matchIdx = 0; matchIdx < (int)mangleContext.mSubstituteList.size(); matchIdx++)
  1360. {
  1361. auto& entry = mangleContext.mSubstituteList[matchIdx];
  1362. if ((entry.mKind == NameSubstitute::Kind_PrimitivePrefix) && (entry.mExtendsTypeCode == typeCode) && (entry.mPrefix == prefix))
  1363. {
  1364. name.RemoveToEnd(startIdx);
  1365. AddSubIdx(name, matchIdx);
  1366. return;
  1367. }
  1368. }
  1369. NameSubstitute nameSub;
  1370. nameSub.mKind = NameSubstitute::Kind_PrimitivePrefix;
  1371. nameSub.mExtendsTypeCode = typeCode;
  1372. nameSub.mPrefix = prefix;
  1373. mangleContext.mSubstituteList.push_back(nameSub);
  1374. name.Insert(startIdx, prefix);
  1375. return;
  1376. }
  1377. else
  1378. {
  1379. // Applies to last-added one
  1380. subIdx = (int)mangleContext.mSubstituteList.size() - 1;
  1381. BF_ASSERT(isdigit(startChar) || (startChar == 'N') || (startChar == 'P') || (startChar == 'R'));
  1382. }
  1383. }
  1384. NameSubstitute nameSub;
  1385. nameSub.mKind = NameSubstitute::Kind_Prefix;
  1386. nameSub.mExtendsIdx = subIdx;
  1387. nameSub.mPrefix = prefix;
  1388. mangleContext.mSubstituteList.push_back(nameSub);
  1389. name.Insert(startIdx, prefix);
  1390. }
  1391. void BfMSMangler::Mangle(MangleContext& mangleContext, StringImpl& name, BfType* type, bool useTypeList, bool isConst)
  1392. {
  1393. bool isLongPrim = false;
  1394. if (type->IsPrimitiveType())
  1395. {
  1396. auto primType = (BfPrimitiveType*)type;
  1397. switch (primType->mTypeDef->mTypeCode)
  1398. {
  1399. case BfTypeCode_NullPtr:
  1400. {
  1401. name += "P";
  1402. if (mangleContext.mIs64Bit)
  1403. name += "E";
  1404. name += "AV";
  1405. name += "v";
  1406. }
  1407. return;
  1408. case BfTypeCode_None:
  1409. name += "X"; return;
  1410. case BfTypeCode_Int8:
  1411. name += "C"; return;
  1412. case BfTypeCode_UInt8:
  1413. name += "E"; return;
  1414. case BfTypeCode_Int16:
  1415. name += "F"; return;
  1416. case BfTypeCode_UInt16:
  1417. name += "G"; return;
  1418. case BfTypeCode_Int32:
  1419. name += "H"; return;
  1420. case BfTypeCode_UInt32:
  1421. name += "I"; return;
  1422. case BfTypeCode_Char8:
  1423. name += "D"; return;
  1424. case BfTypeCode_Char16:
  1425. name += "_S"; return; //char16_t
  1426. case BfTypeCode_Float:
  1427. name += "M"; return;
  1428. case BfTypeCode_Double:
  1429. name += "N"; return;
  1430. case BfTypeCode_Int64:
  1431. case BfTypeCode_UInt64:
  1432. case BfTypeCode_Boolean:
  1433. case BfTypeCode_Char32:
  1434. isLongPrim = true;
  1435. break;
  1436. case BfTypeCode_IntPtr:
  1437. if ((primType->mSize == 4) && (mangleContext.mCCompat))
  1438. {
  1439. name += "H";
  1440. return;
  1441. }
  1442. isLongPrim = true;
  1443. break;
  1444. case BfTypeCode_UIntPtr:
  1445. if ((primType->mSize == 4) && (mangleContext.mCCompat))
  1446. {
  1447. name += "I";
  1448. return;
  1449. }
  1450. isLongPrim = true;
  1451. break;
  1452. case BfTypeCode_Dot:
  1453. name += "Tdot@@"; return;
  1454. case BfTypeCode_Var:
  1455. if ((mangleContext.mCCompat) || (mangleContext.mInArgs))
  1456. name += "X";
  1457. else
  1458. name += "Tvar@@";
  1459. return;
  1460. case BfTypeCode_Self:
  1461. if ((mangleContext.mCCompat) || (mangleContext.mInArgs))
  1462. name += "X";
  1463. else
  1464. name += "Tself@@";
  1465. return;
  1466. case BfTypeCode_Let:
  1467. name += "Tlet@@"; return;
  1468. case BfTypeCode_IntUnknown:
  1469. name += "Tiunk@@"; return;
  1470. case BfTypeCode_UIntUnknown:
  1471. name += "Tuunk@@"; return;
  1472. default:
  1473. name += "?"; return;
  1474. }
  1475. }
  1476. if (useTypeList)
  1477. {
  1478. for (int checkIdx = 0; checkIdx < (int)mangleContext.mSubstituteTypeList.size(); checkIdx++)
  1479. {
  1480. if (mangleContext.mSubstituteTypeList[checkIdx] == type)
  1481. {
  1482. name += ('0' + checkIdx);
  1483. return;
  1484. }
  1485. }
  1486. }
  1487. if (isLongPrim)
  1488. {
  1489. auto primType = (BfPrimitiveType*)type;
  1490. switch (primType->mTypeDef->mTypeCode)
  1491. {
  1492. case BfTypeCode_Boolean:
  1493. name += "_N"; break;
  1494. case BfTypeCode_Int64:
  1495. name += "_J"; break;
  1496. case BfTypeCode_UInt64:
  1497. name += "_K"; break;
  1498. case BfTypeCode_UIntPtr:
  1499. if (primType->mSize == 4)
  1500. name += "_I";
  1501. else if (mangleContext.mCCompat)
  1502. name += "_K";
  1503. else
  1504. name += "Tuint@@";
  1505. break;
  1506. case BfTypeCode_IntPtr:
  1507. if (primType->mSize == 4)
  1508. name += "_H";
  1509. else if (mangleContext.mCCompat)
  1510. name += "_J";
  1511. else
  1512. name += "Tint@@";
  1513. break;
  1514. case BfTypeCode_Char32:
  1515. name += "_U"; break;
  1516. default: break;
  1517. }
  1518. }
  1519. else if (type->IsTypeInstance())
  1520. {
  1521. auto typeInstance = (BfTypeInstance*)type;
  1522. auto typeDef = typeInstance->mTypeDef;
  1523. if (type->IsObjectOrInterface())
  1524. {
  1525. name += "P";
  1526. if (mangleContext.mIs64Bit)
  1527. name += "E";
  1528. name += "A";
  1529. }
  1530. else if (((type->IsGenericTypeInstance()) || (type->IsComposite()) || (type->IsEnum())) && (mangleContext.mInRet))
  1531. name += "?A";
  1532. Mangle(mangleContext, name, typeInstance, false);
  1533. }
  1534. else if (type->IsGenericParam())
  1535. {
  1536. FindOrCreateNameSub(mangleContext, name, NameSubstitute(BfMangler::NameSubstitute::Kind_GenericParam, type));
  1537. }
  1538. else if (type->IsPointer())
  1539. {
  1540. auto pointerType = (BfPointerType*)type;
  1541. const char* strAdd = mangleContext.mIs64Bit ? "PEA" : "PA";
  1542. if (mangleContext.mIs64Bit)
  1543. name += "PE";
  1544. else
  1545. name += "P";
  1546. if (isConst)
  1547. name += "B";
  1548. else
  1549. name += "A";
  1550. Mangle(mangleContext, name, pointerType->mElementType);
  1551. }
  1552. else if (type->IsRef())
  1553. {
  1554. auto refType = (BfRefType*)type;
  1555. name += "A";
  1556. if (mangleContext.mIs64Bit)
  1557. name += "E";
  1558. if ((isConst) || (refType->mRefKind == BfRefType::RefKind_In))
  1559. name += "B";
  1560. else
  1561. name += "A";
  1562. if (refType->mRefKind == BfRefType::RefKind_Mut)
  1563. name += "mut$";
  1564. else if (refType->mRefKind == BfRefType::RefKind_Out)
  1565. name += "out$";
  1566. Mangle(mangleContext, name, refType->mElementType);
  1567. }
  1568. else if (type->IsModifiedTypeType())
  1569. {
  1570. auto retType = (BfModifiedTypeType*)type;
  1571. if (retType->mModifiedKind == BfToken_RetType)
  1572. name += "rettype$";
  1573. else if (retType->mModifiedKind == BfToken_AllocType)
  1574. name += "alloc$";
  1575. else if (retType->mModifiedKind == BfToken_Nullable)
  1576. name += "nullable$";
  1577. else if (retType->mModifiedKind == BfToken_Params)
  1578. name += "params$";
  1579. else
  1580. BF_FATAL("Unhandled");
  1581. Mangle(mangleContext, name, retType->mElementType);
  1582. }
  1583. else if (type->IsConcreteInterfaceType())
  1584. {
  1585. auto concreteType = (BfConcreteInterfaceType*)type;
  1586. name += "concrete$";
  1587. Mangle(mangleContext, name, concreteType->mInterface);
  1588. }
  1589. else if (type->IsSizedArray())
  1590. {
  1591. if (type->IsUnknownSizedArrayType())
  1592. {
  1593. auto arrType = (BfUnknownSizedArrayType*)type;
  1594. name += StrFormat("arr_$", arrType->mSize);
  1595. Mangle(mangleContext, name, arrType->mElementType);
  1596. name += "$";
  1597. Mangle(mangleContext, name, arrType->mElementCountSource);
  1598. }
  1599. else
  1600. {
  1601. // We can't use MS mangling of "_O" because it isn't size-specific
  1602. auto arrType = (BfSizedArrayType*)type;
  1603. //name += StrFormat("arr_%d$", arrType->mSize);
  1604. //Mangle(mangleContext, name, arrType->mElementType);
  1605. name += "?$_ARRAY@";
  1606. Mangle(mangleContext, name, arrType->mElementType);
  1607. MangleConst(mangleContext, name, arrType->mElementCount);
  1608. name += '@';
  1609. }
  1610. }
  1611. else if (type->IsMethodRef())
  1612. {
  1613. auto methodRefType = (BfMethodRefType*)type;
  1614. name += "Tmref_";
  1615. StringT<128> mangleName;
  1616. BfMethodInstance* methodInstance = methodRefType->mMethodRef;
  1617. if (methodInstance == NULL)
  1618. {
  1619. BF_ASSERT(!methodRefType->mMangledMethodName.IsEmpty());
  1620. mangleName = methodRefType->mMangledMethodName;
  1621. }
  1622. else
  1623. {
  1624. if (methodInstance->mIsAutocompleteMethod)
  1625. name += "AUTOCOMPLETE";
  1626. auto module = methodInstance->GetOwner()->mModule;
  1627. if (module->mCompiler->mIsResolveOnly)
  1628. {
  1629. // There are cases where we will reprocess a method in ResolveOnly for things like
  1630. // GetSymbolReferences, so we will have duplicate live local methodInstances in those cases
  1631. name += HashEncode64((uint64)methodRefType->mMethodRef);
  1632. }
  1633. else
  1634. {
  1635. Mangle(mangleName, mangleContext.mIs64Bit, methodInstance);
  1636. methodRefType->mMangledMethodName = mangleName;
  1637. }
  1638. }
  1639. if (!mangleName.IsEmpty())
  1640. {
  1641. Val128 val128 = Hash128(mangleName.c_str(), (int)mangleName.length());
  1642. name += HashEncode128(val128);
  1643. }
  1644. // if (methodInstance->mIsAutocompleteMethod)
  1645. // name += "AUTOCOMPLETE";
  1646. //
  1647. // String mangleAdd = Mangle(mangleContext.mIs64Bit, methodInstance);
  1648. //
  1649. // auto module = methodInstance->GetOwner()->mModule;
  1650. // if (module->mCompiler->mIsResolveOnly)
  1651. // {
  1652. // // There are cases where we will reprocess a method in ResolveOnly for things like
  1653. // // GetSymbolReferences, so we will have duplicate live local methodInstances in those cases
  1654. // name += HashEncode64((uint64)methodRefType->mMethodRef);
  1655. // }
  1656. // else
  1657. // {
  1658. // Val128 val128 = Hash128(mangleAdd.c_str(), (int)mangleAdd.length());
  1659. // name += HashEncode128(val128);
  1660. // }
  1661. name += "@@";
  1662. }
  1663. else if (type->IsConstExprValue())
  1664. {
  1665. BfConstExprValueType* constExprValueType = (BfConstExprValueType*)type;
  1666. int64 val = constExprValueType->mValue.mInt64;
  1667. if ((!constExprValueType->mType->IsPrimitiveType()) ||
  1668. (((BfPrimitiveType*)constExprValueType->mType)->mTypeDef->mTypeCode != BfTypeCode_IntPtr))
  1669. {
  1670. Mangle(mangleContext, name, constExprValueType->mType);
  1671. name += "$";
  1672. }
  1673. MangleConst(mangleContext, name, val);
  1674. if (constExprValueType->mValue.mTypeCode == BfTypeCode_Let)
  1675. name += "Undef";
  1676. }
  1677. else
  1678. {
  1679. BF_ASSERT("Unhandled");
  1680. }
  1681. if ((useTypeList) && (!mangleContext.mInRet) && ((int)mangleContext.mSubstituteTypeList.size() < 10))
  1682. mangleContext.mSubstituteTypeList.push_back(type);
  1683. }
  1684. void BfMSMangler::Mangle(StringImpl& name, bool is64Bit, BfType* type, BfModule* module)
  1685. {
  1686. if (type->IsTypeAlias())
  1687. {
  1688. auto typeAlias = (BfTypeAliasType*)type;
  1689. name += "__ALIAS_";
  1690. name += typeAlias->mTypeDef->mName->ToString();
  1691. name += '@';
  1692. Mangle(name, is64Bit, typeAlias->mAliasToType, module);
  1693. return;
  1694. }
  1695. MangleContext mangleContext;
  1696. mangleContext.mIs64Bit = is64Bit;
  1697. mangleContext.mModule = module;
  1698. auto typeInst = type->ToTypeInstance();
  1699. if ((typeInst != NULL) && (typeInst->mModule != NULL))
  1700. mangleContext.mModule = typeInst->mModule;
  1701. if (typeInst != NULL)
  1702. Mangle(mangleContext, name, typeInst, true);
  1703. else
  1704. Mangle(mangleContext, name, type);
  1705. while ((name.length() > 0) && (name[name.length() - 1] == '@'))
  1706. name.Remove(name.length() - 1);
  1707. }
  1708. void BfMSMangler::Mangle(StringImpl& name, bool is64Bit, BfMethodInstance* methodInst)
  1709. {
  1710. static int mangleIdx = 0;
  1711. mangleIdx++;
  1712. int startNameLen = name.mLength;
  1713. if ((methodInst->mMethodDef->mCLink) && (!methodInst->mMangleWithIdx))
  1714. {
  1715. name += methodInst->mMethodDef->mName;
  1716. return;
  1717. }
  1718. auto methodDef = methodInst->mMethodDef;
  1719. auto methodDeclaration = BfNodeDynCastExact<BfMethodDeclaration>(methodDef->mMethodDeclaration);
  1720. auto typeInst = methodInst->GetOwner();
  1721. auto typeDef = typeInst->mTypeDef;
  1722. MangleContext mangleContext;
  1723. mangleContext.mIs64Bit = is64Bit;
  1724. mangleContext.mModule = methodInst->GetOwner()->mModule;
  1725. if (methodInst->mCallingConvention != BfCallingConvention_Unspecified)
  1726. mangleContext.mCCompat = true;
  1727. bool isCMangle = false;
  1728. HandleCustomAttributes(methodInst->GetCustomAttributes(), typeInst->mConstHolder, mangleContext.mModule, name, isCMangle, mangleContext.mCPPMangle);
  1729. if (isCMangle)
  1730. name += methodInst->mMethodDef->mName;
  1731. if (name.mLength > startNameLen)
  1732. return;
  1733. name += '?';
  1734. if (methodInst->GetNumGenericArguments() != 0)
  1735. {
  1736. name += "?$";
  1737. }
  1738. bool isSpecialFunc = false;
  1739. if (methodInst->mMethodDef->mIsOperator)
  1740. {
  1741. String methodName;
  1742. auto operatorDef = (BfOperatorDef*)methodInst->mMethodDef;
  1743. if (operatorDef->mOperatorDeclaration->mIsConvOperator)
  1744. {
  1745. name += "?B";
  1746. }
  1747. else
  1748. {
  1749. switch (operatorDef->mOperatorDeclaration->mBinOp)
  1750. {
  1751. case BfBinaryOp_Add:
  1752. name += "?H";
  1753. break;
  1754. case BfBinaryOp_Subtract:
  1755. name += "?G";
  1756. break;
  1757. case BfBinaryOp_Multiply:
  1758. name += "?D";
  1759. break;
  1760. case BfBinaryOp_OverflowAdd:
  1761. name += "?OH";
  1762. break;
  1763. case BfBinaryOp_OverflowSubtract:
  1764. name += "?OG";
  1765. break;
  1766. case BfBinaryOp_OverflowMultiply:
  1767. name += "?OD";
  1768. break;
  1769. case BfBinaryOp_Divide:
  1770. name += "?K";
  1771. break;
  1772. case BfBinaryOp_Modulus:
  1773. name += "?L";
  1774. break;
  1775. case BfBinaryOp_BitwiseAnd:
  1776. name += "?I";
  1777. break;
  1778. case BfBinaryOp_BitwiseOr:
  1779. name += "?U";
  1780. break;
  1781. case BfBinaryOp_ExclusiveOr:
  1782. name += "?T";
  1783. break;
  1784. case BfBinaryOp_LeftShift:
  1785. name += "?6";
  1786. break;
  1787. case BfBinaryOp_RightShift:
  1788. name += "?5";
  1789. break;
  1790. case BfBinaryOp_Equality:
  1791. name += "?8";
  1792. break;
  1793. case BfBinaryOp_InEquality:
  1794. name += "?9";
  1795. break;
  1796. case BfBinaryOp_GreaterThan:
  1797. name += "?O";
  1798. break;
  1799. case BfBinaryOp_LessThan:
  1800. name += "?M";
  1801. break;
  1802. case BfBinaryOp_GreaterThanOrEqual:
  1803. name += "?P";
  1804. break;
  1805. case BfBinaryOp_LessThanOrEqual:
  1806. name += "?N";
  1807. break;
  1808. case BfBinaryOp_Compare:
  1809. name += "__cmp__";
  1810. break;
  1811. case BfBinaryOp_ConditionalAnd:
  1812. name += "?V";
  1813. break;
  1814. case BfBinaryOp_ConditionalOr:
  1815. name += "?W";
  1816. break;
  1817. case BfBinaryOp_NullCoalesce:
  1818. methodName = "__nc__";
  1819. break;
  1820. case BfBinaryOp_Is:
  1821. methodName = "__is__";
  1822. break;
  1823. case BfBinaryOp_As:
  1824. methodName = "__as__";
  1825. break;
  1826. default: break;
  1827. }
  1828. switch (operatorDef->mOperatorDeclaration->mUnaryOp)
  1829. {
  1830. case BfUnaryOp_AddressOf:
  1831. name += "?I";
  1832. break;
  1833. case BfUnaryOp_Dereference:
  1834. name += "?D";
  1835. break;
  1836. case BfUnaryOp_Negate:
  1837. name += "?G";
  1838. break;
  1839. case BfUnaryOp_Not:
  1840. name += "?7";
  1841. break;
  1842. case BfUnaryOp_Positive:
  1843. name += "?H";
  1844. break;
  1845. case BfUnaryOp_InvertBits:
  1846. name += "?S";
  1847. break;
  1848. case BfUnaryOp_Increment:
  1849. name += "?E";
  1850. break;
  1851. case BfUnaryOp_Decrement:
  1852. name += "?F";
  1853. break;
  1854. case BfUnaryOp_PostIncrement:
  1855. methodName = "__pi__";
  1856. break;
  1857. case BfUnaryOp_PostDecrement:
  1858. methodName = "__pd__";
  1859. break;
  1860. case BfUnaryOp_Ref:
  1861. methodName = "__ref__";
  1862. break;
  1863. case BfUnaryOp_Out:
  1864. methodName = "__out__";
  1865. break;
  1866. default: break;
  1867. }
  1868. switch (operatorDef->mOperatorDeclaration->mAssignOp)
  1869. {
  1870. case BfAssignmentOp_Assign:
  1871. methodName += "__a__";
  1872. break;
  1873. case BfAssignmentOp_Add:
  1874. methodName += "__a_add__";
  1875. break;
  1876. case BfAssignmentOp_Subtract:
  1877. methodName += "__a_sub__";
  1878. break;
  1879. case BfAssignmentOp_Multiply:
  1880. methodName += "__a_mul__";
  1881. break;
  1882. case BfAssignmentOp_Divide:
  1883. methodName += "__a_div__";
  1884. break;
  1885. case BfAssignmentOp_Modulus:
  1886. methodName += "__a_mod__";
  1887. break;
  1888. case BfAssignmentOp_ShiftLeft:
  1889. methodName += "__a_shl__";
  1890. break;
  1891. case BfAssignmentOp_ShiftRight:
  1892. methodName += "__a_shr__";
  1893. break;
  1894. case BfAssignmentOp_BitwiseAnd:
  1895. methodName += "__a_bwa__";
  1896. break;
  1897. case BfAssignmentOp_BitwiseOr:
  1898. methodName += "__a_bwo__";
  1899. break;
  1900. case BfAssignmentOp_ExclusiveOr:
  1901. methodName += "__a_xor__";
  1902. break;
  1903. default: break;
  1904. }
  1905. }
  1906. if (!methodName.empty())
  1907. {
  1908. AddStr(mangleContext, name, methodName);
  1909. }
  1910. }
  1911. /*else if ((methodDef->mMethodType == BfMethodType_Ctor) && (!methodDef->mIsStatic))
  1912. {
  1913. isSpecialFunc = true;
  1914. name += "?0";
  1915. //AddAtomStr(mangleContext, name, typeDef->mName);
  1916. }
  1917. else if ((methodDef->mMethodType == BfMethodType_Dtor) && (!methodDef->mIsStatic))
  1918. {
  1919. isSpecialFunc = true;
  1920. name += "?1";
  1921. //AddAtomStr(mangleContext, name, typeDef->mName);
  1922. }*/
  1923. else if (methodInst->GetNumGenericArguments() != 0)
  1924. {
  1925. AddStr(mangleContext, name, methodDef->mName);
  1926. AddGenericArgs(mangleContext, name, methodInst->mMethodInfoEx->mMethodGenericArguments);
  1927. name += '@';
  1928. }
  1929. else
  1930. {
  1931. if ((!mangleContext.mCPPMangle) && (!methodDef->mIsMutating) && (!methodDef->mIsStatic) && (methodInst->GetOwner()->IsValueType()))
  1932. AddStr(mangleContext, name, methodDef->mName + "__im");
  1933. else
  1934. AddStr(mangleContext, name, methodDef->mName);
  1935. }
  1936. if (((methodInst->GetOwner()->mTypeDef->IsGlobalsContainer()) &&
  1937. ((methodDef->mMethodType == BfMethodType_Ctor) || (methodDef->mMethodType == BfMethodType_Dtor) || (methodDef->mName == BF_METHODNAME_MARKMEMBERS_STATIC))) ||
  1938. ((methodInst->mMethodDef->mDeclaringType->mPartialIdx != -1) && (methodInst->mMethodDef->mDeclaringType->IsExtension()) &&
  1939. (!methodInst->mIsForeignMethodDef) && (!methodInst->mMethodDef->mIsExtern) &&
  1940. ((!methodInst->mMethodDef->mIsOverride) || (methodDef->mName == BF_METHODNAME_MARKMEMBERS) || (methodDef->mMethodType == BfMethodType_Dtor))))
  1941. {
  1942. auto declType = methodInst->mMethodDef->mDeclaringType;
  1943. BF_ASSERT(methodInst->GetOwner()->mTypeDef->mIsCombinedPartial);
  1944. auto declProject = declType->mProject;
  1945. bool addProjectName = (declProject != typeInst->mTypeDef->mProject);
  1946. bool addIndex = true;
  1947. if (typeInst->mTypeDef->IsGlobalsContainer())
  1948. {
  1949. addProjectName = true;
  1950. if ((methodInst->mCallingConvention == BfCallingConvention_Cdecl) ||
  1951. (methodInst->mCallingConvention == BfCallingConvention_Stdcall))
  1952. {
  1953. addProjectName = false;
  1954. addIndex = false;
  1955. }
  1956. }
  1957. if (addProjectName)
  1958. {
  1959. name += declProject->mName;
  1960. name += '$';
  1961. }
  1962. if (addIndex)
  1963. name += StrFormat("%d$", declType->mPartialIdx);
  1964. }
  1965. if (!mangleContext.mCPPMangle)
  1966. {
  1967. if (methodInst->mMangleWithIdx)
  1968. name += StrFormat("i%d$", methodInst->mMethodDef->mIdx);
  1969. if (methodDef->mCheckedKind == BfCheckedKind_Checked)
  1970. name += "CHK$";
  1971. else if (methodDef->mCheckedKind == BfCheckedKind_Unchecked)
  1972. name += "UCHK$";
  1973. if (methodDef->mHasComptime)
  1974. name += "COMPTIME$";
  1975. }
  1976. /*if ((methodInst->mMethodInstanceGroup->mOwner->mTypeDef->IsGlobalsContainer()) && (methodInst->mMethodDef->mMethodDeclaration == NULL))
  1977. {
  1978. name += methodInst->mMethodInstanceGroup->mOwner->mTypeDef->mProject->mName;
  1979. name += "$";
  1980. }*/
  1981. if (methodInst->GetForeignType() != NULL)
  1982. Mangle(mangleContext, name, methodInst->GetForeignType(), true);
  1983. if (methodInst->GetExplicitInterface() != NULL)
  1984. Mangle(mangleContext, name, methodInst->GetExplicitInterface(), true);
  1985. ///
  1986. {
  1987. // Only use CCompat for params, not for the owning type name - unless we're doing an explicit CPP mangle
  1988. SetAndRestoreValue<bool> prevCCompat(mangleContext.mCCompat, (mangleContext.mCCompat && mangleContext.mCPPMangle) ? true : false);
  1989. Mangle(mangleContext, name, methodInst->GetOwner(), true);
  1990. }
  1991. /*bool isCppDecl = false;
  1992. if (!isCppDecl)
  1993. {
  1994. if (name.EndsWith("@"))
  1995. name.Remove(name.length() - 1);
  1996. FindOrCreateNameSub(mangleContext, name, NameSubstitute(BfMangler::NameSubstitute::Kind_NamespaceAtom, typeInst->mModule->mSystem->mBfAtom));
  1997. name += '@';
  1998. }*/
  1999. //QEA AXXZ
  2000. char attrib ='A';
  2001. if (methodDef->mProtection == BfProtection_Protected)
  2002. attrib = 'I';
  2003. else if (methodDef->mProtection == BfProtection_Public)
  2004. attrib = 'Q';
  2005. bool doExplicitThis = (!methodDef->mIsStatic) && (typeInst->IsTypedPrimitive());
  2006. if ((methodDef->mIsStatic) || (doExplicitThis))
  2007. attrib += 2;
  2008. if ((methodDef->mIsVirtual) && (!methodDef->mIsOverride))
  2009. attrib += 4;
  2010. name += attrib;
  2011. auto bfSystem = methodInst->GetOwner()->mModule->mSystem;
  2012. if ((!methodDef->mIsStatic) && (!doExplicitThis))
  2013. {
  2014. /*char cvQualifier = 'A';
  2015. if (mangleContext.mIs64Bit)
  2016. cvQualifier = 'E';
  2017. name += cvQualifier;*/
  2018. if (mangleContext.mIs64Bit)
  2019. name += "E";
  2020. char qualifier = 'A'; // const / volatile
  2021. name += qualifier;
  2022. }
  2023. auto callingConvention = mangleContext.mModule->GetIRCallingConvention(methodInst);
  2024. char callingConv = 'A';
  2025. if (callingConvention == BfIRCallingConv_StdCall)
  2026. callingConv = 'G';
  2027. else if (callingConvention == BfIRCallingConv_ThisCall)
  2028. callingConv = 'E';
  2029. name += callingConv;
  2030. if (isSpecialFunc)
  2031. name += '@';
  2032. //
  2033. if (!isSpecialFunc)
  2034. {
  2035. bool isConst = false;
  2036. if (methodDeclaration != NULL)
  2037. HandleParamCustomAttributes(methodDeclaration->mAttributes, true, isConst);
  2038. mangleContext.mInRet = true;
  2039. Mangle(mangleContext, name, methodInst->mReturnType, false, isConst);
  2040. mangleContext.mInRet = false;
  2041. }
  2042. if ((methodInst->mParams.size() == 0) && (!doExplicitThis))
  2043. {
  2044. name += 'X';
  2045. }
  2046. else
  2047. {
  2048. // Is this right?
  2049. if (methodInst->GetNumGenericArguments() != 0)
  2050. mangleContext.mSubstituteList.clear();
  2051. mangleContext.mInArgs = true;
  2052. if (doExplicitThis)
  2053. {
  2054. Mangle(mangleContext, name, typeInst->GetUnderlyingType(), true);
  2055. }
  2056. for (int paramIdx = 0; paramIdx < methodInst->mParams.mSize; paramIdx++)
  2057. {
  2058. auto& param = methodInst->mParams[paramIdx];
  2059. bool isConst = false;
  2060. if ((param.mParamDefIdx >= 0) && (methodDeclaration != NULL) && (param.mParamDefIdx < methodDeclaration->mParams.mSize))
  2061. {
  2062. auto paramDecl = methodDeclaration->mParams[param.mParamDefIdx];
  2063. HandleParamCustomAttributes(paramDecl->mAttributes, false, isConst);
  2064. }
  2065. if (!mangleContext.mCPPMangle)
  2066. {
  2067. auto paramKind = methodInst->GetParamKind(paramIdx);
  2068. if (paramKind == BfParamKind_Params)
  2069. name += "Tparams@@";
  2070. else if (paramKind == BfParamKind_DelegateParam)
  2071. name += "Tparam@@";
  2072. }
  2073. Mangle(mangleContext, name, param.mResolvedType, true, isConst);
  2074. }
  2075. name += '@';
  2076. }
  2077. name += 'Z';
  2078. bool wantLog = false;
  2079. if (wantLog)
  2080. {
  2081. BfLog2("Mangling #%d : %s -> %s\n", mangleIdx, mangleContext.mModule->MethodToString(methodInst).c_str(), name.c_str());
  2082. if (!methodInst->mIsUnspecialized)
  2083. {
  2084. String demangled = BfDemangler::Demangle(name, DbgLanguage_Beef);
  2085. BfLog2(" Demangled %d: %s\n", mangleIdx, demangled.c_str());
  2086. }
  2087. }
  2088. }
  2089. void BfMSMangler::Mangle(StringImpl& name, bool is64Bit, BfFieldInstance* fieldInstance)
  2090. {
  2091. auto fieldDef = fieldInstance->GetFieldDef();
  2092. if (fieldDef->mFieldDeclaration != NULL)
  2093. {
  2094. auto module = fieldInstance->mOwner->mModule;
  2095. if ((fieldInstance->mCustomAttributes != NULL) && (fieldInstance->mCustomAttributes->Contains(module->mCompiler->mCLinkAttributeTypeDef)))
  2096. {
  2097. name += fieldDef->mName;
  2098. return;
  2099. }
  2100. }
  2101. BF_ASSERT(fieldDef->mIsStatic);
  2102. MangleContext mangleContext;
  2103. mangleContext.mIs64Bit = is64Bit;
  2104. mangleContext.mModule = fieldInstance->mOwner->mModule;
  2105. bool isCMangle = false;
  2106. HandleCustomAttributes(fieldInstance->mCustomAttributes, fieldInstance->mOwner->mConstHolder, mangleContext.mModule, name, isCMangle, mangleContext.mCPPMangle);
  2107. if (isCMangle)
  2108. name += fieldInstance->GetFieldDef()->mName;
  2109. if (!name.IsEmpty())
  2110. return;
  2111. name += '?';
  2112. AddStr(mangleContext, name, fieldDef->mName);
  2113. Mangle(mangleContext, name, fieldInstance->mOwner, true);
  2114. name += '2'; //TODO: Don't always mark as 'public'
  2115. Mangle(mangleContext, name, fieldInstance->mResolvedType);
  2116. name += ('A' + /*(fieldDef->mIsConst ? 1 : 0) +*/ (fieldDef->mIsVolatile ? 2 : 0));
  2117. }
  2118. void BfMSMangler::MangleMethodName(StringImpl& name, bool is64Bit, BfTypeInstance* type, const StringImpl& methodName)
  2119. {
  2120. MangleContext mangleContext;
  2121. mangleContext.mIs64Bit = is64Bit;
  2122. mangleContext.mModule = type->GetModule();
  2123. name += '?';
  2124. AddStr(mangleContext, name, methodName);
  2125. Mangle(mangleContext, name, type, true);
  2126. name += "SAXXZ";
  2127. }
  2128. void BfMSMangler::MangleStaticFieldName(StringImpl& name, bool is64Bit, BfTypeInstance* owner, const StringImpl& fieldName, BfType* fieldType)
  2129. {
  2130. MangleContext mangleContext;
  2131. mangleContext.mIs64Bit = is64Bit;
  2132. mangleContext.mModule = owner->GetModule();
  2133. name += '?';
  2134. AddStr(mangleContext, name, fieldName);
  2135. Mangle(mangleContext, name, owner, true);
  2136. //name += "@@";
  2137. name += '2'; // public
  2138. if (fieldType == NULL)
  2139. name += 'H';
  2140. else
  2141. Mangle(mangleContext, name, fieldType);
  2142. name += "A"; // static
  2143. }
  2144. //////////////////////////////////////////////////////////////////////////
  2145. String BfSafeMangler::Mangle(BfType* type, BfModule* module)
  2146. {
  2147. MangleContext mangleContext;
  2148. mangleContext.mIs64Bit = true;
  2149. mangleContext.mModule = module;
  2150. mangleContext.mIsSafeMangle = true;
  2151. auto typeInst = type->ToTypeInstance();
  2152. String name;
  2153. if (typeInst != NULL)
  2154. BfMSMangler::Mangle(mangleContext, name, typeInst, true);
  2155. else
  2156. BfMSMangler::Mangle(mangleContext, name, type);
  2157. return name;
  2158. }
  2159. //////////////////////////////////////////////////////////////////////////
  2160. void BfMangler::Mangle(StringImpl& outStr, MangleKind mangleKind, BfType* type, BfModule* module)
  2161. {
  2162. if (mangleKind == BfMangler::MangleKind_GNU)
  2163. outStr += BfGNUMangler::Mangle(type, module);
  2164. else
  2165. BfMSMangler::Mangle(outStr, mangleKind == BfMangler::MangleKind_Microsoft_64, type, module);
  2166. }
  2167. void BfMangler::Mangle(StringImpl& outStr, MangleKind mangleKind, BfMethodInstance* methodInst)
  2168. {
  2169. if (mangleKind == BfMangler::MangleKind_GNU)
  2170. outStr += BfGNUMangler::Mangle(methodInst);
  2171. else
  2172. BfMSMangler::Mangle(outStr, mangleKind == BfMangler::MangleKind_Microsoft_64, methodInst);
  2173. }
  2174. void BfMangler::Mangle(StringImpl& outStr, MangleKind mangleKind, BfFieldInstance* fieldInstance)
  2175. {
  2176. if (mangleKind == BfMangler::MangleKind_GNU)
  2177. {
  2178. outStr += BfGNUMangler::Mangle(fieldInstance);
  2179. }
  2180. else
  2181. BfMSMangler::Mangle(outStr, mangleKind == BfMangler::MangleKind_Microsoft_64, fieldInstance);
  2182. }
  2183. void BfMangler::MangleMethodName(StringImpl& outStr, MangleKind mangleKind, BfTypeInstance* type, const StringImpl& methodName)
  2184. {
  2185. if (mangleKind == BfMangler::MangleKind_GNU)
  2186. outStr += BfGNUMangler::MangleMethodName(type, methodName);
  2187. else
  2188. BfMSMangler::MangleMethodName(outStr, mangleKind == BfMangler::MangleKind_Microsoft_64, type, methodName);
  2189. }
  2190. void BfMangler::MangleStaticFieldName(StringImpl& outStr, MangleKind mangleKind, BfTypeInstance* type, const StringImpl& fieldName, BfType* fieldType)
  2191. {
  2192. if (mangleKind == BfMangler::MangleKind_GNU)
  2193. outStr += BfGNUMangler::MangleStaticFieldName(type, fieldName);
  2194. else
  2195. BfMSMangler::MangleStaticFieldName(outStr, mangleKind == BfMangler::MangleKind_Microsoft_64, type, fieldName, fieldType);
  2196. }
  2197. void BfMangler::HandleCustomAttributes(BfCustomAttributes* customAttributes, BfIRConstHolder* constHolder, BfModule* module, StringImpl& name, bool& isCMangle, bool& isCPPMangle)
  2198. {
  2199. if (customAttributes == NULL)
  2200. return;
  2201. auto linkNameAttr = customAttributes->Get(module->mCompiler->mLinkNameAttributeTypeDef);
  2202. if (linkNameAttr != NULL)
  2203. {
  2204. if (linkNameAttr->mCtorArgs.size() == 1)
  2205. {
  2206. if (module->TryGetConstString(constHolder, linkNameAttr->mCtorArgs[0], name))
  2207. if (!name.IsWhitespace())
  2208. return;
  2209. auto constant = constHolder->GetConstant(linkNameAttr->mCtorArgs[0]);
  2210. if (constant != NULL)
  2211. {
  2212. if (constant->mInt32 == 1) // C
  2213. {
  2214. isCMangle = true;
  2215. }
  2216. else if (constant->mInt32 == 2) // CPP
  2217. {
  2218. isCPPMangle = true;
  2219. }
  2220. }
  2221. }
  2222. }
  2223. }
  2224. void BfMangler::HandleParamCustomAttributes(BfAttributeDirective* attributes, bool isReturn, bool& isConst)
  2225. {
  2226. while (attributes != NULL)
  2227. {
  2228. if (attributes->mAttributeTypeRef != NULL)
  2229. {
  2230. auto typeRefName = attributes->mAttributeTypeRef->ToCleanAttributeString();
  2231. if (typeRefName == "MangleConst")
  2232. isConst = true;
  2233. }
  2234. attributes = attributes->mNextAttribute;
  2235. }
  2236. }