123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460 |
- #include "BfMangler.h"
- #include "BfDemangler.h"
- #include "BfCompiler.h"
- #pragma warning(disable:4996)
- USING_NS_BF;
- int BfGNUMangler::ParseSubIdx(StringImpl& name, int strIdx)
- {
- const char* charPtr = name.c_str() + strIdx + 1;
- if (*charPtr == '_')
- return 0;
- int idx = atoi(charPtr) + 1;
- return idx;
- }
- void BfGNUMangler::AddSubIdx(StringImpl& name, int subIdx)
- {
- name += 'S';
- if (subIdx != 0)
- {
- int showIdx = subIdx - 1;
- if (showIdx > 36)
- {
- name += '0' + (showIdx / 36);
- showIdx %= 36;
- }
- if (showIdx < 10)
- name += '0' + showIdx;
- else
- name += 'A' + (showIdx - 10);
- }
- name += '_';
- }
- void BfGNUMangler::AddSizedString(StringImpl& name, const StringImpl& addStr)
- {
- char str[16];
- itoa((int)addStr.length(), str, 10);
- name += str;
- name += addStr;
- }
- BfTypeCode BfGNUMangler::GetPrimTypeAt(MangleContext& mangleContext, StringImpl& name, int strIdx)
- {
- char startChar = name[strIdx];
- auto module = mangleContext.mModule;
- switch (startChar)
- {
- case 'v': return BfTypeCode_None;
- case 'b': return BfTypeCode_Boolean;
- case 'a': return BfTypeCode_Int8;
- case 'h': return BfTypeCode_UInt8;
- case 's': return BfTypeCode_Int16;
- case 't': return BfTypeCode_UInt16;
- case 'i': return BfTypeCode_Int32;
- case 'j': return BfTypeCode_UInt32;
- case 'l': return BfTypeCode_Int64;
- case 'm': return BfTypeCode_UInt64;
- case 'x': return BfTypeCode_Int64;
- case 'y': return BfTypeCode_UInt64;
- case 'u':
- if (name[strIdx + 1] == '3')
- return BfTypeCode_IntPtr;
- if (name[strIdx + 1] == '4')
- return BfTypeCode_UIntPtr;
- break;
- case 'c': return BfTypeCode_Char8;
- case 'D':
- if (name[strIdx + 1] == 'i')
- return BfTypeCode_Char32;
- else if (name[strIdx + 1] == 's')
- return BfTypeCode_Char16;
- break;
- case 'f': return BfTypeCode_Float;
- case 'd': return BfTypeCode_Double;
- }
- return (BfTypeCode)-1;
- }
- void BfGNUMangler::AddPrefix(MangleContext& mangleContext, StringImpl& name, int startIdx, const char* prefix)
- {
- int subIdx;
- char startChar = name[startIdx];
- if (startChar == 'S')
- {
- subIdx = ParseSubIdx(name, startIdx);
- for (int matchIdx = subIdx + 1; matchIdx < (int)mangleContext.mSubstituteList.size(); matchIdx++)
- {
- auto& entry = mangleContext.mSubstituteList[matchIdx];
- if ((entry.mKind == NameSubstitute::Kind_Prefix) && (entry.mExtendsIdx == subIdx) && (entry.mPrefix == prefix))
- {
- BF_ASSERT(name.EndsWith('_'));
- name.RemoveToEnd(startIdx);
- AddSubIdx(name, matchIdx);
- return;
- }
- }
- }
- else
- {
- auto typeCode = GetPrimTypeAt(mangleContext, name, startIdx);
- if (typeCode != (BfTypeCode)-1)
- {
- for (int matchIdx = 0; matchIdx < (int)mangleContext.mSubstituteList.size(); matchIdx++)
- {
- auto& entry = mangleContext.mSubstituteList[matchIdx];
- if ((entry.mKind == NameSubstitute::Kind_PrimitivePrefix) && (entry.mExtendsTypeCode == typeCode) && (entry.mPrefix == prefix))
- {
- name.RemoveToEnd(startIdx);
- AddSubIdx(name, matchIdx);
- return;
- }
- }
- NameSubstitute nameSub;
- nameSub.mKind = NameSubstitute::Kind_PrimitivePrefix;
- nameSub.mExtendsTypeCode = typeCode;
- nameSub.mPrefix = prefix;
- mangleContext.mSubstituteList.push_back(nameSub);
- name.Insert(startIdx, prefix);
- return;
- }
- else
- {
- // Applies to last-added one
- subIdx = (int)mangleContext.mSubstituteList.size() - 1;
- BF_ASSERT(isdigit(startChar) || (startChar == 'A') || (startChar == 'N') || (startChar == 'P') || (startChar == 'R') || (startChar == 'U'));
- }
- }
- NameSubstitute nameSub;
- nameSub.mKind = NameSubstitute::Kind_Prefix;
- nameSub.mExtendsIdx = subIdx;
- nameSub.mPrefix = prefix;
- mangleContext.mSubstituteList.push_back(nameSub);
- name.Insert(startIdx, prefix);
- }
- void BfGNUMangler::FindOrCreateNameSub(MangleContext& mangleContext, StringImpl& name, const NameSubstitute& newNameSub)
- {
- int curMatchIdx = -1;
- bool matchFailed = false;
- FindOrCreateNameSub(mangleContext, name, newNameSub, curMatchIdx, matchFailed);
- if (!matchFailed)
- AddSubIdx(name, curMatchIdx);
- }
- void BfGNUMangler::FindOrCreateNameSub(MangleContext& mangleContext, StringImpl& name, const NameSubstitute& newNameSub, int& curMatchIdx, bool& matchFailed)
- {
- int parentIdx = curMatchIdx;
- if (!matchFailed)
- {
- curMatchIdx++;
- for ( ; curMatchIdx < (int)mangleContext.mSubstituteList.size(); curMatchIdx++)
- {
- auto& entry = mangleContext.mSubstituteList[curMatchIdx];
- if ((entry.mExtendsIdx == parentIdx) && (entry.mKind == newNameSub.mKind) && (entry.mParam == newNameSub.mParam))
- {
- return;
- }
- }
- matchFailed = true;
- if (newNameSub.mKind != BfGNUMangler::NameSubstitute::Kind_GenericParam)
- name += "N";
- if (parentIdx != -1)
- AddSubIdx(name, parentIdx);
- }
- if (newNameSub.mKind == NameSubstitute::Kind_NamespaceAtom)
- {
- AddSizedString(name, newNameSub.mAtom->mString.mPtr);
- }
- else if (newNameSub.mKind == NameSubstitute::Kind_TypeInstName)
- {
- auto typeDef = newNameSub.mTypeInst->mTypeDef;
- // Mixing this in could create linking errors since the references to the "correct" version won't necessarily be recompiled
- // when we remove the "incorrect" version. I believe this is no longer needed since our compilation model has changed
- /*if (typeDef->mDupDetectedRevision != -1)
- {
- char str[64];
- sprintf(str, "_%p", typeDef);
- name += str;
- }*/
- if ((typeDef->mIsDelegate) && (newNameSub.mTypeInst->IsClosure()))
- {
- auto closureType = (BfClosureType*)newNameSub.mTypeInst;
- if (!closureType->mCreatedTypeDef)
- name += closureType->mNameAdd;
- }
- AddSizedString(name, typeDef->mName->mString.mPtr);
- }
- else if (newNameSub.mKind == BfGNUMangler::NameSubstitute::Kind_TypeGenericArgs)
- {
- int genericParamStart = 0;
- if (newNameSub.mTypeInst->mTypeDef->mOuterType != NULL)
- genericParamStart = (int)newNameSub.mTypeInst->mTypeDef->mOuterType->mGenericParamDefs.size();
- name += "I";
- auto typeDef = newNameSub.mTypeInst->mTypeDef;
- BfType* checkType = newNameSub.mTypeInst;
- if (checkType->IsClosure())
- {
- checkType = ((BfClosureType*)checkType)->mSrcDelegate;
- }
- BF_ASSERT(checkType->IsGenericTypeInstance());
- BfTypeInstance* genericTypeInstance = (BfTypeInstance*)checkType;
- for (int genericParamIdx = genericParamStart; genericParamIdx < (int) typeDef->mGenericParamDefs.size(); genericParamIdx++)
- {
- auto genericParam = genericTypeInstance->mGenericTypeInfo->mTypeGenericArguments[genericParamIdx];
- Mangle(mangleContext, name, genericParam);
- }
- name += "E";
- }
- else if (newNameSub.mKind == BfGNUMangler::NameSubstitute::Kind_GenericParam)
- {
- auto genericParamType = (BfGenericParamType*)newNameSub.mType;
- char str[16];
- if (genericParamType->mGenericParamIdx < 10)
- name += "3";
- else
- name += "4";
- if (genericParamType->mGenericParamKind == BfGenericParamKind_Method)
- name += "`M";
- else
- name += "`T";
- itoa(genericParamType->mGenericParamIdx, str, 10);
- name += str;
- }
- curMatchIdx = (int)mangleContext.mSubstituteList.size();
- mangleContext.mSubstituteList.push_back(newNameSub);
- auto& nameSubRef = mangleContext.mSubstituteList.back();
- nameSubRef.mExtendsIdx = parentIdx;
- }
- void BfGNUMangler::FindOrCreateNameSub(MangleContext& mangleContext, StringImpl& name, BfTypeInstance* typeInst, int& curMatchIdx, bool& matchFailed)
- {
- auto typeDef = typeInst->mTypeDef;
- if (typeDef->IsGlobalsContainer())
- return;
- int numOuterGenericParams = 0;
- if (typeDef->mOuterType != NULL)
- {
- numOuterGenericParams = (int)typeDef->mOuterType->mGenericParamDefs.size();
- auto useModule = typeInst->mModule;
- if (useModule == NULL)
- useModule = mangleContext.mModule;
- auto outerType = useModule->GetOuterType(typeInst);
- if (outerType != NULL)
- FindOrCreateNameSub(mangleContext, name, outerType, curMatchIdx, matchFailed);
- else
- useModule->Fail("Failed to mangle name in BfGNUMangler::FindOrCreateNameSub");
- }
- FindOrCreateNameSub(mangleContext, name, NameSubstitute(NameSubstitute::Kind_TypeInstName, typeInst), curMatchIdx, matchFailed);
- if (typeDef->mGenericParamDefs.size() != numOuterGenericParams)
- {
- FindOrCreateNameSub(mangleContext, name, NameSubstitute(NameSubstitute::Kind_TypeGenericArgs, typeInst), curMatchIdx, matchFailed);
- }
- }
- void BfGNUMangler::MangleTypeInst(MangleContext& mangleContext, StringImpl& name, BfTypeInstance* typeInst, BfTypeInstance* postfixTypeInstance, bool* isEndOpen)
- {
- static int sCallCount = 0;
- sCallCount++;
- if (typeInst->IsTuple())
- {
- auto tupleType = (BfTypeInstance*)typeInst;
- name += "N7__TUPLEI";
- mangleContext.mSubstituteList.push_back(NameSubstitute(BfGNUMangler::NameSubstitute::Kind_None, NULL)); // Insert entry for '__TUPLE'
- for (int fieldIdx = 0; fieldIdx < (int)tupleType->mFieldInstances.size(); fieldIdx++)
- {
- BfFieldInstance* fieldInstance = &tupleType->mFieldInstances[fieldIdx];
- BfFieldDef* fieldDef = fieldInstance->GetFieldDef();
- String fieldName = fieldDef->mName;
- if ((fieldName[0] < '0') || (fieldName[0] > '9'))
- name += StrFormat("U%d`%s", fieldName.length() + 1, fieldName.c_str());
- Mangle(mangleContext, name, fieldInstance->mResolvedType, postfixTypeInstance);
- }
- name += "E";
- mangleContext.mSubstituteList.push_back(NameSubstitute(BfGNUMangler::NameSubstitute::Kind_None, NULL)); // Insert entry for '__TUPLE<T>'
- if (isEndOpen != NULL)
- *isEndOpen = true;
- else
- name += "E";
- return;
- }
- else if ((typeInst->IsDelegateFromTypeRef()) || (typeInst->IsFunctionFromTypeRef()))
- {
- BF_ASSERT(typeInst->mTypeDef->mMethods[0]->mName == "Invoke");
- auto delegateInfo = typeInst->GetDelegateInfo();
- auto methodDef = typeInst->mTypeDef->mMethods[0];
- if (typeInst->IsDelegate())
- name += "N8delegateI";
- else
- name += "N8functionI";
- SizedArray<BfType*, 8> typeVec;
- typeVec.push_back(BfNodeDynCast<BfDirectTypeReference>(methodDef->mReturnTypeRef)->mType);
- if (methodDef->mIsMutating)
- name += "_mut_";
- if (delegateInfo->mCallingConvention == BfCallingConvention_Cdecl)
- name += "_cdecl_";
- else if (delegateInfo->mCallingConvention == BfCallingConvention_Stdcall)
- name += "_stdcall_";
- else if (delegateInfo->mCallingConvention == BfCallingConvention_Fastcall)
- name += "_fastcall_";
- for (int paramIdx = 0; paramIdx < (int)methodDef->mParams.size(); paramIdx++)
- {
- name += "_";
- name += methodDef->mParams[paramIdx]->mName;
- if (methodDef->mParams[paramIdx]->mParamKind == BfParamKind_VarArgs)
- {
- name += "__varargs";
- continue;
- }
- if (methodDef->mParams[paramIdx]->mParamKind == BfParamKind_Params)
- name += "_params_";
- typeVec.push_back(BfNodeDynCast<BfDirectTypeReference>(methodDef->mParams[paramIdx]->mTypeRef)->mType);
- }
- for (auto type : typeVec)
- Mangle(mangleContext, name, type, postfixTypeInstance);
- mangleContext.mSubstituteList.push_back(NameSubstitute(BfGNUMangler::NameSubstitute::Kind_None, NULL)); // Insert entry for 'Delegate'
- name += "E";
- mangleContext.mSubstituteList.push_back(NameSubstitute(BfGNUMangler::NameSubstitute::Kind_None, NULL)); // Insert entry for 'Delegate<T>'
- if (isEndOpen != NULL)
- *isEndOpen = true;
- else
- name += "E";
- name += "E";
- }
- else if (typeInst->IsBoxed())
- {
- auto boxedType = (BfBoxedType*)typeInst;
- name += "N3BoxI";
- mangleContext.mSubstituteList.push_back(NameSubstitute(BfGNUMangler::NameSubstitute::Kind_None, NULL)); // Insert entry for 'Box'
- Mangle(mangleContext, name, boxedType->GetModifiedElementType(), postfixTypeInstance);
- name += "E";
- mangleContext.mSubstituteList.push_back(NameSubstitute(BfGNUMangler::NameSubstitute::Kind_None, NULL)); // Insert entry for 'Box<T>'
- if (isEndOpen != NULL)
- *isEndOpen = true;
- else
- name += "E";
- return;
- }
- int curMatchIdx = -1;
- bool matchFailed = false;
- for (int typeIdx = 0; typeIdx < 2; typeIdx++)
- {
- BfTypeInstance* useTypeInst = typeInst;
- if (typeIdx == 1)
- {
- if (postfixTypeInstance == NULL)
- break;
- useTypeInst = postfixTypeInstance;
- }
- auto typeDef = useTypeInst->mTypeDef;
- if (!mangleContext.mCPPMangle)
- FindOrCreateNameSub(mangleContext, name, NameSubstitute(NameSubstitute::Kind_NamespaceAtom, typeInst->mModule->mSystem->mBfAtom), curMatchIdx, matchFailed);
- for (int i = 0; i < typeDef->mNamespace.mSize; i++)
- FindOrCreateNameSub(mangleContext, name, NameSubstitute(NameSubstitute::Kind_NamespaceAtom, typeDef->mNamespace.mParts[i]), curMatchIdx, matchFailed);
- FindOrCreateNameSub(mangleContext, name, useTypeInst, curMatchIdx, matchFailed);
- }
- if (isEndOpen != NULL)
- {
- if (!matchFailed)
- {
- if (curMatchIdx != -1)
- {
- name += "N";
- AddSubIdx(name, curMatchIdx);
- *isEndOpen = true;
- }
- else
- *isEndOpen = false;
- }
- else
- *isEndOpen = true;
- return;
- }
- if (matchFailed)
- {
- name += "E";
- }
- else
- {
- AddSubIdx(name, curMatchIdx);
- }
- }
- void BfGNUMangler::Mangle(MangleContext& mangleContext, StringImpl& name, BfType* type, BfType* postfixType, bool isConst)
- {
- static int sCallCount = 0;
- sCallCount++;
- if (type->IsPrimitiveType())
- {
- auto primType = (BfPrimitiveType*)type;
- switch (primType->mTypeDef->mTypeCode)
- {
- case BfTypeCode_NullPtr:
- {
- auto pointerType = (BfPointerType*)type;
- int startIdx = (int)name.length();
- name += "v";
- AddPrefix(mangleContext, name, startIdx, "P");
- }
- return;
- case BfTypeCode_Dot:
- name += "U3dot";
- return;
- case BfTypeCode_None:
- if ((mangleContext.mCCompat) || (mangleContext.mInArgs))
- name += "v";
- else
- name += "U4void";
- return;
- case BfTypeCode_Self:
- if ((mangleContext.mCCompat) || (mangleContext.mInArgs))
- name += "U8concrete";
- else
- name += "U4self";
- return;
- case BfTypeCode_Boolean:
- name += "b"; return;
- case BfTypeCode_Int8:
- name += "a"; return;
- case BfTypeCode_UInt8:
- name += "h"; return;
- case BfTypeCode_Int16:
- name += "s"; return;
- case BfTypeCode_UInt16:
- name += "t"; return;
- case BfTypeCode_Int32:
- name += "i"; return;
- case BfTypeCode_UInt32:
- name += "j"; return;
- case BfTypeCode_Int64:
- if ((mangleContext.mModule == NULL) || (mangleContext.mModule->mCompiler->mOptions.mCLongSize == 8))
- name += "l";
- else
- name += "x";
- return;
- case BfTypeCode_UInt64:
- if ((mangleContext.mModule == NULL) || (mangleContext.mModule->mCompiler->mOptions.mCLongSize == 8))
- name += "m";
- else
- name += "y";
- return;
- case BfTypeCode_UIntPtr:
- if ((mangleContext.mCCompat) || (mangleContext.mInArgs))
- {
- if ((mangleContext.mModule == NULL) || (mangleContext.mModule->mCompiler->mOptions.mCLongSize == 8))
- name += (primType->mSize == 8) ? "m" : "j";
- else
- name += (primType->mSize == 8) ? "y" : "j";
- return;
- }
- name += "u4uint";
- return;
- case BfTypeCode_IntPtr:
- if ((mangleContext.mCCompat) || (mangleContext.mInArgs))
- {
- if ((mangleContext.mModule == NULL) || (mangleContext.mModule->mCompiler->mOptions.mCLongSize == 8))
- name += (primType->mSize == 8) ? "l" : "i";
- else
- name += (primType->mSize == 8) ? "x" : "i";
- return;
- }
- name += "u3int";
- return;
- case BfTypeCode_Char8:
- name += "c"; return;
- case BfTypeCode_Char16:
- name += "Ds"; return;
- case BfTypeCode_Char32:
- name += "Di"; return;
- case BfTypeCode_Float:
- name += "f"; return;
- case BfTypeCode_Double:
- name += "d"; return;
- case BfTypeCode_Var:
- if ((mangleContext.mCCompat) || (mangleContext.mInArgs))
- name += "v";
- else
- name += "U3var";
- return;
- case BfTypeCode_Let:
- name += "U3let"; return;
- case BfTypeCode_IntUnknown:
- name += "U4iunk"; return;
- case BfTypeCode_UIntUnknown:
- name += "U4uunk"; return;
- default: break;
- }
- name += "?"; return;
- //name += Mangle(primType->mTypeDef, NULL, addName, NULL, substituteList);
- }
- else if (type->IsTypeInstance())
- {
- BfTypeInstance* postfixTypeInst = NULL;
- if (postfixType != NULL)
- postfixTypeInst = postfixType->ToTypeInstance();
- auto typeInstance = (BfTypeInstance*)type;
- int startIdx = (int)name.length();
- MangleTypeInst(mangleContext, name, typeInstance, postfixTypeInst);
- if ((type->IsObjectOrInterface()) && (mangleContext.mPrefixObjectPointer))
- AddPrefix(mangleContext, name, startIdx, "P");
- }
- else if (type->IsGenericParam())
- {
- FindOrCreateNameSub(mangleContext, name, NameSubstitute(NameSubstitute::Kind_GenericParam, type));
- }
- else if (type->IsPointer())
- {
- auto pointerType = (BfPointerType*)type;
- int startIdx = (int)name.length();
- Mangle(mangleContext, name, pointerType->mElementType);
- AddPrefix(mangleContext, name, startIdx, "P");
- return;
- }
- else if (type->IsRef())
- {
- BfRefType* refType = (BfRefType*)type;
- if (refType->mRefKind == BfRefType::RefKind_In)
- {
- isConst = true;
- }
- else if ((refType->mRefKind == BfRefType::RefKind_Mut) && (!mangleContext.mCCompat))
- {
- name += "U3mut";
- Mangle(mangleContext, name, refType->mElementType);
- return;
- }
- else if ((refType->mRefKind == BfRefType::RefKind_Out) && (!mangleContext.mCCompat))
- {
- name += "U3out";
- Mangle(mangleContext, name, refType->mElementType);
- return;
- }
- int startIdx = (int)name.length();
- Mangle(mangleContext, name, refType->mElementType);
- AddPrefix(mangleContext, name, startIdx, isConst ? "RK" : "R");
- return;
- }
- else if (type->IsModifiedTypeType())
- {
- BfModifiedTypeType* retTypeType = (BfModifiedTypeType*)type;
- if (retTypeType->mModifiedKind == BfToken_RetType)
- name += "U7rettype";
- else if (retTypeType->mModifiedKind == BfToken_AllocType)
- name += "U5alloc";
- else if (retTypeType->mModifiedKind == BfToken_Nullable)
- name += "U8nullable";
- else if (retTypeType->mModifiedKind == BfToken_Params)
- name += "U6params";
- else
- BF_FATAL("Unhandled");
- Mangle(mangleContext, name, retTypeType->mElementType);
- return;
- }
- else if (type->IsConcreteInterfaceType())
- {
- BfConcreteInterfaceType* concreteInterfaceType = (BfConcreteInterfaceType*)type;
- name += "U8concrete";
- Mangle(mangleContext, name, concreteInterfaceType->mInterface);
- return;
- }
- else if (type->IsSizedArray())
- {
- if (type->IsUnknownSizedArrayType())
- {
- BfUnknownSizedArrayType* arrayType = (BfUnknownSizedArrayType*)type;
- name += "A_";
- Mangle(mangleContext, name, arrayType->mElementType);
- name += "_";
- Mangle(mangleContext, name, arrayType->mElementCountSource);
- return;
- }
- else
- {
- BfSizedArrayType* arrayType = (BfSizedArrayType*)type;
- name += StrFormat("A%d_", arrayType->mElementCount);
- Mangle(mangleContext, name, arrayType->mElementType);
- return;
- }
- }
- else if (type->IsMethodRef())
- {
- auto methodRefType = (BfMethodRefType*)type;
- String mrefName = "mref_";
- String mangleName;
- BfMethodInstance* methodInstance = methodRefType->mMethodRef;
- if (methodInstance == NULL)
- {
- BF_ASSERT(!methodRefType->mMangledMethodName.IsEmpty());
- mangleName = methodRefType->mMangledMethodName;
- }
- else
- {
- if (methodInstance->mIsAutocompleteMethod)
- name += "AUTOCOMPLETE";
- auto module = methodInstance->GetOwner()->mModule;
- if (module->mCompiler->mIsResolveOnly)
- {
- // There are cases where we will reprocess a method in ResolveOnly for things like
- // GetSymbolReferences, so we will have duplicate live local methodInstances in those cases
- mrefName += HashEncode64((uint64)methodRefType->mMethodRef);
- }
- else
- {
- mangleName = Mangle(methodInstance);
- methodRefType->mMangledMethodName = mangleName;
- }
- }
- if (!mangleName.IsEmpty())
- {
- Val128 val128 = Hash128(mangleName.c_str(), (int)mangleName.length());
- mrefName += HashEncode128(val128);
- }
- //TODO: Make a 'U' name?
- name += mrefName;
- }
- else if (type->IsConstExprValue())
- {
- BfConstExprValueType* constExprValueType = (BfConstExprValueType*)type;
- int64 val = constExprValueType->mValue.mInt64;
- if ((!constExprValueType->mType->IsPrimitiveType()) ||
- (((BfPrimitiveType*)constExprValueType->mType)->mTypeDef->mTypeCode != BfTypeCode_IntPtr))
- {
- Mangle(mangleContext, name, constExprValueType->mType);
- }
- name += "$0";
- if (val < 0)
- {
- name += "?";
- val = -val;
- }
- if ((val >= 1) && (val < 10))
- {
- name += (char)('0' + val - 1);
- }
- else
- {
- char str[64];
- char* strP = str + 63;
- *strP = 0;
- while (val > 0)
- {
- *(--strP) = (char)((val % 0x10) + 'A');
- val /= 0x10;
- }
- name += strP;
- name += '`';
- }
- if (constExprValueType->mValue.mTypeCode == BfTypeCode_Let)
- name += "Undef";
- }
- else
- {
- BF_FATAL("Not handled");
- }
- }
- String BfGNUMangler::Mangle(BfType* type, BfModule* module)
- {
- StringT<256> name;
- name += "_ZTS";
- MangleContext mangleContext;
- mangleContext.mModule = module;
- Mangle(mangleContext, name, type);
- return name;
- }
- String BfGNUMangler::Mangle(BfMethodInstance* methodInst)
- {
- StringT<256> name;
- if ((methodInst->mMethodDef->mCLink) && (!methodInst->mMangleWithIdx))
- {
- return methodInst->mMethodDef->mName;
- }
- auto methodDef = methodInst->mMethodDef;
- auto methodDeclaration = BfNodeDynCastExact<BfMethodDeclaration>(methodDef->mMethodDeclaration);
- auto typeInst = methodInst->GetOwner();
- auto typeDef = typeInst->mTypeDef;
- MangleContext mangleContext;
- mangleContext.mModule = methodInst->GetOwner()->mModule;
- if (methodInst->mCallingConvention != BfCallingConvention_Unspecified)
- mangleContext.mCCompat = true;
- bool isCMangle = false;
- HandleCustomAttributes(methodInst->GetCustomAttributes(), typeInst->mConstHolder, mangleContext.mModule, name, isCMangle, mangleContext.mCPPMangle);
- if (isCMangle)
- name += methodInst->mMethodDef->mName;
- if (!name.IsEmpty())
- return name;
- bool mangledMethodIdx = false;
- bool prefixLen = false;
- bool isNameOpen = false;
- name += "_Z";
- MangleTypeInst(mangleContext, name, methodInst->mMethodInstanceGroup->mOwner, methodInst->GetExplicitInterface(), &isNameOpen);
- if (methodInst->GetForeignType() != NULL)
- {
- // This won't demangle correctly. TODO: Do this 'correctly'
- MangleTypeInst(mangleContext, name, methodInst->GetForeignType());
- }
- mangleContext.mPrefixObjectPointer = true;
- StringT<128> methodName = methodInst->mMethodDef->mName;
- for (int i = 0; i < (int)methodName.length(); i++)
- {
- if (methodName[i] == '@')
- methodName[i] = '$';
- }
- if ((!mangleContext.mCPPMangle) && (!methodDef->mIsMutating) && (!methodDef->mIsStatic) && (methodInst->GetOwner()->IsValueType()))
- methodName += "__im";
- if (methodInst->mMethodDef->mIsOperator)
- {
- auto operatorDef = (BfOperatorDef*)methodInst->mMethodDef;
- if (operatorDef->mOperatorDeclaration->mIsConvOperator)
- {
- methodName = "cv";
- Mangle(mangleContext, methodName, methodInst->mReturnType);
- }
- else
- {
- switch (operatorDef->mOperatorDeclaration->mBinOp)
- {
- case BfBinaryOp_Add:
- methodName = "pl";
- break;
- case BfBinaryOp_Subtract:
- methodName = "mi";
- break;
- case BfBinaryOp_Multiply:
- methodName = "ml";
- break;
- case BfBinaryOp_OverflowAdd:
- methodName = "opl";
- break;
- case BfBinaryOp_OverflowSubtract:
- methodName = "omi";
- break;
- case BfBinaryOp_OverflowMultiply:
- methodName = "oml";
- break;
- case BfBinaryOp_Divide:
- methodName = "dv";
- break;
- case BfBinaryOp_Modulus:
- methodName = "rm";
- break;
- case BfBinaryOp_BitwiseAnd:
- methodName = "an";
- break;
- case BfBinaryOp_BitwiseOr:
- methodName = "or";
- break;
- case BfBinaryOp_ExclusiveOr:
- methodName = "eo";
- break;
- case BfBinaryOp_LeftShift:
- methodName = "ls";
- break;
- case BfBinaryOp_RightShift:
- methodName = "rs";
- break;
- case BfBinaryOp_Equality:
- methodName = "eq";
- break;
- case BfBinaryOp_InEquality:
- methodName = "ne";
- break;
- case BfBinaryOp_GreaterThan:
- methodName = "gt";
- break;
- case BfBinaryOp_LessThan:
- methodName = "lt";
- break;
- case BfBinaryOp_GreaterThanOrEqual:
- methodName = "ge";
- break;
- case BfBinaryOp_LessThanOrEqual:
- methodName = "le";
- break;
- case BfBinaryOp_ConditionalAnd:
- methodName = "aa";
- break;
- case BfBinaryOp_ConditionalOr:
- methodName = "oo";
- break;
- case BfBinaryOp_NullCoalesce:
- methodName = "2nc";
- break;
- case BfBinaryOp_Is:
- methodName = "2is";
- break;
- case BfBinaryOp_As:
- methodName = "2as";
- break;
- default: break;
- }
- switch (operatorDef->mOperatorDeclaration->mUnaryOp)
- {
- case BfUnaryOp_AddressOf:
- methodName = "ad";
- break;
- case BfUnaryOp_Dereference:
- methodName = "de";
- break;
- case BfUnaryOp_Negate:
- methodName = "ng";
- break;
- case BfUnaryOp_Not:
- methodName = "nt";
- break;
- case BfUnaryOp_Positive:
- methodName = "ps";
- break;
- case BfUnaryOp_InvertBits:
- methodName = "co";
- break;
- case BfUnaryOp_Increment:
- methodName = "pp";
- break;
- case BfUnaryOp_Decrement:
- methodName = "mm";
- break;
- case BfUnaryOp_PostIncrement:
- methodName = "pp";
- break;
- case BfUnaryOp_PostDecrement:
- methodName = "mm";
- break;
- case BfUnaryOp_Ref:
- methodName = "3ref";
- break;
- case BfUnaryOp_Mut:
- methodName = "3mut";
- break;
- case BfUnaryOp_Out:
- methodName = "3out";
- break;
- default: break;
- }
- }
- }
- else if (methodInst->mMethodDef->mMethodType == BfMethodType_Ctor)
- {
- if (methodInst->mMethodDef->mIsStatic)
- {
- methodName = "__BfStaticCtor";
- prefixLen = true;
- }
- else
- methodName = "C1";
- }
- else if (methodInst->mMethodDef->mMethodType == BfMethodType_Dtor)
- {
- if (methodInst->mMethodDef->mIsStatic)
- {
- methodName = "__BfStaticDtor";
- prefixLen = true;
- }
- else
- methodName = "D1";
- }
- else
- {
- if (methodInst->mMangleWithIdx)
- {
- methodName += StrFormat("`%d", methodInst->mMethodDef->mIdx);
- mangledMethodIdx = true;
- }
- prefixLen = true;
- }
- if (!mangleContext.mCPPMangle)
- {
- if (methodDef->mCheckedKind == BfCheckedKind_Checked)
- name += "`CHK";
- else if (methodDef->mCheckedKind == BfCheckedKind_Unchecked)
- name += "`UCHK";
- if (methodDef->mHasComptime)
- name += "`COMPTIME";
- }
- if (((methodInst->GetOwner()->mTypeDef->IsGlobalsContainer()) &&
- ((methodDef->mMethodType == BfMethodType_Ctor) || (methodDef->mMethodType == BfMethodType_Dtor) || (methodDef->mName == BF_METHODNAME_MARKMEMBERS_STATIC))) ||
- ((methodInst->mMethodDef->mDeclaringType->mPartialIdx != -1) && (methodInst->mMethodDef->mDeclaringType->IsExtension()) &&
- (!methodInst->mIsForeignMethodDef) && (!methodInst->mMethodDef->mIsExtern) &&
- ((!methodInst->mMethodDef->mIsOverride) || (methodDef->mName == BF_METHODNAME_MARKMEMBERS) || (methodDef->mMethodType == BfMethodType_Dtor))))
- {
- auto declType = methodInst->mMethodDef->mDeclaringType;
- BF_ASSERT(methodInst->GetOwner()->mTypeDef->mIsCombinedPartial);
- auto declProject = declType->mProject;
- bool addProjectName = (declProject != typeInst->mTypeDef->mProject);
- bool addIndex = true;
- if (typeInst->mTypeDef->IsGlobalsContainer())
- {
- addProjectName = true;
- if ((methodInst->mCallingConvention == BfCallingConvention_Cdecl) ||
- (methodInst->mCallingConvention == BfCallingConvention_Stdcall))
- {
- addProjectName = false;
- addIndex = false;
- }
- }
- if (addProjectName)
- {
- name += declProject->mName;
- name += "$";
- }
- if (addIndex)
- name += StrFormat("%d$", declType->mPartialIdx);
- }
- if ((methodInst->mMangleWithIdx) && (!mangledMethodIdx))
- {
- methodName += StrFormat("`%d", methodInst->mMethodDef->mIdx);
- }
- //
- if ((prefixLen) && (methodInst->mMethodInstanceGroup->mOwner->mTypeDef->IsGlobalsContainer()) && (methodInst->mMethodDef->mMethodDeclaration == NULL))
- {
- methodName += '`';
- methodName += methodInst->mMethodInstanceGroup->mOwner->mTypeDef->mProject->mName;
- }
- if (prefixLen)
- AddSizedString(name, methodName);
- else
- name += methodName;
- if (methodInst->GetNumGenericArguments() != 0)
- {
- auto& methodGenericArguments = methodInst->mMethodInfoEx->mMethodGenericArguments;
- NameSubstitute nameSub(NameSubstitute::Kind_MethodName, methodInst);
- nameSub.mExtendsIdx = (int)mangleContext.mSubstituteList.size() - 1;
- mangleContext.mSubstituteList.push_back(nameSub);
- name += 'I';
- for (auto genericArg : methodGenericArguments)
- Mangle(mangleContext, name, genericArg);
- name += 'E';
- }
- else if (methodInst->mMethodDef->mGenericParams.size() != 0)
- {
- NameSubstitute nameSub(NameSubstitute::Kind_MethodName, methodInst);
- nameSub.mExtendsIdx = (int)mangleContext.mSubstituteList.size() - 1;
- mangleContext.mSubstituteList.push_back(nameSub);
- name += 'I';
- for (auto genericArg : methodInst->mMethodDef->mGenericParams)
- name += 'v';
- name += 'E';
- }
- if (isNameOpen)
- name += 'E';
- if (methodInst->mMethodDef->mGenericParams.size() != 0)
- Mangle(mangleContext, name, methodInst->mReturnType);
- mangleContext.mInArgs = true;
- bool doExplicitThis = (!methodDef->mIsStatic) && (typeInst->IsTypedPrimitive());
- if (doExplicitThis) // Explicit "_this"
- Mangle(mangleContext, name, typeInst->GetUnderlyingType());
- for (int paramIdx = 0; paramIdx < (int)methodInst->GetParamCount(); paramIdx++)
- {
- BfType* paramType = methodInst->GetParamType(paramIdx);
- bool isConst = false;
- if ((methodDeclaration != NULL) && (paramIdx < methodDeclaration->mParams.mSize))
- {
- auto paramDecl = methodDeclaration->mParams[paramIdx];
- HandleParamCustomAttributes(paramDecl->mAttributes, false, isConst);
- }
- if (!mangleContext.mCPPMangle)
- {
- auto paramKind = methodInst->GetParamKind(paramIdx);
- if (paramKind == BfParamKind_Params)
- name += "U6params";
- else if (paramKind == BfParamKind_DelegateParam)
- name += "U5param";
- }
- if ((paramType->IsVoid()) && (methodInst->GetParamCount() == 1))
- {
- // Avoid collision between 'Method()' and 'Method(void)'
- name += "U4void";
- }
- else
- Mangle(mangleContext, name, paramType, NULL, isConst);
- }
- if ((methodInst->GetParamCount() == 0) && (!doExplicitThis))
- name += 'v';
- return name;
- }
- String BfGNUMangler::MangleMethodName(BfTypeInstance* type, const StringImpl& methodName)
- {
- MangleContext mangleContext;
- mangleContext.mModule = type->mModule;
- StringT<256> name = "_Z";
- auto typeInst = type->ToTypeInstance();
- BF_ASSERT(typeInst != NULL);
- bool isNameOpen;
- MangleTypeInst(mangleContext, name, typeInst, NULL, &isNameOpen);
- AddSizedString(name, methodName);
- if (isNameOpen)
- name += "E";
- name += "v";
- return name;
- }
- String BfGNUMangler::MangleStaticFieldName(BfTypeInstance* type, const StringImpl& fieldName)
- {
- MangleContext mangleContext;
- mangleContext.mModule = type->mModule;
- auto typeInst = type->ToTypeInstance();
- auto typeDef = typeInst->mTypeDef;
- if ((typeDef->IsGlobalsContainer()) && (typeDef->mNamespace.IsEmpty()))
- return fieldName;
- StringT<256> name = "_Z";
- bool isNameOpen;
- MangleTypeInst(mangleContext, name, typeInst, NULL, &isNameOpen);
- AddSizedString(name, fieldName);
- if (isNameOpen)
- name += "E";
- return name;
- }
- String BfGNUMangler::Mangle(BfFieldInstance* fieldInstance)
- {
- StringT<256> name;
- MangleContext mangleContext;
- mangleContext.mModule = fieldInstance->mOwner->mModule;
- bool isCMangle = false;
- HandleCustomAttributes(fieldInstance->mCustomAttributes, fieldInstance->mOwner->mConstHolder, mangleContext.mModule, name, isCMangle, mangleContext.mCPPMangle);
- if (isCMangle)
- name += fieldInstance->GetFieldDef()->mName;
- if (!name.IsEmpty())
- return name;
- auto typeInst = fieldInstance->mOwner->ToTypeInstance();
- auto typeDef = typeInst->mTypeDef;
- if ((typeDef->IsGlobalsContainer()) && (typeDef->mNamespace.IsEmpty()))
- return fieldInstance->GetFieldDef()->mName;
- name += "_Z";
- bool isNameOpen;
- MangleTypeInst(mangleContext, name, typeInst, NULL, &isNameOpen);
- AddSizedString(name, fieldInstance->GetFieldDef()->mName);
- if (isNameOpen)
- name += "E";
- return name;
- }
- //////////////////////////////////////////////////////////////////////////
- BfModule* BfMSMangler::MangleContext::GetUnreifiedModule()
- {
- if (mModule == NULL)
- return NULL;
- return mModule->mContext->mUnreifiedModule;
- }
- //////////////////////////////////////////////////////////////////////////
- void BfMSMangler::AddGenericArgs(MangleContext& mangleContext, StringImpl& name, const SizedArrayImpl<BfType*>& genericArgs, int numOuterGenericParams)
- {
- if (numOuterGenericParams == (int)genericArgs.size())
- return;
- auto prevSubList = mangleContext.mSubstituteList;
- auto prevSubTypeList = mangleContext.mSubstituteTypeList;
- mangleContext.mSubstituteList.clear();
- for (int genericIdx = numOuterGenericParams; genericIdx < (int)genericArgs.size(); genericIdx++)
- Mangle(mangleContext, name, genericArgs[genericIdx]);
- mangleContext.mSubstituteList = prevSubList;
- mangleContext.mSubstituteTypeList = prevSubTypeList;
- }
- void BfMSMangler::AddStr(MangleContext& mangleContext, StringImpl& name, const StringImpl& str)
- {
- if ((int)mangleContext.mSubstituteList.size() < 10)
- {
- // Add NULL entry... shouldn't match anything
- mangleContext.mSubstituteList.push_back(NameSubstitute(NameSubstitute::Kind_None, NULL));
- }
- name += str;
- name += '@';
- }
- void BfMSMangler::AddSubIdx(StringImpl& name, int strIdx)
- {
- //TODO: BF_ASSERT(strIdx < 10);
- char str[16];
- itoa(strIdx, str, 10);
- name += str;
- }
- void BfMSMangler::AddTypeStart(MangleContext& mangleContext, StringImpl& name, BfType* type)
- {
- if (mangleContext.mIsSafeMangle)
- {
- name += "V"; // Mangle everything as a struct so we don't need to require the type to be populated
- return;
- }
- if (!type->IsDeclared())
- {
- if (mangleContext.mModule != NULL)
- {
- auto unreifiedModule = mangleContext.GetUnreifiedModule();
- if (unreifiedModule != NULL)
- unreifiedModule->PopulateType(type, BfPopulateType_Declaration);
- }
- else
- {
- BF_FATAL("No module");
- }
- }
- if ((type->IsEnum()) && (type->IsTypedPrimitive()))
- {
- auto unreifiedModule = mangleContext.GetUnreifiedModule();
- if (type->mDefineState >= BfTypeDefineState_Defined)
- {
- BF_ASSERT(type->mSize >= 0);
- }
- // The enum size is supposed to be encoded, but VC always uses '4'
- //name += "W";
- //name += ('0' + type->mSize);
- name += "W4";
- return;
- }
- name += type->IsStruct() ? "U" : "V";
- }
- bool BfMSMangler::FindOrCreateNameSub(MangleContext& mangleContext, StringImpl& name, const NameSubstitute& newNameSub)
- {
- for (int curMatchIdx = 0; curMatchIdx < (int)mangleContext.mSubstituteList.size(); curMatchIdx++)
- {
- auto& entry = mangleContext.mSubstituteList[curMatchIdx];
- if ((entry.mKind == newNameSub.mKind) && (entry.mParam == newNameSub.mParam) && (entry.mExtendsTypeId == newNameSub.mExtendsTypeId))
- {
- AddSubIdx(name, curMatchIdx);
- return true;
- }
- }
- if (newNameSub.mKind == NameSubstitute::Kind_NamespaceAtom)
- {
- name += newNameSub.mAtom->mString;
- name += '@';
- }
- else if (newNameSub.mKind == NameSubstitute::Kind_TypeInstName)
- {
- if (mangleContext.mWantsGroupStart)
- {
- AddTypeStart(mangleContext, name, newNameSub.mTypeInst);
- mangleContext.mWantsGroupStart = false;
- }
- if (newNameSub.mTypeInst->IsTuple())
- {
- auto tupleType = (BfTypeInstance*)newNameSub.mType;
- name += "?$__TUPLE";
- SizedArray<BfType*, 8> typeVec;
- for (auto& fieldInst : tupleType->mFieldInstances)
- {
- BfFieldDef* fieldDef = fieldInst.GetFieldDef();
- String fieldName = fieldDef->mName;
- if ((fieldName[0] < '0') || (fieldName[0] > '9'))
- name += StrFormat("_%s", fieldName.c_str());
- typeVec.push_back(fieldInst.mResolvedType);
- }
- name += '@';
- if (!typeVec.empty())
- AddGenericArgs(mangleContext, name, typeVec);
- name += '@';
- }
- else if ((newNameSub.mTypeInst->IsDelegateFromTypeRef()) || (newNameSub.mTypeInst->IsFunctionFromTypeRef()))
- {
- BF_ASSERT(newNameSub.mTypeInst->mTypeDef->mMethods[0]->mName == "Invoke");
- auto delegateInfo = newNameSub.mTypeInst->GetDelegateInfo();
- auto methodDef = newNameSub.mTypeInst->mTypeDef->mMethods[0];
- if (newNameSub.mTypeInst->IsDelegate())
- name += "?$delegate";
- else
- name += "?$function";
- if (methodDef->mIsMutating)
- name += "_mut_";
- if (delegateInfo->mCallingConvention == BfCallingConvention_Cdecl)
- name += "_cdecl_";
- else if (delegateInfo->mCallingConvention == BfCallingConvention_Stdcall)
- name += "_stdcall_";
- else if (delegateInfo->mCallingConvention == BfCallingConvention_Fastcall)
- name += "_fastcall_";
- SizedArray<BfType*, 8> typeVec;
- typeVec.push_back(BfNodeDynCast<BfDirectTypeReference>(methodDef->mReturnTypeRef)->mType);
- for (int paramIdx = 0; paramIdx < (int)methodDef->mParams.size(); paramIdx++)
- {
- name += "_";
- name += methodDef->mParams[paramIdx]->mName;
- if (methodDef->mParams[paramIdx]->mParamKind == BfParamKind_VarArgs)
- {
- name += "__varargs";
- continue;
- }
- if (methodDef->mParams[paramIdx]->mParamKind == BfParamKind_Params)
- name += "_params_";
- typeVec.push_back(BfNodeDynCast<BfDirectTypeReference>(methodDef->mParams[paramIdx]->mTypeRef)->mType);
- }
- name += '@';
- if (!typeVec.empty())
- AddGenericArgs(mangleContext, name, typeVec);
- name += '@';
- }
- else if (newNameSub.mTypeInst->IsBoxed())
- {
- auto boxedType = (BfBoxedType*)newNameSub.mTypeInst;
- name += "?$Box@";
- SizedArray<BfType*, 8> typeVec;
- typeVec.push_back(boxedType->GetModifiedElementType());
- AddGenericArgs(mangleContext, name, typeVec);
- name += '@';
- }
- else
- {
- auto typeDef = newNameSub.mTypeInst->mTypeDef;
- BfTypeInstance* genericTypeInst = NULL;
- if (newNameSub.mTypeInst->IsGenericTypeInstance())
- genericTypeInst = (BfTypeInstance*)newNameSub.mTypeInst;
- int numOuterGenericParams = 0;
- if ((!mangleContext.mIsSafeMangle) && (typeDef->mOuterType != NULL))
- {
- numOuterGenericParams = (int)typeDef->mOuterType->mGenericParamDefs.size();
- }
- if (genericTypeInst != NULL)
- {
- // If we don't have our own generic params then don't treat us as a generic
- if ((int)typeDef->mGenericParamDefs.size() == numOuterGenericParams)
- genericTypeInst = NULL;
- }
- if (genericTypeInst != NULL)
- {
- name += "?$";
- mangleContext.mWantsGroupStart = false;
- }
- // name += *typeDef->mName->mString;
- // if ((typeDef->mIsDelegate) && (newNameSub.mTypeInst->IsClosure()))
- // {
- // auto closureType = (BfClosureType*)newNameSub.mTypeInst;
- // if (!closureType->mCreatedTypeDef)
- // name += closureType->mNameAdd;
- // }
- if (newNameSub.mTypeInst->IsClosure())
- {
- auto closureType = (BfClosureType*)newNameSub.mTypeInst;
- name += closureType->mSrcDelegate->mTypeDef->mName->mString;
- name += closureType->mNameAdd;
- }
- else
- {
- name += typeDef->mName->mString;
- }
- name += '@';
- if (genericTypeInst != NULL)
- {
- AddGenericArgs(mangleContext, name, genericTypeInst->mGenericTypeInfo->mTypeGenericArguments, numOuterGenericParams);
- name += '@';
- }
- }
- }
- else if (newNameSub.mKind == BfGNUMangler::NameSubstitute::Kind_GenericParam)
- {
- name += "U"; // Struct
- auto genericParamType = (BfGenericParamType*)newNameSub.mType;
- if (genericParamType->mGenericParamKind == BfGenericParamKind_Method)
- name += "_M";
- else
- name += "_T";
- char str[16];
- itoa(genericParamType->mGenericParamIdx, str, 10);
- name += str;
- name += '@';
- name += '@';
- }
- mangleContext.mSubstituteList.push_back(newNameSub);
- return false;
- }
- void BfMSMangler::Mangle(MangleContext& mangleContext, StringImpl& name, BfTypeInstance* typeInstance, bool isAlreadyStarted, bool isOuterType)
- {
- BfTypeInstance* genericTypeInst = NULL;
- if (typeInstance->IsGenericTypeInstance())
- {
- genericTypeInst = (BfTypeInstance*)typeInstance;
- }
- auto typeDef = typeInstance->mTypeDef;
- bool hasNamespace = typeDef->mNamespace.mSize != 0;
- if (!isAlreadyStarted)
- {
- if ((hasNamespace) || (typeDef->mOuterType != NULL))
- {
- AddTypeStart(mangleContext, name, typeInstance);
- }
- else
- {
- if (typeDef->IsGlobalsContainer())
- return;
- mangleContext.mWantsGroupStart = true;
- }
- }
- if (!typeDef->IsGlobalsContainer())
- FindOrCreateNameSub(mangleContext, name, NameSubstitute(BfMangler::NameSubstitute::Kind_TypeInstName, typeInstance));
- mangleContext.mWantsGroupStart = false;
- auto useModule = typeInstance->mModule;
- if (useModule == NULL)
- useModule = mangleContext.mModule;
- if ((typeDef->mOuterType != NULL) && (!typeInstance->IsBoxed()))
- {
- if (mangleContext.mIsSafeMangle)
- {
- auto outerType = typeDef->mOuterType;
- while (outerType != NULL)
- {
- name += ":";
- name += outerType->mFullName.ToString();
- outerType = outerType->mOuterType;
- }
- }
- else
- {
- auto unreifiedModule = useModule->mContext->mUnreifiedModule;
- auto outerType = unreifiedModule->GetOuterType(typeInstance);
- if (outerType != NULL)
- Mangle(mangleContext, name, outerType, true, true);
- else
- useModule->Fail("Failed to mangle name in BfMSMangler::Mangle");
- }
- }
- if (!isOuterType)
- {
- if (!typeInstance->IsBoxed())
- {
- for (int namespaceIdx = (int)typeDef->mNamespace.mSize - 1; namespaceIdx >= 0; namespaceIdx--)
- {
- auto namePart = typeDef->mNamespace.mParts[namespaceIdx];
- FindOrCreateNameSub(mangleContext, name, NameSubstitute(BfMangler::NameSubstitute::Kind_NamespaceAtom, namePart));
- }
- if (!mangleContext.mCPPMangle)
- FindOrCreateNameSub(mangleContext, name, NameSubstitute(BfMangler::NameSubstitute::Kind_NamespaceAtom, useModule->mSystem->mBfAtom));
- }
- name += '@';
- }
- }
- void BfMSMangler::MangleConst(MangleContext & mangleContext, StringImpl & name, int64 val)
- {
- name += "$0";
- if (val < 0)
- {
- name += "?";
- val = -val;
- }
- if ((val > 0) && (val <= 10))
- {
- name += (char)('0' + val - 1);
- }
- else
- {
- char str[64];
- char* strP = str + 63;
- *strP = 0;
- while (val > 0)
- {
- *(--strP) = (char)((val % 0x10) + 'A');
- val /= 0x10;
- }
- name += strP;
- name += '@';
- }
- }
- void BfMSMangler::AddPrefix(MangleContext& mangleContext, StringImpl& name, int startIdx, const char* prefix)
- {
- int subIdx;
- char startChar = name[startIdx];
- if ((startChar >= '0') && (startChar <= '9'))
- {
- //subIdx = ParseSubIdx(name, startIdx);
- subIdx = startChar - '0';
- for (int matchIdx = subIdx + 1; matchIdx < (int)mangleContext.mSubstituteList.size(); matchIdx++)
- {
- auto& entry = mangleContext.mSubstituteList[matchIdx];
- if ((entry.mKind == NameSubstitute::Kind_Prefix) && (entry.mExtendsIdx == subIdx) && (entry.mPrefix == prefix))
- {
- BF_ASSERT(name.EndsWith('_'));
- name.RemoveToEnd(startIdx);
- AddSubIdx(name, matchIdx);
- return;
- }
- }
- }
- else
- {
- //auto typeCode = GetPrimTypeAt(mangleContext, name, startIdx);
- auto typeCode = BfTypeCode_None;
- if (typeCode != (BfTypeCode)-1)
- {
- for (int matchIdx = 0; matchIdx < (int)mangleContext.mSubstituteList.size(); matchIdx++)
- {
- auto& entry = mangleContext.mSubstituteList[matchIdx];
- if ((entry.mKind == NameSubstitute::Kind_PrimitivePrefix) && (entry.mExtendsTypeCode == typeCode) && (entry.mPrefix == prefix))
- {
- name.RemoveToEnd(startIdx);
- AddSubIdx(name, matchIdx);
- return;
- }
- }
- NameSubstitute nameSub;
- nameSub.mKind = NameSubstitute::Kind_PrimitivePrefix;
- nameSub.mExtendsTypeCode = typeCode;
- nameSub.mPrefix = prefix;
- mangleContext.mSubstituteList.push_back(nameSub);
- name.Insert(startIdx, prefix);
- return;
- }
- else
- {
- // Applies to last-added one
- subIdx = (int)mangleContext.mSubstituteList.size() - 1;
- BF_ASSERT(isdigit(startChar) || (startChar == 'N') || (startChar == 'P') || (startChar == 'R'));
- }
- }
- NameSubstitute nameSub;
- nameSub.mKind = NameSubstitute::Kind_Prefix;
- nameSub.mExtendsIdx = subIdx;
- nameSub.mPrefix = prefix;
- mangleContext.mSubstituteList.push_back(nameSub);
- name.Insert(startIdx, prefix);
- }
- void BfMSMangler::Mangle(MangleContext& mangleContext, StringImpl& name, BfType* type, bool useTypeList, bool isConst)
- {
- bool isLongPrim = false;
- if (type->IsPrimitiveType())
- {
- auto primType = (BfPrimitiveType*)type;
- switch (primType->mTypeDef->mTypeCode)
- {
- case BfTypeCode_NullPtr:
- {
- name += "P";
- if (mangleContext.mIs64Bit)
- name += "E";
- name += "AV";
- name += "v";
- }
- return;
- case BfTypeCode_None:
- name += "X"; return;
- case BfTypeCode_Int8:
- name += "C"; return;
- case BfTypeCode_UInt8:
- name += "E"; return;
- case BfTypeCode_Int16:
- name += "F"; return;
- case BfTypeCode_UInt16:
- name += "G"; return;
- case BfTypeCode_Int32:
- name += "H"; return;
- case BfTypeCode_UInt32:
- name += "I"; return;
- case BfTypeCode_Char8:
- name += "D"; return;
- case BfTypeCode_Char16:
- name += "_S"; return; //char16_t
- case BfTypeCode_Float:
- name += "M"; return;
- case BfTypeCode_Double:
- name += "N"; return;
- case BfTypeCode_Int64:
- case BfTypeCode_UInt64:
- case BfTypeCode_Boolean:
- case BfTypeCode_Char32:
- isLongPrim = true;
- break;
- case BfTypeCode_IntPtr:
- if ((primType->mSize == 4) && (mangleContext.mCCompat))
- {
- name += "H";
- return;
- }
- isLongPrim = true;
- break;
- case BfTypeCode_UIntPtr:
- if ((primType->mSize == 4) && (mangleContext.mCCompat))
- {
- name += "I";
- return;
- }
- isLongPrim = true;
- break;
- case BfTypeCode_Dot:
- name += "Tdot@@"; return;
- case BfTypeCode_Var:
- if ((mangleContext.mCCompat) || (mangleContext.mInArgs))
- name += "X";
- else
- name += "Tvar@@";
- return;
- case BfTypeCode_Self:
- if ((mangleContext.mCCompat) || (mangleContext.mInArgs))
- name += "X";
- else
- name += "Tself@@";
- return;
- case BfTypeCode_Let:
- name += "Tlet@@"; return;
- case BfTypeCode_IntUnknown:
- name += "Tiunk@@"; return;
- case BfTypeCode_UIntUnknown:
- name += "Tuunk@@"; return;
- default:
- name += "?"; return;
- }
- }
- if (useTypeList)
- {
- for (int checkIdx = 0; checkIdx < (int)mangleContext.mSubstituteTypeList.size(); checkIdx++)
- {
- if (mangleContext.mSubstituteTypeList[checkIdx] == type)
- {
- name += ('0' + checkIdx);
- return;
- }
- }
- }
- if (isLongPrim)
- {
- auto primType = (BfPrimitiveType*)type;
- switch (primType->mTypeDef->mTypeCode)
- {
- case BfTypeCode_Boolean:
- name += "_N"; break;
- case BfTypeCode_Int64:
- name += "_J"; break;
- case BfTypeCode_UInt64:
- name += "_K"; break;
- case BfTypeCode_UIntPtr:
- if (primType->mSize == 4)
- name += "_I";
- else if (mangleContext.mCCompat)
- name += "_K";
- else
- name += "Tuint@@";
- break;
- case BfTypeCode_IntPtr:
- if (primType->mSize == 4)
- name += "_H";
- else if (mangleContext.mCCompat)
- name += "_J";
- else
- name += "Tint@@";
- break;
- case BfTypeCode_Char32:
- name += "_U"; break;
- default: break;
- }
- }
- else if (type->IsTypeInstance())
- {
- auto typeInstance = (BfTypeInstance*)type;
- auto typeDef = typeInstance->mTypeDef;
- if (type->IsObjectOrInterface())
- {
- name += "P";
- if (mangleContext.mIs64Bit)
- name += "E";
- name += "A";
- }
- else if (((type->IsGenericTypeInstance()) || (type->IsComposite()) || (type->IsEnum())) && (mangleContext.mInRet))
- name += "?A";
- Mangle(mangleContext, name, typeInstance, false);
- }
- else if (type->IsGenericParam())
- {
- FindOrCreateNameSub(mangleContext, name, NameSubstitute(BfMangler::NameSubstitute::Kind_GenericParam, type));
- }
- else if (type->IsPointer())
- {
- auto pointerType = (BfPointerType*)type;
- const char* strAdd = mangleContext.mIs64Bit ? "PEA" : "PA";
- if (mangleContext.mIs64Bit)
- name += "PE";
- else
- name += "P";
- if (isConst)
- name += "B";
- else
- name += "A";
- Mangle(mangleContext, name, pointerType->mElementType);
- }
- else if (type->IsRef())
- {
- auto refType = (BfRefType*)type;
- name += "A";
- if (mangleContext.mIs64Bit)
- name += "E";
- if ((isConst) || (refType->mRefKind == BfRefType::RefKind_In))
- name += "B";
- else
- name += "A";
- if (refType->mRefKind == BfRefType::RefKind_Mut)
- name += "mut$";
- else if (refType->mRefKind == BfRefType::RefKind_Out)
- name += "out$";
- Mangle(mangleContext, name, refType->mElementType);
- }
- else if (type->IsModifiedTypeType())
- {
- auto retType = (BfModifiedTypeType*)type;
- if (retType->mModifiedKind == BfToken_RetType)
- name += "rettype$";
- else if (retType->mModifiedKind == BfToken_AllocType)
- name += "alloc$";
- else if (retType->mModifiedKind == BfToken_Nullable)
- name += "nullable$";
- else if (retType->mModifiedKind == BfToken_Params)
- name += "params$";
- else
- BF_FATAL("Unhandled");
- Mangle(mangleContext, name, retType->mElementType);
- }
- else if (type->IsConcreteInterfaceType())
- {
- auto concreteType = (BfConcreteInterfaceType*)type;
- name += "concrete$";
- Mangle(mangleContext, name, concreteType->mInterface);
- }
- else if (type->IsSizedArray())
- {
- if (type->IsUnknownSizedArrayType())
- {
- auto arrType = (BfUnknownSizedArrayType*)type;
- name += StrFormat("arr_$", arrType->mSize);
- Mangle(mangleContext, name, arrType->mElementType);
- name += "$";
- Mangle(mangleContext, name, arrType->mElementCountSource);
- }
- else
- {
- // We can't use MS mangling of "_O" because it isn't size-specific
- auto arrType = (BfSizedArrayType*)type;
- //name += StrFormat("arr_%d$", arrType->mSize);
- //Mangle(mangleContext, name, arrType->mElementType);
- name += "?$_ARRAY@";
- Mangle(mangleContext, name, arrType->mElementType);
- MangleConst(mangleContext, name, arrType->mElementCount);
- name += '@';
- }
- }
- else if (type->IsMethodRef())
- {
- auto methodRefType = (BfMethodRefType*)type;
- name += "Tmref_";
- StringT<128> mangleName;
- BfMethodInstance* methodInstance = methodRefType->mMethodRef;
- if (methodInstance == NULL)
- {
- BF_ASSERT(!methodRefType->mMangledMethodName.IsEmpty());
- mangleName = methodRefType->mMangledMethodName;
- }
- else
- {
- if (methodInstance->mIsAutocompleteMethod)
- name += "AUTOCOMPLETE";
- auto module = methodInstance->GetOwner()->mModule;
- if (module->mCompiler->mIsResolveOnly)
- {
- // There are cases where we will reprocess a method in ResolveOnly for things like
- // GetSymbolReferences, so we will have duplicate live local methodInstances in those cases
- name += HashEncode64((uint64)methodRefType->mMethodRef);
- }
- else
- {
- Mangle(mangleName, mangleContext.mIs64Bit, methodInstance);
- methodRefType->mMangledMethodName = mangleName;
- }
- }
- if (!mangleName.IsEmpty())
- {
- Val128 val128 = Hash128(mangleName.c_str(), (int)mangleName.length());
- name += HashEncode128(val128);
- }
- // if (methodInstance->mIsAutocompleteMethod)
- // name += "AUTOCOMPLETE";
- //
- // String mangleAdd = Mangle(mangleContext.mIs64Bit, methodInstance);
- //
- // auto module = methodInstance->GetOwner()->mModule;
- // if (module->mCompiler->mIsResolveOnly)
- // {
- // // There are cases where we will reprocess a method in ResolveOnly for things like
- // // GetSymbolReferences, so we will have duplicate live local methodInstances in those cases
- // name += HashEncode64((uint64)methodRefType->mMethodRef);
- // }
- // else
- // {
- // Val128 val128 = Hash128(mangleAdd.c_str(), (int)mangleAdd.length());
- // name += HashEncode128(val128);
- // }
- name += "@@";
- }
- else if (type->IsConstExprValue())
- {
- BfConstExprValueType* constExprValueType = (BfConstExprValueType*)type;
- int64 val = constExprValueType->mValue.mInt64;
- if ((!constExprValueType->mType->IsPrimitiveType()) ||
- (((BfPrimitiveType*)constExprValueType->mType)->mTypeDef->mTypeCode != BfTypeCode_IntPtr))
- {
- Mangle(mangleContext, name, constExprValueType->mType);
- name += "$";
- }
- MangleConst(mangleContext, name, val);
- if (constExprValueType->mValue.mTypeCode == BfTypeCode_Let)
- name += "Undef";
- }
- else
- {
- BF_ASSERT("Unhandled");
- }
- if ((useTypeList) && (!mangleContext.mInRet) && ((int)mangleContext.mSubstituteTypeList.size() < 10))
- mangleContext.mSubstituteTypeList.push_back(type);
- }
- void BfMSMangler::Mangle(StringImpl& name, bool is64Bit, BfType* type, BfModule* module)
- {
- if (type->IsTypeAlias())
- {
- auto typeAlias = (BfTypeAliasType*)type;
- name += "__ALIAS_";
- name += typeAlias->mTypeDef->mName->ToString();
- name += '@';
- Mangle(name, is64Bit, typeAlias->mAliasToType, module);
- return;
- }
- MangleContext mangleContext;
- mangleContext.mIs64Bit = is64Bit;
- mangleContext.mModule = module;
- auto typeInst = type->ToTypeInstance();
- if ((typeInst != NULL) && (typeInst->mModule != NULL))
- mangleContext.mModule = typeInst->mModule;
- if (typeInst != NULL)
- Mangle(mangleContext, name, typeInst, true);
- else
- Mangle(mangleContext, name, type);
- while ((name.length() > 0) && (name[name.length() - 1] == '@'))
- name.Remove(name.length() - 1);
- }
- void BfMSMangler::Mangle(StringImpl& name, bool is64Bit, BfMethodInstance* methodInst)
- {
- static int mangleIdx = 0;
- mangleIdx++;
- int startNameLen = name.mLength;
- if ((methodInst->mMethodDef->mCLink) && (!methodInst->mMangleWithIdx))
- {
- name += methodInst->mMethodDef->mName;
- return;
- }
- auto methodDef = methodInst->mMethodDef;
- auto methodDeclaration = BfNodeDynCastExact<BfMethodDeclaration>(methodDef->mMethodDeclaration);
- auto typeInst = methodInst->GetOwner();
- auto typeDef = typeInst->mTypeDef;
- MangleContext mangleContext;
- mangleContext.mIs64Bit = is64Bit;
- mangleContext.mModule = methodInst->GetOwner()->mModule;
- if (methodInst->mCallingConvention != BfCallingConvention_Unspecified)
- mangleContext.mCCompat = true;
- bool isCMangle = false;
- HandleCustomAttributes(methodInst->GetCustomAttributes(), typeInst->mConstHolder, mangleContext.mModule, name, isCMangle, mangleContext.mCPPMangle);
- if (isCMangle)
- name += methodInst->mMethodDef->mName;
- if (name.mLength > startNameLen)
- return;
- name += '?';
- if (methodInst->GetNumGenericArguments() != 0)
- {
- name += "?$";
- }
- bool isSpecialFunc = false;
- if (methodInst->mMethodDef->mIsOperator)
- {
- String methodName;
- auto operatorDef = (BfOperatorDef*)methodInst->mMethodDef;
- if (operatorDef->mOperatorDeclaration->mIsConvOperator)
- {
- name += "?B";
- }
- else
- {
- switch (operatorDef->mOperatorDeclaration->mBinOp)
- {
- case BfBinaryOp_Add:
- name += "?H";
- break;
- case BfBinaryOp_Subtract:
- name += "?G";
- break;
- case BfBinaryOp_Multiply:
- name += "?D";
- break;
- case BfBinaryOp_OverflowAdd:
- name += "?OH";
- break;
- case BfBinaryOp_OverflowSubtract:
- name += "?OG";
- break;
- case BfBinaryOp_OverflowMultiply:
- name += "?OD";
- break;
- case BfBinaryOp_Divide:
- name += "?K";
- break;
- case BfBinaryOp_Modulus:
- name += "?L";
- break;
- case BfBinaryOp_BitwiseAnd:
- name += "?I";
- break;
- case BfBinaryOp_BitwiseOr:
- name += "?U";
- break;
- case BfBinaryOp_ExclusiveOr:
- name += "?T";
- break;
- case BfBinaryOp_LeftShift:
- name += "?6";
- break;
- case BfBinaryOp_RightShift:
- name += "?5";
- break;
- case BfBinaryOp_Equality:
- name += "?8";
- break;
- case BfBinaryOp_InEquality:
- name += "?9";
- break;
- case BfBinaryOp_GreaterThan:
- name += "?O";
- break;
- case BfBinaryOp_LessThan:
- name += "?M";
- break;
- case BfBinaryOp_GreaterThanOrEqual:
- name += "?P";
- break;
- case BfBinaryOp_LessThanOrEqual:
- name += "?N";
- break;
- case BfBinaryOp_Compare:
- name += "__cmp__";
- break;
- case BfBinaryOp_ConditionalAnd:
- name += "?V";
- break;
- case BfBinaryOp_ConditionalOr:
- name += "?W";
- break;
- case BfBinaryOp_NullCoalesce:
- methodName = "__nc__";
- break;
- case BfBinaryOp_Is:
- methodName = "__is__";
- break;
- case BfBinaryOp_As:
- methodName = "__as__";
- break;
- default: break;
- }
- switch (operatorDef->mOperatorDeclaration->mUnaryOp)
- {
- case BfUnaryOp_AddressOf:
- name += "?I";
- break;
- case BfUnaryOp_Dereference:
- name += "?D";
- break;
- case BfUnaryOp_Negate:
- name += "?G";
- break;
- case BfUnaryOp_Not:
- name += "?7";
- break;
- case BfUnaryOp_Positive:
- name += "?H";
- break;
- case BfUnaryOp_InvertBits:
- name += "?S";
- break;
- case BfUnaryOp_Increment:
- name += "?E";
- break;
- case BfUnaryOp_Decrement:
- name += "?F";
- break;
- case BfUnaryOp_PostIncrement:
- methodName = "__pi__";
- break;
- case BfUnaryOp_PostDecrement:
- methodName = "__pd__";
- break;
- case BfUnaryOp_Ref:
- methodName = "__ref__";
- break;
- case BfUnaryOp_Out:
- methodName = "__out__";
- break;
- default: break;
- }
- switch (operatorDef->mOperatorDeclaration->mAssignOp)
- {
- case BfAssignmentOp_Assign:
- methodName += "__a__";
- break;
- case BfAssignmentOp_Add:
- methodName += "__a_add__";
- break;
- case BfAssignmentOp_Subtract:
- methodName += "__a_sub__";
- break;
- case BfAssignmentOp_Multiply:
- methodName += "__a_mul__";
- break;
- case BfAssignmentOp_Divide:
- methodName += "__a_div__";
- break;
- case BfAssignmentOp_Modulus:
- methodName += "__a_mod__";
- break;
- case BfAssignmentOp_ShiftLeft:
- methodName += "__a_shl__";
- break;
- case BfAssignmentOp_ShiftRight:
- methodName += "__a_shr__";
- break;
- case BfAssignmentOp_BitwiseAnd:
- methodName += "__a_bwa__";
- break;
- case BfAssignmentOp_BitwiseOr:
- methodName += "__a_bwo__";
- break;
- case BfAssignmentOp_ExclusiveOr:
- methodName += "__a_xor__";
- break;
- default: break;
- }
- }
- if (!methodName.empty())
- {
- AddStr(mangleContext, name, methodName);
- }
- }
- /*else if ((methodDef->mMethodType == BfMethodType_Ctor) && (!methodDef->mIsStatic))
- {
- isSpecialFunc = true;
- name += "?0";
- //AddAtomStr(mangleContext, name, typeDef->mName);
- }
- else if ((methodDef->mMethodType == BfMethodType_Dtor) && (!methodDef->mIsStatic))
- {
- isSpecialFunc = true;
- name += "?1";
- //AddAtomStr(mangleContext, name, typeDef->mName);
- }*/
- else if (methodInst->GetNumGenericArguments() != 0)
- {
- AddStr(mangleContext, name, methodDef->mName);
- AddGenericArgs(mangleContext, name, methodInst->mMethodInfoEx->mMethodGenericArguments);
- name += '@';
- }
- else
- {
- if ((!mangleContext.mCPPMangle) && (!methodDef->mIsMutating) && (!methodDef->mIsStatic) && (methodInst->GetOwner()->IsValueType()))
- AddStr(mangleContext, name, methodDef->mName + "__im");
- else
- AddStr(mangleContext, name, methodDef->mName);
- }
- if (((methodInst->GetOwner()->mTypeDef->IsGlobalsContainer()) &&
- ((methodDef->mMethodType == BfMethodType_Ctor) || (methodDef->mMethodType == BfMethodType_Dtor) || (methodDef->mName == BF_METHODNAME_MARKMEMBERS_STATIC))) ||
- ((methodInst->mMethodDef->mDeclaringType->mPartialIdx != -1) && (methodInst->mMethodDef->mDeclaringType->IsExtension()) &&
- (!methodInst->mIsForeignMethodDef) && (!methodInst->mMethodDef->mIsExtern) &&
- ((!methodInst->mMethodDef->mIsOverride) || (methodDef->mName == BF_METHODNAME_MARKMEMBERS) || (methodDef->mMethodType == BfMethodType_Dtor))))
- {
- auto declType = methodInst->mMethodDef->mDeclaringType;
- BF_ASSERT(methodInst->GetOwner()->mTypeDef->mIsCombinedPartial);
- auto declProject = declType->mProject;
- bool addProjectName = (declProject != typeInst->mTypeDef->mProject);
- bool addIndex = true;
- if (typeInst->mTypeDef->IsGlobalsContainer())
- {
- addProjectName = true;
- if ((methodInst->mCallingConvention == BfCallingConvention_Cdecl) ||
- (methodInst->mCallingConvention == BfCallingConvention_Stdcall))
- {
- addProjectName = false;
- addIndex = false;
- }
- }
- if (addProjectName)
- {
- name += declProject->mName;
- name += '$';
- }
- if (addIndex)
- name += StrFormat("%d$", declType->mPartialIdx);
- }
- if (!mangleContext.mCPPMangle)
- {
- if (methodInst->mMangleWithIdx)
- name += StrFormat("i%d$", methodInst->mMethodDef->mIdx);
- if (methodDef->mCheckedKind == BfCheckedKind_Checked)
- name += "CHK$";
- else if (methodDef->mCheckedKind == BfCheckedKind_Unchecked)
- name += "UCHK$";
- if (methodDef->mHasComptime)
- name += "COMPTIME$";
- }
- /*if ((methodInst->mMethodInstanceGroup->mOwner->mTypeDef->IsGlobalsContainer()) && (methodInst->mMethodDef->mMethodDeclaration == NULL))
- {
- name += methodInst->mMethodInstanceGroup->mOwner->mTypeDef->mProject->mName;
- name += "$";
- }*/
- if (methodInst->GetForeignType() != NULL)
- Mangle(mangleContext, name, methodInst->GetForeignType(), true);
- if (methodInst->GetExplicitInterface() != NULL)
- Mangle(mangleContext, name, methodInst->GetExplicitInterface(), true);
- ///
- {
- // Only use CCompat for params, not for the owning type name - unless we're doing an explicit CPP mangle
- SetAndRestoreValue<bool> prevCCompat(mangleContext.mCCompat, (mangleContext.mCCompat && mangleContext.mCPPMangle) ? true : false);
- Mangle(mangleContext, name, methodInst->GetOwner(), true);
- }
- /*bool isCppDecl = false;
- if (!isCppDecl)
- {
- if (name.EndsWith("@"))
- name.Remove(name.length() - 1);
- FindOrCreateNameSub(mangleContext, name, NameSubstitute(BfMangler::NameSubstitute::Kind_NamespaceAtom, typeInst->mModule->mSystem->mBfAtom));
- name += '@';
- }*/
- //QEA AXXZ
- char attrib ='A';
- if (methodDef->mProtection == BfProtection_Protected)
- attrib = 'I';
- else if (methodDef->mProtection == BfProtection_Public)
- attrib = 'Q';
- bool doExplicitThis = (!methodDef->mIsStatic) && (typeInst->IsTypedPrimitive());
- if ((methodDef->mIsStatic) || (doExplicitThis))
- attrib += 2;
- if ((methodDef->mIsVirtual) && (!methodDef->mIsOverride))
- attrib += 4;
- name += attrib;
- auto bfSystem = methodInst->GetOwner()->mModule->mSystem;
- if ((!methodDef->mIsStatic) && (!doExplicitThis))
- {
- /*char cvQualifier = 'A';
- if (mangleContext.mIs64Bit)
- cvQualifier = 'E';
- name += cvQualifier;*/
- if (mangleContext.mIs64Bit)
- name += "E";
- char qualifier = 'A'; // const / volatile
- name += qualifier;
- }
- auto callingConvention = mangleContext.mModule->GetIRCallingConvention(methodInst);
- char callingConv = 'A';
- if (callingConvention == BfIRCallingConv_StdCall)
- callingConv = 'G';
- else if (callingConvention == BfIRCallingConv_ThisCall)
- callingConv = 'E';
- name += callingConv;
- if (isSpecialFunc)
- name += '@';
- //
- if (!isSpecialFunc)
- {
- bool isConst = false;
- if (methodDeclaration != NULL)
- HandleParamCustomAttributes(methodDeclaration->mAttributes, true, isConst);
- mangleContext.mInRet = true;
- Mangle(mangleContext, name, methodInst->mReturnType, false, isConst);
- mangleContext.mInRet = false;
- }
- if ((methodInst->mParams.size() == 0) && (!doExplicitThis))
- {
- name += 'X';
- }
- else
- {
- // Is this right?
- if (methodInst->GetNumGenericArguments() != 0)
- mangleContext.mSubstituteList.clear();
- mangleContext.mInArgs = true;
- if (doExplicitThis)
- {
- Mangle(mangleContext, name, typeInst->GetUnderlyingType(), true);
- }
- for (int paramIdx = 0; paramIdx < methodInst->mParams.mSize; paramIdx++)
- {
- auto& param = methodInst->mParams[paramIdx];
- bool isConst = false;
- if ((param.mParamDefIdx >= 0) && (methodDeclaration != NULL) && (param.mParamDefIdx < methodDeclaration->mParams.mSize))
- {
- auto paramDecl = methodDeclaration->mParams[param.mParamDefIdx];
- HandleParamCustomAttributes(paramDecl->mAttributes, false, isConst);
- }
- if (!mangleContext.mCPPMangle)
- {
- auto paramKind = methodInst->GetParamKind(paramIdx);
- if (paramKind == BfParamKind_Params)
- name += "Tparams@@";
- else if (paramKind == BfParamKind_DelegateParam)
- name += "Tparam@@";
- }
- Mangle(mangleContext, name, param.mResolvedType, true, isConst);
- }
- name += '@';
- }
- name += 'Z';
- bool wantLog = false;
- if (wantLog)
- {
- BfLog2("Mangling #%d : %s -> %s\n", mangleIdx, mangleContext.mModule->MethodToString(methodInst).c_str(), name.c_str());
- if (!methodInst->mIsUnspecialized)
- {
- String demangled = BfDemangler::Demangle(name, DbgLanguage_Beef);
- BfLog2(" Demangled %d: %s\n", mangleIdx, demangled.c_str());
- }
- }
- }
- void BfMSMangler::Mangle(StringImpl& name, bool is64Bit, BfFieldInstance* fieldInstance)
- {
- auto fieldDef = fieldInstance->GetFieldDef();
- if (fieldDef->mFieldDeclaration != NULL)
- {
- auto module = fieldInstance->mOwner->mModule;
- if ((fieldInstance->mCustomAttributes != NULL) && (fieldInstance->mCustomAttributes->Contains(module->mCompiler->mCLinkAttributeTypeDef)))
- {
- name += fieldDef->mName;
- return;
- }
- }
- BF_ASSERT(fieldDef->mIsStatic);
- MangleContext mangleContext;
- mangleContext.mIs64Bit = is64Bit;
- mangleContext.mModule = fieldInstance->mOwner->mModule;
- bool isCMangle = false;
- HandleCustomAttributes(fieldInstance->mCustomAttributes, fieldInstance->mOwner->mConstHolder, mangleContext.mModule, name, isCMangle, mangleContext.mCPPMangle);
- if (isCMangle)
- name += fieldInstance->GetFieldDef()->mName;
- if (!name.IsEmpty())
- return;
- name += '?';
- AddStr(mangleContext, name, fieldDef->mName);
- Mangle(mangleContext, name, fieldInstance->mOwner, true);
- name += '2'; //TODO: Don't always mark as 'public'
- Mangle(mangleContext, name, fieldInstance->mResolvedType);
- name += ('A' + /*(fieldDef->mIsConst ? 1 : 0) +*/ (fieldDef->mIsVolatile ? 2 : 0));
- }
- void BfMSMangler::MangleMethodName(StringImpl& name, bool is64Bit, BfTypeInstance* type, const StringImpl& methodName)
- {
- MangleContext mangleContext;
- mangleContext.mIs64Bit = is64Bit;
- mangleContext.mModule = type->GetModule();
- name += '?';
- AddStr(mangleContext, name, methodName);
- Mangle(mangleContext, name, type, true);
- name += "SAXXZ";
- }
- void BfMSMangler::MangleStaticFieldName(StringImpl& name, bool is64Bit, BfTypeInstance* owner, const StringImpl& fieldName, BfType* fieldType)
- {
- MangleContext mangleContext;
- mangleContext.mIs64Bit = is64Bit;
- mangleContext.mModule = owner->GetModule();
- name += '?';
- AddStr(mangleContext, name, fieldName);
- Mangle(mangleContext, name, owner, true);
- //name += "@@";
- name += '2'; // public
- if (fieldType == NULL)
- name += 'H';
- else
- Mangle(mangleContext, name, fieldType);
- name += "A"; // static
- }
- //////////////////////////////////////////////////////////////////////////
- String BfSafeMangler::Mangle(BfType* type, BfModule* module)
- {
- MangleContext mangleContext;
- mangleContext.mIs64Bit = true;
- mangleContext.mModule = module;
- mangleContext.mIsSafeMangle = true;
- auto typeInst = type->ToTypeInstance();
- String name;
- if (typeInst != NULL)
- BfMSMangler::Mangle(mangleContext, name, typeInst, true);
- else
- BfMSMangler::Mangle(mangleContext, name, type);
- return name;
- }
- //////////////////////////////////////////////////////////////////////////
- void BfMangler::Mangle(StringImpl& outStr, MangleKind mangleKind, BfType* type, BfModule* module)
- {
- if (mangleKind == BfMangler::MangleKind_GNU)
- outStr += BfGNUMangler::Mangle(type, module);
- else
- BfMSMangler::Mangle(outStr, mangleKind == BfMangler::MangleKind_Microsoft_64, type, module);
- }
- void BfMangler::Mangle(StringImpl& outStr, MangleKind mangleKind, BfMethodInstance* methodInst)
- {
- if (mangleKind == BfMangler::MangleKind_GNU)
- outStr += BfGNUMangler::Mangle(methodInst);
- else
- BfMSMangler::Mangle(outStr, mangleKind == BfMangler::MangleKind_Microsoft_64, methodInst);
- }
- void BfMangler::Mangle(StringImpl& outStr, MangleKind mangleKind, BfFieldInstance* fieldInstance)
- {
- if (mangleKind == BfMangler::MangleKind_GNU)
- {
- outStr += BfGNUMangler::Mangle(fieldInstance);
- }
- else
- BfMSMangler::Mangle(outStr, mangleKind == BfMangler::MangleKind_Microsoft_64, fieldInstance);
- }
- void BfMangler::MangleMethodName(StringImpl& outStr, MangleKind mangleKind, BfTypeInstance* type, const StringImpl& methodName)
- {
- if (mangleKind == BfMangler::MangleKind_GNU)
- outStr += BfGNUMangler::MangleMethodName(type, methodName);
- else
- BfMSMangler::MangleMethodName(outStr, mangleKind == BfMangler::MangleKind_Microsoft_64, type, methodName);
- }
- void BfMangler::MangleStaticFieldName(StringImpl& outStr, MangleKind mangleKind, BfTypeInstance* type, const StringImpl& fieldName, BfType* fieldType)
- {
- if (mangleKind == BfMangler::MangleKind_GNU)
- outStr += BfGNUMangler::MangleStaticFieldName(type, fieldName);
- else
- BfMSMangler::MangleStaticFieldName(outStr, mangleKind == BfMangler::MangleKind_Microsoft_64, type, fieldName, fieldType);
- }
- void BfMangler::HandleCustomAttributes(BfCustomAttributes* customAttributes, BfIRConstHolder* constHolder, BfModule* module, StringImpl& name, bool& isCMangle, bool& isCPPMangle)
- {
- if (customAttributes == NULL)
- return;
- auto linkNameAttr = customAttributes->Get(module->mCompiler->mLinkNameAttributeTypeDef);
- if (linkNameAttr != NULL)
- {
- if (linkNameAttr->mCtorArgs.size() == 1)
- {
- if (module->TryGetConstString(constHolder, linkNameAttr->mCtorArgs[0], name))
- if (!name.IsWhitespace())
- return;
- auto constant = constHolder->GetConstant(linkNameAttr->mCtorArgs[0]);
- if (constant != NULL)
- {
- if (constant->mInt32 == 1) // C
- {
- isCMangle = true;
- }
- else if (constant->mInt32 == 2) // CPP
- {
- isCPPMangle = true;
- }
- }
- }
- }
- }
- void BfMangler::HandleParamCustomAttributes(BfAttributeDirective* attributes, bool isReturn, bool& isConst)
- {
- while (attributes != NULL)
- {
- if (attributes->mAttributeTypeRef != NULL)
- {
- auto typeRefName = attributes->mAttributeTypeRef->ToCleanAttributeString();
- if (typeRefName == "MangleConst")
- isConst = true;
- }
- attributes = attributes->mNextAttribute;
- }
- }
|