123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517 |
- #include "BfDemangler.h"
- USING_NS_BF;
- static char SafeGetChar(const StringImpl& str, int idx)
- {
- if (idx >= (int)str.length())
- return '!';
- return str[idx];
- }
- DemangleBase::DemangleBase()
- {
- mCurIdx = 0;
- mFailed = false;
- mLanguage = DbgLanguage_Unknown;
- mInArgs = false;
- mBeefFixed = false;
- }
- bool DemangleBase::Failed()
- {
- //BF_DBG_FATAL("DwDemangler::Failed");
- mFailed = true;
- return false;
- }
- void DemangleBase::Require(bool result)
- {
- //BF_ASSERT(result);
- if (!result)
- {
- mFailed = true;
- }
- }
- //////////////////////////////////////////////////////////////////////////
- DwDemangler::DwDemangler()
- {
- mOmitSubstituteAdd = false;
- mIsFirstName = true;
- mTemplateDepth = 0;
- mCaptureTargetType = false;
- mFunctionPopSubstitute = false;
- mRawDemangle = false;
- }
- #define RETURN_STR(strVal) do { outName = strVal; return true; } while(false)
- bool DwDemangler::DemangleBuiltinType(StringImpl& outName)
- {
- auto firstChar = SafeGetChar(mMangledName, mCurIdx++);
- switch (firstChar)
- {
- case 'v':
- RETURN_STR("void");
- case 'w':
- RETURN_STR("wchar_t");
- case 'b':
- RETURN_STR("bool");
- case 'a':
- if (mLanguage == DbgLanguage_Beef)
- RETURN_STR("int8");
- else
- RETURN_STR("sbyte");
- case 'h':
- if (mLanguage == DbgLanguage_Beef)
- RETURN_STR("uint8");
- else
- RETURN_STR("byte");
- case 's':
- RETURN_STR("short");
- case 't':
- RETURN_STR("ushort");
- case 'i':
- if (mLanguage == DbgLanguage_Beef)
- RETURN_STR("int32");
- else
- RETURN_STR("int");
- case 'j':
- if (mLanguage == DbgLanguage_Beef)
- RETURN_STR("uint32");
- else
- RETURN_STR("uint");
- case 'x':
- RETURN_STR("long");
- case 'l':
- if (mLanguage == DbgLanguage_Beef)
- RETURN_STR("int32");
- else
- RETURN_STR("int");
- case 'm':
- if (mLanguage == DbgLanguage_Beef)
- RETURN_STR("uint32");
- else
- RETURN_STR("uint");
- case 'y':
- RETURN_STR("ulong");
- case 'c':
- if (mLanguage == DbgLanguage_Beef)
- RETURN_STR("char8");
- else
- RETURN_STR("char");
- case 'f':
- RETURN_STR("float");
- case 'd':
- RETURN_STR("double");
- case 'n':
- RETURN_STR("__int128");
- case 'o':
- RETURN_STR("__uint128");
- case 'e':
- RETURN_STR("__float80");
- case 'g':
- RETURN_STR("__float128");
- case 'z':
- RETURN_STR("...");
- case 'D':
- {
- char nextChar = SafeGetChar(mMangledName, mCurIdx++);
- switch (nextChar)
- {
- case 'i':
- RETURN_STR("char32");
- case 's':
- RETURN_STR("char16");
- case 'a':
- RETURN_STR("auto");
- case 'c':
- RETURN_STR("decltype(auto)");
- case 'n':
- RETURN_STR("std::nullptr_t");
- default:
- RETURN_STR("?");
- }
- }
- break;
- default:
- mCurIdx--;
- break;
- }
- return false;
- }
- bool DwDemangler::DemangleArrayType(StringImpl& outName)
- {
- //TODO:
- /*auto firstChar = SafeGetChar(mMangledName, mCurIdx++);
- switch (firstChar)
- {
- case 'A':
- {
- }
- break;
- default:
- mCurIdx--;
- }*/
- return false;
- }
- bool DwDemangler::DemangleClassEnumType(StringImpl& outName)
- {
- if (DemangleName(outName))
- return true;
- //TODO: 'Ts', 'Tu', 'Te'
- return false;
- }
- bool DwDemangler::DemangleFunction(StringImpl& outName)
- {
- bool wantsReturnValue = false;
- //String outName;
- bool hasTemplateArgs;
- Require(DemangleName(outName, &hasTemplateArgs));
- mIsFirstName = false;
- if (hasTemplateArgs)
- wantsReturnValue = true;
- // Pop either function name or template args
- if (mSubstituteList.size() > 0)
- mSubstituteList.pop_back();
- if (mCaptureTargetType)
- {
- int lastAt = (int)outName.LastIndexOf('@');
- if (lastAt != -1)
- {
- DwDemangler subDemangler;
- outName.Remove(0, lastAt + 1);
- outName = subDemangler.Demangle(outName);
- return true;
- }
- int lastDot = (int)outName.LastIndexOf('.');
- if (lastDot != -1)
- outName.RemoveToEnd(lastDot);
- return true;
- }
- // New
- if (mFunctionPopSubstitute)
- {
- BF_ASSERT(mSubstituteList.size() > 0);
- if (mSubstituteList.size() > 0)
- mSubstituteList.pop_back();
- mFunctionPopSubstitute = false;
- }
- if (mCurIdx < (int) mMangledName.length())
- {
- //TODO: Needed? Caused a crash. mSubstituteList.pop_back(); // Remove method name
- int atPos = (int)outName.LastIndexOf('@');
- if (atPos != -1)
- {
- int dotPos = (int)outName.LastIndexOf('.', atPos);
- if (dotPos != -1)
- {
- StringT<256> prefix = outName.Substring(dotPos + 1, atPos - dotPos - 1);
- if ((prefix == "get") || (prefix == "set"))
- {
- outName = outName.Substring(0, dotPos + 1) + outName.Substring(atPos + 1) + " " + prefix;
- return true;
- }
- }
- }
- outName += "(";
- bool needsComma = false;
- for (int paramIdx = 0; mCurIdx < (int)mMangledName.length(); paramIdx++)
- {
- if (SafeGetChar(mMangledName, mCurIdx) == 'E')
- break;
- if (needsComma)
- outName += ", ";
- StringT<256> paramType;
- Require(DemangleType(paramType));
- bool atEnd = mCurIdx >= (int) mMangledName.length();
- if ((paramIdx == 0) && (wantsReturnValue))
- {
- outName = paramType + " " + outName;
- }
- else
- {
- if ((paramType == "void") && (paramIdx == 0) && (atEnd))
- break;
- outName += paramType;
- needsComma = true;
- }
- if (mFailed)
- break;
- }
- outName += ")";
- }
- return true;
- }
- bool DwDemangler::DemangleLocalName(StringImpl& outName)
- {
- auto firstChar = SafeGetChar(mMangledName, mCurIdx++);
- if (firstChar == 'Z')
- {
- if (SafeGetChar(mMangledName, mCurIdx) == 'L') // Literal (?)
- mCurIdx++;
- DemangleFunction(outName);
- auto endChar = SafeGetChar(mMangledName, mCurIdx++);
- if (endChar != 'E')
- return false;
- endChar = SafeGetChar(mMangledName, mCurIdx++);
- if (endChar == 's')
- {
- //
- }
- else
- {
- mCurIdx--;
- StringT<256> entityName;
- Require(DemangleName(entityName));
- if (mLanguage == DbgLanguage_Beef)
- outName += "." + entityName;
- else
- outName += "::" + entityName;
- }
- endChar = SafeGetChar(mMangledName, mCurIdx++);
- if (endChar == '_')
- {
- //
- }
- else
- {
- mCurIdx--;
- }
- BF_ASSERT(mSubstituteList.size() > 0);
- if (mSubstituteList.size() >= 2)
- {
- mSubstituteList.pop_back();
- mSubstituteList[mSubstituteList.size() - 1] = outName;
- }
- return true;
- }
- mCurIdx--;
- return false;
- }
- bool DwDemangler::DemangleType(StringImpl& outName)
- {
- StringT<256> cvQualifiers;
- if (DemangleCVQualifiers(cvQualifiers))
- {
- Require(DemangleType(outName));
- outName = cvQualifiers + " " + outName;
- mSubstituteList.push_back(outName);
- return true;
- }
- auto firstChar = SafeGetChar(mMangledName, mCurIdx++);
- switch (firstChar)
- {
- case 'D':
- {
- auto nextChar = SafeGetChar(mMangledName, mCurIdx++);
- if (nextChar == 'p')
- {
- Require(DemangleType(outName));
- return true;
- }
- mCurIdx--;
- }
- case 'P':
- if (DemangleFunctionType(outName))
- {
- mSubstituteList.push_back(outName);
- return true;
- }
- if (DemangleType(outName))
- {
- outName = outName + "*";
- mSubstituteList.push_back(outName);
- return true;
- }
- break;
- case 'R':
- if (DemangleType(outName))
- {
- outName = outName + "&";
- mSubstituteList.push_back(outName);
- return true;
- }
- break;
- case 'O':
- if (DemangleType(outName))
- {
- if (outName[outName.length() - 1] != '&')
- outName = outName + "&&";
- mSubstituteList.push_back(outName);
- return true;
- }
- break;
- case 'U':
- {
- StringT<256> modName;
- Require(DemangleUnqualifiedName(modName));
- Require(DemangleType(outName));
- if (modName[0] == '@')
- outName = outName + " " + modName.Substring(1);
- else
- outName = modName + " " + outName;
- return true;
- }
- break;
- //TODO: 'C', 'G', 'U'
- default:
- mCurIdx--;
- break;
- }
- if (DemangleBuiltinType(outName))
- return true;
- if (DemangleFunctionType(outName))
- return true;
- if (DemangleSubstitution(outName))
- {
- StringT<256> templateArgs;
- if (DemangleTemplateArgs(templateArgs))
- {
- outName += templateArgs;
- mSubstituteList.push_back(outName);
- }
- return true;
- }
- if (DemangleClassEnumType(outName))
- return true;
- //TODO: DemangleArrayType
- //TODO: DemanglePointerToMemberType
- if (DemangleTemplateParam(outName))
- return true;
- //TODO: TemplateTemplateParam
- //TODO: DeclType
- return false;
- }
- bool DwDemangler::DemangleFunctionType(StringImpl& outName)
- {
- auto firstChar = SafeGetChar(mMangledName, mCurIdx++);
- if (firstChar == 'F')
- {
- StringT<256> returnType;
- Require(DemangleType(returnType));
- outName = returnType + " (*)(";
- for (int paramNum = 0; true; paramNum++)
- {
- if (DemangleEnd())
- break;
- if (paramNum > 0)
- outName += ", ";
- StringT<256> paramType;
- Require(DemangleType(paramType));
- outName += paramType;
- }
- outName += ")";
- return true;
- }
- mCurIdx--;
- return false;
- }
- bool DwDemangler::DemangleNestedName(StringImpl& outName)
- {
- auto firstChar = SafeGetChar(mMangledName, mCurIdx++);
- switch (firstChar)
- {
- case 'N':
- {
- }
- break;
- }
- mCurIdx--;
- return false;
- }
- bool DwDemangler::DemangleCVQualifiers(StringImpl& outName)
- {
- auto firstChar = SafeGetChar(mMangledName, mCurIdx++);
- switch (firstChar)
- {
- case 'r':
- RETURN_STR("restrict");
- case 'V':
- RETURN_STR("volatile");
- case 'K':
- RETURN_STR("const");
- }
- mCurIdx--;
- return false;
- }
- bool DwDemangler::DemangleRefQualifier(StringImpl& outName)
- {
- auto firstChar = SafeGetChar(mMangledName, mCurIdx++);
- switch (firstChar)
- {
- case 'R':
- RETURN_STR("&");
- case 'O':
- RETURN_STR("&&");
- }
- mCurIdx--;
- return false;
- }
- bool DwDemangler::DemangleOperatorName(StringImpl& outName)
- {
- auto firstChar = SafeGetChar(mMangledName, mCurIdx++);
- StringT<64> opCode;
- opCode += firstChar;
- opCode += SafeGetChar(mMangledName, mCurIdx++);
- StringT<64> opName;
- if (opCode == "nw")
- opName = " new";
- else if (opCode == "na")
- opName = " new[]";
- else if (opCode == "dl")
- opName = " delete";
- else if (opCode == "da")
- opName = " delete[]";
- else if (opCode == "pl")
- opName = "+";
- else if (opCode == "mi")
- opName = "-";
- else if (opCode == "ml")
- opName = "*";
- else if (opCode == "dv")
- opName = "/";
- else if (opCode == "rm")
- opName = "%";
- else if (opCode == "an")
- opName = "&";
- else if (opCode == "or")
- opName = "|";
- else if (opCode == "eo")
- opName = "^";
- else if (opCode == "aS")
- opName = "=";
- else if (opCode == "pL")
- opName = "+=";
- else if (opCode == "mI")
- opName = "-=";
- else if (opCode == "mL")
- opName = "*=";
- else if (opCode == "dV")
- opName = "/=";
- else if (opCode == "rM")
- opName = "%=";
- else if (opCode == "aN")
- opName = "&=";
- else if (opCode == "oR")
- opName = "|=";
- else if (opCode == "eO")
- opName = "^=";
- else if (opCode == "ls")
- opName = "<<";
- else if (opCode == "rs")
- opName = ">>";
- else if (opCode == "eq")
- opName = "==";
- else if (opCode == "ne")
- opName = "!=";
- else if (opCode == "lt")
- opName = "<";
- else if (opCode == "gt")
- opName = ">";
- else if (opCode == "ge")
- opName = ">=";
- else if (opCode == "le")
- opName = "<=";
- else if (opCode == "aa")
- opName = "&&";
- else if (opCode == "oo")
- opName = "||";
- else if (opCode == "ad")
- opName = "&";
- else if (opCode == "de")
- opName = "*";
- else if (opCode == "ng")
- opName = "-";
- else if (opCode == "nt")
- opName = "!";
- else if (opCode == "ps")
- opName = "+";
- else if (opCode == "co")
- opName = "~";
- else if (opCode == "pp")
- opName = "++";
- else if (opCode == "mm")
- opName = "--";
- else if (opCode == "cm")
- opName = ",";
- else if (opCode == "pm")
- opName = "->*";
- else if (opCode == "pt")
- opName = "->";
- else if (opCode == "ix")
- opName = "[]";
- else if (opCode == "cl")
- opName = "()";
- else if (opCode == "qu")
- opName = "?";
- else if (opCode == "li")
- {
- opName = "\"\"";
- }
- else if (opCode == "cv")
- {
- StringT<256> typeName;
- Require(DemangleType(typeName));
- opName = " " + typeName;
- }
- else if ((opCode == "C1") || (opCode == "C2") || (opCode == "C3"))
- {
- outName += "this";
- }
- else if ((opCode == "D0") || (opCode == "D1") || (opCode == "D2"))
- {
- outName += "~this";
- }
- else
- {
- mCurIdx -= 2;
- return false;
- }
- if (!opName.empty())
- outName += "operator" + opName;
- //mSubstituteList.push_back(outName);
- return true;
- }
- bool DwDemangler::DemangleSourceName(StringImpl& outName)
- {
- auto c = SafeGetChar(mMangledName, mCurIdx);
- if ((c >= '0') && (c <= '9'))
- {
- int nameLen = 0;
- while (mCurIdx < (int) mMangledName.length())
- {
- char c = mMangledName[mCurIdx];
- if ((c >= '0') && (c <= '9'))
- {
- nameLen = (int) (c - '0') + (nameLen * 10);
- mCurIdx++;
- }
- else
- break;
- }
- for (int nameIdx = 0; ((nameIdx < nameLen) && (mCurIdx < (int) mMangledName.length())); nameIdx++)
- {
- char c = mMangledName[mCurIdx++];
- outName += c;
- }
- //mSubstituteList.push_back(outName);
- return true;
- }
- return false;
- }
- bool DwDemangler::DemangleUnqualifiedName(StringImpl& outName)
- {
- if (DemangleOperatorName(outName)) // Also handles ctor/dtor
- return true;
- if (DemangleSourceName(outName))
- return true;
- return false;
- }
- bool DwDemangler::DemangleEnd()
- {
- auto firstChar = SafeGetChar(mMangledName, mCurIdx++);
- if (firstChar == 'E')
- return true;
- mCurIdx--;
- return false;
- }
- bool DwDemangler::DemangleInternalName(StringImpl& outName)
- {
- auto firstChar = SafeGetChar(mMangledName, mCurIdx++);
- if (firstChar == 'L')
- {
- bool result = DemangleSourceName(outName);
- Require(result);
- return result;
- }
- mCurIdx--;
- return false;
- }
- bool DwDemangler::DemangleExprPriamry(StringImpl& outName)
- {
- auto firstChar = SafeGetChar(mMangledName, mCurIdx++);
- if (firstChar == 'L')
- {
- StringT<256> outType;
- Require(DemangleType(outType));
- StringT<256> value;
- while (true)
- {
- auto c = SafeGetChar(mMangledName, mCurIdx++);
- if (c == 'E')
- break;
- value += c;
- }
- if (outType == "bool")
- outName = (value == "0") ? "false" : "true";
- else
- outName = value;
- return true;
- }
- mCurIdx--;
- return false;
- }
- bool DwDemangler::DemangleTemplateArg(StringImpl& outName)
- {
- if (DemangleType(outName))
- return true;
- if (DemangleExprPriamry(outName))
- return true;
- //TODO: Expression, Simple Expressions, Argument Pack
- return false;
- }
- bool DwDemangler::DemangleTemplateArgs(StringImpl& outName)
- {
- auto firstChar = SafeGetChar(mMangledName, mCurIdx++);
- if (firstChar == 'I')
- {
- bool recordTemplateArgs = mIsFirstName && (mTemplateDepth == 0);
- if (recordTemplateArgs)
- mTemplateList.Clear();
- mTemplateDepth++;
- bool inParamPack = false;
- bool foundEnd = false;
- bool needsComma = false;
- outName = "<";
- for (int argIdx = 0; true; argIdx++)
- {
- if (mFailed)
- return true;
- if (DemangleEnd())
- {
- if (inParamPack)
- {
- inParamPack = false;
- continue;
- }
- else
- break;
- }
- StringT<256> templateArg;
- auto firstChar = SafeGetChar(mMangledName, mCurIdx);
- if (firstChar == 'J')
- {
- mCurIdx++;
- inParamPack = true;
- continue;
- }
- Require(DemangleTemplateArg(templateArg));
- if (recordTemplateArgs)
- mTemplateList.push_back(templateArg);
- if (needsComma)
- outName += ", ";
- outName += templateArg;
- needsComma = true;
- }
- outName += ">";
- mTemplateDepth--;
- return true;
- }
- mCurIdx--;
- return false;
- }
- bool DwDemangler::DemangleSubstitution(StringImpl& outName)
- {
- auto firstChar = SafeGetChar(mMangledName, mCurIdx++);
- if (firstChar == 'S')
- {
- int idx = 0;
- bool hadChars = 0;
- while (true)
- {
- char idxChar = SafeGetChar(mMangledName, mCurIdx++);
- if (idxChar == 't')
- {
- DemangleUnqualifiedName(outName);
- outName = "std." + outName;
- mSubstituteList.push_back(outName);
- mOmitSubstituteAdd = true;
- return true;
- }
- mOmitSubstituteAdd = true;
- if (idxChar == 'a')
- {
- RETURN_STR("std.allocator");
- }
- if (idxChar == 'b')
- {
- RETURN_STR("std.basic_string");
- }
- if (idxChar == 's')
- {
- RETURN_STR("std.string");
- }
- if (idxChar == 'i')
- {
- RETURN_STR("std.basic_istream<char, std.char_traits<char>>");
- }
- if (idxChar == 'o')
- {
- RETURN_STR("std.basic_ostream<char, std.char_traits<char>>");
- }
- if (idxChar == 'd')
- {
- RETURN_STR("std.basic_iostream<char, std.char_traits<char>>");
- }
- if (idxChar == '?')
- break;
- if (idxChar == '_')
- break;
- hadChars = true;
- if ((idxChar >= '0') && (idxChar <= '9'))
- idx = (idxChar - '0') + (idx * 36);
- else if ((idxChar >= 'A') && (idxChar <= 'Z'))
- idx = ((idxChar - 'A') + 10) + (idx * 36);
- }
- if (hadChars)
- idx++;
- if ((idx >= 0) && (idx < (int) mSubstituteList.size()))
- {
- outName = mSubstituteList[idx];
- return true;
- }
- outName = "?";
- Failed();
- return true;
- }
- mCurIdx--;
- return false;
- }
- bool DwDemangler::DemangleTemplateParam(StringImpl& outName)
- {
- auto firstChar = SafeGetChar(mMangledName, mCurIdx++);
- if (firstChar == 'T')
- {
- int idx = 0;
- bool hadChars = 0;
- while (true)
- {
- char idxChar = SafeGetChar(mMangledName, mCurIdx++);
- if (idxChar == '?')
- break;
- if (idxChar == '_')
- break;
- hadChars = true;
- if ((idxChar >= '0') && (idxChar <= '9'))
- idx = (idxChar - '0') + (idx * 36);
- else if ((idxChar >= 'A') && (idxChar <= 'Z'))
- idx = ((idxChar - 'A') + 10) + (idx * 36);
- }
- if (hadChars)
- idx++;
- if ((idx >= 0) && (idx < (int)mTemplateList.size()))
- {
- outName = mTemplateList[idx];
- mSubstituteList.push_back(outName);
- return true;
- }
- outName = "?";
- Failed();
- return true;
- }
- mCurIdx--;
- return false;
- }
- bool DwDemangler::DemangleUnscopedName(StringImpl& outName)
- {
- if (DemangleUnqualifiedName(outName))
- return true;
- if (DemangleSubstitution(outName))
- return true;
- return false;
- }
- bool DwDemangler::DemangleName(StringImpl& outName, bool* outHasTemplateArgs)
- {
- if (outHasTemplateArgs != NULL)
- *outHasTemplateArgs = false;
- auto firstChar = SafeGetChar(mMangledName, mCurIdx++);
- switch (firstChar)
- {
- case 'N': // NestedName
- {
- StringT<64> cvQualifier;
- if (DemangleCVQualifiers(cvQualifier))
- outName += cvQualifier + " ";
- StringT<64> refQualifier;
- if (DemangleRefQualifier(refQualifier))
- outName += refQualifier + " ";
- int nameCount = 0;
- while ((!DemangleEnd()) && (!mFailed))
- {
- StringT<128> unqualifiedName;
- mOmitSubstituteAdd = false;
- if ((DemangleUnscopedName(unqualifiedName)) ||
- (DemangleInternalName(unqualifiedName)))
- {
- if (outHasTemplateArgs != NULL)
- *outHasTemplateArgs = false;
- if (nameCount > 0)
- {
- if (mLanguage == DbgLanguage_Beef)
- outName += ".";
- else
- outName += "::";
- }
- outName += unqualifiedName;
- if (!mOmitSubstituteAdd)
- mSubstituteList.push_back(outName);
- else
- mOmitSubstituteAdd = false;
- nameCount++;
- continue;
- }
- StringT<128> templateArgs;
- if (DemangleTemplateArgs(templateArgs))
- {
- if (outHasTemplateArgs != NULL)
- *outHasTemplateArgs = true;
- int arrayDims = 0;
- if (!mRawDemangle)
- {
- if (outName == "__TUPLE")
- {
- outName = "(" + templateArgs.Substring(1, templateArgs.length() - 2) + ")";
- mSubstituteList.push_back(outName);
- continue;
- }
- else if (outName == "Box")
- {
- outName = templateArgs.Substring(1, templateArgs.length() - 2) + "^";
- mSubstituteList.push_back(outName);
- continue;
- }
- if (outName == "System.Array1")
- arrayDims = 1;
- else if (outName == "System.Array2")
- arrayDims = 2;
- else if (outName == "System.Array3")
- arrayDims = 3;
- }
- if (arrayDims > 0)
- {
- outName = templateArgs.Substring(1, templateArgs.length() - 2) + "[";
- for (int i = 0; i < arrayDims - 1; i++)
- outName += ",";
- outName += "]";
- }
- else
- {
- outName += templateArgs;
- mSubstituteList.push_back(outName);
- }
- continue;
- }
- Failed();
- break;
- }
- return true;
- }
- break;
- }
- mCurIdx--;
- if (DemangleUnscopedName(outName))
- {
- if (!mOmitSubstituteAdd)
- mSubstituteList.push_back(outName);
- else
- mOmitSubstituteAdd = false;
- StringT<128> templateArgs;
- if (DemangleTemplateArgs(templateArgs))
- {
- if (outHasTemplateArgs != NULL)
- *outHasTemplateArgs = true;
- outName += templateArgs;
- }
- if ((outName.length() > 0) && (outName[outName.length() - 1] == '.'))
- {
- // an incomplete 'std.'
- StringT<128> unqualifiedName;
- if ((DemangleUnscopedName(unqualifiedName)) ||
- (DemangleInternalName(unqualifiedName)))
- {
- outName += unqualifiedName;
- }
- else
- {
- Failed();
- }
- }
- return true;
- }
- if (DemangleLocalName(outName))
- return true;
- return false;
- }
- String DwDemangler::Demangle(const StringImpl& mangledName)
- {
- BF_ASSERT(mCurIdx == 0);
- /*String overrideVal = "_ZZL9DumpStatsP16TCMalloc_PrinteriE3MiB";
- //String overrideVal = "_ZN3Hey4Dude3Bro9TestClass7MethodBEivf";
- //"_ZN3Hey4Dude3Bro9TestClass14DlgTestGenericIiE12TestThinggieEi";
- //"_ZStL19piecewise_construct";
- //"_ZNSbIwSt11char_traitsIwESaIwEED1Ev";
- //"_ZN12_GLOBAL__N_124do_realloc_with_callbackEPvjPFvS0_EPFjPKvE";
- //"_ZNK17TCMalloc_PageMap2ILi19EE3getEj";
- //"_ZN5BeefyL13FromBigEndianEs";
- //"_ZNSt6vectorIZN4BFGC19WriteDebugDumpStateEvE9DebugInfoSaIS1_EED2Ev";
- //"_ZNSt6vectorISsSaISsEE19_M_emplace_back_auxIJRKSsEEEvDpOT_";
- //"_ZSt4moveIRiEONSt16remove_referenceIT_E4typeEOS2_";
- //"_ZL10CStartProcPN6System9Threading6ThreadE";
- //"_ZNSt8_Rb_treeIPN6System9Threading6ThreadESt4pairIKS3_PS3_ESt10_Select1stIS7_ESt4lessIS3_ESaIS7_EE13_Rb_tree_implISB_Lb1EED2Ev";
- //Clang failure: (?) "__ZNSt16allocator_traitsISaISsEE9constructISsJRKSsEEEDTcl12_S_constructfp_fp0_spclsr3stdE7forwardIT0_Efp1_EEERS0_PT_DpOS5_";
- //"__ZNSt4pairIifEC2IKifvEERKS_IT_T0_E";
- //"__ZNSsaSEPKc";
- //"__ZN6System6String6ConcatEU6paramsPNS_6Array1INS_6ObjectEEE";
- //_ZNSt3mapI3HeyfSt4lessIiESaISt4pairIKifEEEixES_S0_S1_S2_S3_S4_S5_S6_
- String overrideDemangled;
- if (mangledName != overrideVal)
- {
- BfDemangler demangler;
- overrideDemangled = demangler.Demangle(overrideVal);
- }*/
- mMangledName = mangledName;
- String outStr;
- if (mangledName.length() < 3)
- return mangledName;
- if (strncmp(mangledName.c_str(), "_Z", 2) == 0)
- mCurIdx = 2;
- else if (strncmp(mangledName.c_str(), "__Z", 3) == 0)
- mCurIdx = 3;
- else
- {
- int dotIdx = (int)mangledName.IndexOf('.');
- if (dotIdx > 1)
- return mangledName.Substring(0, dotIdx) + ":" + Demangle(mangledName.Substring(dotIdx + 1));
- return mangledName;
- }
- /*int ePos = (int) mMangledName.rfind('E');
- if (ePos > 0)
- mMangledName = mMangledName.substr(0, mMangledName.length() - 1);*/
- int endPos = (int)mMangledName.length() - 1;
- while (endPos > 0)
- {
- char c = mMangledName[endPos];
- if (c == '@')
- {
- mMangledName = mMangledName.Substring(0, endPos);
- break;
- }
- bool isNum = (c >= '0') && (c <= '9');
- if (!isNum)
- break;
- endPos--;
- }
- bool mayHaveParams = false;
- char typeChar = SafeGetChar(mangledName, mCurIdx);
- if (typeChar == 'T')
- {
- mCurIdx++;
- char typeChar2 = SafeGetChar(mangledName, mCurIdx++);
- if (typeChar2 == 'S')
- {
- // typeinfo
- }
- else if (typeChar2 == 'V')
- {
- // vtable
- }
- else
- {
- return mangledName;
- }
- }
- else if (typeChar == 'S')
- {
- mayHaveParams = false;
- }
- else if (typeChar == 'L')
- {
- mayHaveParams = true;
- mCurIdx++;
- }
- else if (typeChar == 'Z') // Static function-scoped field
- mayHaveParams = false;
- else
- mayHaveParams = true;
- bool wantsReturnValue = false;
- StringT<256> outName;
- if (mayHaveParams)
- Require(DemangleFunction(outName));
- else
- Require(DemangleName(outName));
- if (mFailed)
- return mangledName;
- //OutputDebugStrF("%s\n", outName.c_str());
- return outName;
- }
- //////////////////////////////////////////////////////////////////////////
- MsDemangler::MsDemangler()
- {
- mCurIdx = 0;
- }
- bool MsDemangler::DemangleString(StringImpl& outName)
- {
- while (true)
- {
- char c = SafeGetChar(mMangledName, mCurIdx++);
- if ((c == '!') || (c == '?'))
- return Failed();
- if (c == '@')
- break;
- outName.Append(c);
- }
- //mSubstituteList.push_back(outName);
- return true;
- }
- bool MsDemangler::DemangleTemplateName(StringImpl& outName, String* primaryName)
- {
- DemangleString(outName);
- if (primaryName != NULL)
- *primaryName = outName;
- mSubstituteList.push_back(outName);
- outName += "<";
- for (int paramIdx = 0; true; paramIdx++)
- {
- String paramType;
- if (!DemangleType(paramType))
- break;
- if (paramIdx > 0)
- outName += ", ";
- outName += paramType;
- }
- outName += ">";
- return true;
- }
- bool MsDemangler::DemangleScopedName(StringImpl& outName, String* primaryName)
- {
- for (int nameIdx = 0; true; nameIdx++)
- {
- if (mFailed)
- return false;
- char c = SafeGetChar(mMangledName, mCurIdx++);
- if (c == '@')
- return true;
- /*{
- if (curScope.length() == 0)
- return true;
- if (nameIdx == 0)
- {
- if (primaryName != NULL)
- *primaryName = curScope;
- }
- else
- outName = "::" + outName;
- outName = curScope + outName;
- curScope.clear();
- mSubstituteList.push_back(outName);
- nameIdx++;
- continue;
- }*/
- String namePart;
- if (c == '?')
- {
- c = SafeGetChar(mMangledName, mCurIdx++);
- if (c == '$')
- {
- SubstituteList oldSubList = mSubstituteList;
- mSubstituteList.Clear();
- DemangleTemplateName(namePart, /*primaryName*/NULL);
- mSubstituteList = oldSubList;
- }
- else if (c == '?')
- {
- return Failed();
- }
- else
- {
- mCurIdx--;
- int num = DemangleNumber();
- outName = StrFormat("%d", num);
- }
- }
- else if ((c >= '0') && (c <= '9'))
- {
- int subIdx = c - '0';
- if (subIdx < mSubstituteList.size())
- {
- namePart = mSubstituteList[subIdx];
- }
- else
- {
- return Failed();
- }
- }
- else
- {
- mCurIdx--;
- Require(DemangleString(namePart));
- }
- if (nameIdx == 0)
- {
- //We moved this down so we get the template args for the ctor name
- /*if ((primaryName != NULL) && (primaryName->empty()))
- *primaryName = namePart;*/
- outName = namePart;
- if ((primaryName != NULL) && (primaryName->empty()))
- *primaryName = namePart;
- }
- else if (mLanguage == DbgLanguage_Beef)
- {
- if ((mBeefFixed) && (namePart == "bf"))
- namePart.Clear();
- if (!namePart.IsEmpty())
- outName = namePart + "." + outName;
- }
- else
- {
- outName = namePart + "::" + outName;
- }
- mSubstituteList.push_back(namePart);
- }
- }
- bool MsDemangler::DemangleModifiedType(StringImpl& outName, bool isPtr)
- {
- String modifier;
- DemangleCV(modifier);
- char c = SafeGetChar(mMangledName, mCurIdx);
- if (c == 'Y') // Sized array
- {
- String dimStr;
- mCurIdx++;
- int dimCount = DemangleNumber();
- for (int dim = 0; dim < dimCount; dim++)
- {
- int dimSize = DemangleNumber();
- dimStr += StrFormat("[%d]", dimSize);
- }
- DemangleType(outName);
- outName += dimStr;
- }
- else
- {
- DemangleType(outName);
- if (isPtr)
- outName += "*";
- }
- if (!modifier.empty())
- outName = modifier + " " + outName;
- return true;
- }
- bool MsDemangler::DemangleType(StringImpl& outName)
- {
- char c = SafeGetChar(mMangledName, mCurIdx++);
- if ((c == 0) || (c == '@'))
- return false;
- switch (c)
- {
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- {
- if (mFailed)
- return false;
- int subIdx = c - '0';
- if ((subIdx < 0) || (subIdx >= (int)mSubstituteList.size()))
- return Failed();
- outName = mSubstituteList[subIdx];
- return true;
- }
- break;
- case '$':
- {
- char c = SafeGetChar(mMangledName, mCurIdx++);
- switch (c)
- {
- case '0':
- {
- int64 val = 0;
- bool doNeg = false;
- auto nextChar = SafeGetChar(mMangledName, mCurIdx++);
- if (nextChar == '?')
- {
- doNeg = true;
- nextChar = SafeGetChar(mMangledName, mCurIdx++);
- }
- if ((nextChar >= '0') && (nextChar <= '9'))
- {
- val = (nextChar - '0') + 1;
- }
- else
- {
- while (true)
- {
- if (nextChar == 0)
- return Failed();
- if (nextChar == '@')
- break;
- val = (val * 0x10) + (nextChar - 'A');
- nextChar = SafeGetChar(mMangledName, mCurIdx++);
- }
- }
- if (doNeg)
- val = -val;
- if (mLanguage == DbgLanguage_Beef)
- outName += StrFormat("const %d", val);
- else
- outName += StrFormat("%d", val);
- return true;
- }
- break;
- case 'D':
- {
- int templateParamNum = DemangleNumber();
- return Failed();
- }
- break;
- case 'F':
- {
- int param1 = DemangleNumber();
- int param2 = DemangleNumber();
- return Failed();
- }
- break;
- case 'G':
- {
- int param1 = DemangleNumber();
- int param2 = DemangleNumber();
- int param3 = DemangleNumber();
- return Failed();
- }
- break;
- case 'Q':
- {
- int nonTypeTemplateParam = DemangleNumber();
- return Failed();
- }
- break;
- case '$':
- {
- char c = SafeGetChar(mMangledName, mCurIdx++);
- if (c == 'C')
- {
- String modifier;
- DemangleCV(modifier);
- DemangleType(outName);
- outName = modifier + " " + outName;
- return true;
- }
- else if (c == 'Q')
- {
- String modifier;
- DemangleCV(modifier);
- DemangleType(outName);
- outName = modifier + " " + outName;
- return true;
- }
- }
- break;
- }
- }
- break;
- case '_':
- {
- c = SafeGetChar(mMangledName, mCurIdx++);
- switch (c)
- {
- case 'D':
- outName = "int8";
- return true;
- case 'E':
- outName = "uint8";
- return true;
- case 'F':
- outName = "int16";
- return true;
- case 'G':
- outName = "uint16";
- return true;
- case 'H':
- outName = "int32";
- return true;
- case 'I':
- outName = "uint32";
- return true;
- case 'J':
- outName = "int64";
- return true;
- case 'K':
- outName = "uint64";
- return true;
- case 'L':
- outName = "int128";
- return true;
- case 'M':
- outName = "float";
- return true;
- case 'W':
- outName = "wchar_t";
- return true;
- case 'N':
- outName = "bool";
- return true;
- default:
- return Failed();
- break;
- }
- }
- break;
- case 'A':
- {
- DemangleModifiedType(outName, false);
- outName += "&";
- }
- return true;
- case 'B':
- DemangleModifiedType(outName, false);
- outName = "volatile " + outName + "&";
- return true;
- case 'P':
- DemangleModifiedType(outName, true);
- return true;
- case 'Q':
- DemangleModifiedType(outName, true);
- outName = "const " + outName;
- return true;
- case 'R':
- DemangleModifiedType(outName, true);
- outName = "volatile " + outName;
- return true;
- case 'S':
- DemangleModifiedType(outName, true);
- outName = "const volatile" + outName;
- return true;
- case 'T':
- // union
- DemangleScopedName(outName);
- return true;
- case 'U':
- // struct
- DemangleScopedName(outName);
- return true;
- case 'V':
- // class
- DemangleScopedName(outName);
- return true;
- case 'W':
- // enum
- c = SafeGetChar(mMangledName, mCurIdx++);
- Require((c >= '0') && (c <= '8'));
- DemangleScopedName(outName);
- return true;
- case 'C':
- outName = "char";
- return true;
- case 'D':
- if (mLanguage == DbgLanguage_Beef)
- outName = "char8";
- else
- outName = "char";
- return true;
- case 'E':
- if (mLanguage == DbgLanguage_Beef)
- outName = "uint8";
- else
- outName = "uchar";
- return true;
- case 'F':
- if (mLanguage == DbgLanguage_Beef)
- outName = "int16";
- else
- outName = "short";
- return true;
- case 'G':
- if (mLanguage == DbgLanguage_Beef)
- outName = "uint16";
- else
- outName = "ushort";
- return true;
- case 'H':
- if (mLanguage == DbgLanguage_Beef)
- outName = "int32";
- else
- outName = "int";
- return true;
- case 'I':
- if (mLanguage == DbgLanguage_Beef)
- outName = "uint32";
- else
- outName = "uint";
- return true;
- case 'J':
- outName = "long";
- return true;
- case 'K':
- outName = "ulong";
- return true;
- case 'M':
- outName = "float";
- return true;
- case 'N':
- outName = "double";
- return true;
- case 'O':
- outName = "long double";
- return true;
- case 'X':
- outName += "void";
- return true;
- case '?':
- if (mInArgs)
- {
- int num = DemangleNumber();
- //
- }
- else
- {
- DemangleModifiedType(outName, false);
- }
- break;
- default:
- return Failed();
- break;
- }
- return false;
- }
- int MsDemangler::DemangleNumber()
- {
- char c = SafeGetChar(mMangledName, mCurIdx++);
- bool isSigned = false;
- if (c == '?')
- {
- isSigned = true;
- c = SafeGetChar(mMangledName, mCurIdx++);
- }
- if ((c >= '0') && (c <= '9'))
- {
- return c - '0' + 1;
- }
- int val = 0;
- while ((c >= 'A') && (c <= 'P'))
- {
- val = (val * 0x10) + (c - 'A');
- c = SafeGetChar(mMangledName, mCurIdx++);
- }
- if (c != '@')
- Failed();
- return val;
- }
- bool MsDemangler::DemangleCV(StringImpl& outName)
- {
- String modifier;
- while (true)
- {
- char c = SafeGetChar(mMangledName, mCurIdx++);
- if (c == 'E')
- {
- // __ptr64
- }
- else if (c == 'F')
- {
- // Unaligned
- //BF_ASSERT("Unhandled");
- }
- else if (c == 'I')
- {
- // __restrict
- }
- else
- break;
- }
- mCurIdx--;
- //int modifier = DemangleConst();
- char c = SafeGetChar(mMangledName, mCurIdx++);
- int constVal = 0;
- //BF_ASSERT((c >= 'A') && (c <= 'X'));
- if ((c < 'A') || (c > 'X'))
- {
- return Failed();
- }
- constVal = c - 'A';
- if ((constVal & 3) == 3)
- outName = "const volatile";
- else if ((constVal & 1) != 0)
- outName = "const";
- else if ((constVal & 2) != 0)
- outName = "const";
- /*switch (c)
- {
- case 'A':
- case 'M':
- case 'Q':
- case 'U':
- case 'Y':
- case '2':
- // None
- break;
- case 'B':
- case 'J':
- case 'R':
- case 'V':
- case 'Z':
- case '3':
- modifier = "const";
- break;
- case 'C':
- case 'G':
- case 'K':
- case 'S':
- case 'W':
- case '0':
- modifier = "volatile";
- break;
- case 'D':
- case 'H':
- case 'L':
- modifier = "const volatile";
- break;
- default:
- BF_ASSERT("Unhandled");
- }*/
- return true;
- }
- bool MsDemangler::DemangleName(StringImpl& outName)
- {
- bool appendRetType = false;
- bool hasTemplateArgs = false;
- char c = SafeGetChar(mMangledName, mCurIdx++);
- if (c == '?')
- {
- c = SafeGetChar(mMangledName, mCurIdx++);
- if (c == '$')
- {
- mCurIdx++;
- c = SafeGetChar(mMangledName, mCurIdx++);
- hasTemplateArgs = true;
- }
- String primaryName;
- const char* funcName = NULL;
- switch (c)
- {
- case '0':
- // Ctor
- Require(DemangleScopedName(outName, &primaryName));
- if (mLanguage == DbgLanguage_Beef)
- outName += ".this";
- else
- outName += "::" + primaryName;
- break;
- case '1':
- // Dtor
- Require(DemangleScopedName(outName, &primaryName));
- if (mLanguage == DbgLanguage_Beef)
- outName += ".~this";
- else
- outName += "::~" + primaryName;
- break;
- case '2': funcName = "operator new"; break;
- case '3': funcName = "operator delete"; break;
- case '4': funcName = "operator="; break;
- case '5': funcName = "operator>>"; break;
- case '6': funcName = "operator<<"; break;
- case '7': funcName = "operator!"; break;
- case '8': funcName = "operator=="; break;
- case '9': funcName = "operator!="; break;
- case 'A': funcName = "operator[]"; break;
- case 'B':
- funcName = "operator ";
- appendRetType = true;
- break;
- case 'C': funcName = "operator->"; break;
- case 'D': funcName = "operator*"; break;
- case 'E': funcName = "operator++"; break;
- case 'F': funcName = "operator--"; break;
- case 'G': funcName = "operator-"; break;
- case 'H': funcName = "operator+"; break;
- case 'I': funcName = "operator&"; break;
- case 'J': funcName = "operator->*"; break;
- case 'K': funcName = "operator/"; break;
- case 'L': funcName = "operator%"; break;
- case 'M': funcName = "operator<"; break;
- case 'N': funcName = "operator<="; break;
- case 'O': funcName = "operator>"; break;
- case 'P': funcName = "operator>="; break;
- case 'Q': funcName = "operator,"; break;
- case 'R': funcName = "operator()"; break;
- case 'S': funcName = "operator~"; break;
- case 'T': funcName = "operator^"; break;
- case 'U': funcName = "operator|"; break;
- case 'V': funcName = "operator&&"; break;
- case 'W': funcName = "operator||"; break;
- case 'X': funcName = "operator*="; break;
- case 'Y': funcName = "operator+="; break;
- case 'Z': funcName = "operator-="; break;
- case '_':
- {
- c = SafeGetChar(mMangledName, mCurIdx++);
- switch (c)
- {
- case '0': funcName = "operator/="; break;
- case '1': funcName = "operator%="; break;
- case '2': funcName = "operator>>="; break;
- case '3': funcName = "operator<<="; break;
- case '4': funcName = "operator&="; break;
- case '5': funcName = "operator|="; break;
- case '6': funcName = "operator^="; break;
- case '7': funcName = "`vftable'"; break;
- case '8': funcName = "`vbtable'"; break;
- case '9': funcName = "`vcall'"; break;
- case 'A': funcName = "`typeof'"; break;
- case 'B': funcName = "`local static guard'"; break;
- //case 'C': funcName = "`string'"; do_after = 4; break;
- case 'D': funcName = "`vbase destructor'"; break;
- case 'E': funcName = "`vector deleting destructor'"; break;
- case 'F': funcName = "`default constructor closure'"; break;
- case 'G': funcName = "`scalar deleting destructor'"; break;
- case 'H': funcName = "`vector constructor iterator'"; break;
- case 'I': funcName = "`vector destructor iterator'"; break;
- case 'J': funcName = "`vector vbase constructor iterator'"; break;
- case 'K': funcName = "`virtual displacement map'"; break;
- case 'L': funcName = "`eh vector constructor iterator'"; break;
- case 'M': funcName = "`eh vector destructor iterator'"; break;
- case 'N': funcName = "`eh vector vbase constructor iterator'"; break;
- case 'O': funcName = "`copy constructor closure'"; break;
- case 'R':
- c = SafeGetChar(mMangledName, mCurIdx++);
- switch (c)
- {
- case 0: funcName = "`RTTI Type Descriptor'"; break;
- case 1: funcName = "`RTTI Class Descriptor'"; break;
- case '2': funcName = "`RTTI Base Class Array'"; break;
- case '3': funcName = "`RTTI Class Hierarchy Descriptor'"; break;
- case '4': funcName = "`RTTI Complete Object Locater"; break;
- }
- break;
- case 'S': funcName = "`local vftable'"; break;
- case 'T': funcName = "`local vftable constructor closure'"; break;
- case 'U': funcName = "operator new[]"; break;
- case 'V': funcName = "operator delete[]"; break;
- case 'X': funcName = "`placement delete closure'"; break;
- case 'Y': funcName = "`placement delete[] closure'"; break;
- }
- }
- break;
- default:
- mCurIdx -= 2;
- break;
- }
- if (funcName != NULL)
- {
- if (strcmp(funcName, "__BfCtor") == 0)
- funcName = "this";
- else if (strcmp(funcName, "__BfCtorClear") == 0)
- funcName = "this$clear";
- else if (strcmp(funcName, "__BfStaticCtor") == 0)
- funcName = "this";
- if (hasTemplateArgs)
- {
- outName += funcName;
- outName += "<";
- for (int paramIdx = 0; true; paramIdx++)
- {
- String paramType;
- if (!DemangleType(paramType))
- break;
- if (paramType == "void")
- break;
- if (paramIdx > 0)
- outName += ", ";
- outName += paramType;
- }
- outName += ">";
- mSubstituteList.Clear();
- StringT<128> scopeName;
- Require(DemangleScopedName(scopeName, &primaryName));
- if (!scopeName.empty())
- {
- if (mLanguage == DbgLanguage_Beef)
- {
- scopeName += ".";
- }
- else
- scopeName += "::";
- outName.Insert(0, scopeName);
- }
- /*outName += "(";
- for (int paramIdx = 0; true; paramIdx++)
- {
- String paramType;
- if (!DemangleType(paramType))
- break;
- if (paramType == "void")
- break;
- if (paramIdx > 0)
- outName += ", ";
- outName += paramType;
- }
- outName += ")";*/
- }
- else
- {
- Require(DemangleScopedName(outName, &primaryName));
- if (!primaryName.empty())
- {
- if (mLanguage == DbgLanguage_Beef)
- outName += ".";
- else
- outName += "::";
- }
- outName += funcName;
- }
- }
- else if (outName.empty())
- {
- if (hasTemplateArgs)
- {
- Require(DemangleString(outName));
- primaryName = outName;
- outName += "<";
- for (int paramIdx = 0; true; paramIdx++)
- {
- String paramType;
- if (!DemangleType(paramType))
- break;
- if (paramType == "void")
- break;
- if (paramIdx > 0)
- outName += ", ";
- outName += paramType;
- }
- outName += ">";
- mSubstituteList.Clear();
- String scopeName;
- Require(DemangleScopedName(scopeName, &primaryName));
- if (!scopeName.empty())
- {
- if (mLanguage == DbgLanguage_Beef)
- scopeName += ".";
- else
- scopeName += "::";
- outName.Insert(0, scopeName);
- }
- }
- else
- {
- Require(DemangleScopedName(outName, &primaryName));
- }
- }
- }
- else
- {
- mCurIdx--;
- Require(DemangleScopedName(outName));
- }
- c = SafeGetChar(mMangledName, mCurIdx++);
- if ((c >= '0') && (c <= '9'))
- {
- if ((c == '2') || (c == '3'))
- {
- // Global variable / static member
- String varType;
- Require(DemangleType(varType));
- c = SafeGetChar(mMangledName, mCurIdx++);
- // 0 = private, 1 = protected, 2 = public
- return true;
- }
- return true;
- }
- // Method attribute
- if (c == 0)
- return true;
- struct
- {
- uint8 mUnused1 : 1;
- uint8 mType : 2; // normal, static, virtual, thunk
- uint8 mAccess : 3; // private, protected, public, non-member
- uint8 mUnused2 : 2;
- } methodData;
- *((uint8*)&methodData) = (c - 'A');
- //int funcTypeVal = c - 'A';
- //int accessType = funcTypeVal >> 3;
- //bool isNonMember = c == 'Y';
- //bool isVirtual = (c == 'E') || (c == 'M') || (c == 'U');
- //bool hasThis = isVirtual || (c == 'A') || (c == 'I') || (c == 'Q');
- bool isNonMember = methodData.mAccess == 3;
- bool hasThis = !isNonMember && ((methodData.mType == 0) || (methodData.mType == 2));
- // CV qualifier
- if (hasThis)
- {
- String cvQualifier;
- if (!DemangleCV(cvQualifier))
- return false;
- // Ignore
- }
- // Calling convention
- c = SafeGetChar(mMangledName, mCurIdx++);
- union
- {
- uint8 mDllExport : 1;
- uint8 mCallingConv : 7; // cdecl, pascal, thiscall, stdcall, fastcall
- } callType;
- *((uint8*)&callType) = (c - 'A');
- if (callType.mCallingConv > 6)
- return Failed();
- String retType;
- DemangleType(retType);
- if (appendRetType)
- outName += retType;
- // This was needed for System.ValueType.Equals<_M0>(_M0, ValueType)
- // Do we need to clear ALWAYS before param list though?
- if (hasTemplateArgs)
- mSubstituteList.Clear();
- mInArgs = true;
- outName += "(";
- for (int paramIdx = 0; true; paramIdx++)
- {
- String paramType;
- if (!DemangleType(paramType))
- break;
- if (paramType == "void")
- break;
- if (paramIdx > 0)
- outName += ", ";
- outName += paramType;
- }
- outName += ")";
- return true;
- }
- String MsDemangler::Demangle(const StringImpl& mangledName)
- {
- StringT<256> outName;
- mMangledName = mangledName;
- char c = mangledName[mCurIdx++];
- BF_ASSERT(c == '?');
- DemangleName(outName);
- if (mFailed)
- return mangledName;
- //return outName;
- //return outName + " : " + mangledName;
- return outName;
- }
- //////////////////////////////////////////////////////////////////////////
- MsDemangleScanner::MsDemangleScanner()
- {
- mCurIdx = 0;
- mIsData = false;
- }
- bool MsDemangleScanner::DemangleString()
- {
- while (true)
- {
- char c = SafeGetChar(mMangledName, mCurIdx++);
- if ((c == '!') || (c == '?'))
- return Failed();
- if (c == '@')
- break;
- }
- //mSubstituteList.push_back(outName);
- return true;
- }
- bool MsDemangleScanner::DemangleTemplateName()
- {
- DemangleString();
- for (int paramIdx = 0; true; paramIdx++)
- {
- if (!DemangleType())
- break;
- }
- return true;
- }
- bool MsDemangleScanner::DemangleScopedName()
- {
- for (int nameIdx = 0; true; nameIdx++)
- {
- if (mFailed)
- return false;
- char c = SafeGetChar(mMangledName, mCurIdx++);
- if (c == '@')
- return true;
- if (c == '?')
- {
- c = SafeGetChar(mMangledName, mCurIdx++);
- if (c == '$')
- {
- DemangleTemplateName();
- }
- else if (c == '?')
- {
- return Failed();
- }
- else
- {
- mCurIdx--;
- int num = DemangleNumber();
- }
- }
- else if ((c >= '0') && (c <= '9'))
- {
- int subIdx = c - '0';
- if (subIdx < mSubstituteList.size())
- {
- //
- }
- else
- {
- // Ignore error
- }
- }
- else
- {
- mCurIdx--;
- Require(DemangleString());
- }
- }
- }
- bool MsDemangleScanner::DemangleModifiedType(bool isPtr)
- {
- DemangleCV();
- char c = SafeGetChar(mMangledName, mCurIdx);
- if (c == 'Y') // Sized array
- {
- mCurIdx++;
- int dimCount = DemangleNumber();
- for (int dim = 0; dim < dimCount; dim++)
- {
- int dimSize = DemangleNumber();
- }
- DemangleType();
- }
- else
- {
- DemangleType();
- }
- return true;
- }
- bool MsDemangleScanner::DemangleType()
- {
- char c = SafeGetChar(mMangledName, mCurIdx++);
- if ((c == 0) || (c == '@'))
- return false;
- switch (c)
- {
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- {
- if (mFailed)
- return false;
- int subIdx = c - '0';
- if ((subIdx < 0) || (subIdx >= (int)mSubstituteList.size()))
- return Failed();
- return true;
- }
- break;
- case '$':
- {
- char c = SafeGetChar(mMangledName, mCurIdx++);
- switch (c)
- {
- case '0':
- return Failed();
- break;
- case 'D':
- {
- int templateParamNum = DemangleNumber();
- return Failed();
- }
- break;
- case 'F':
- {
- int param1 = DemangleNumber();
- int param2 = DemangleNumber();
- return Failed();
- }
- break;
- case 'G':
- {
- int param1 = DemangleNumber();
- int param2 = DemangleNumber();
- int param3 = DemangleNumber();
- return Failed();
- }
- break;
- case 'Q':
- {
- int nonTypeTemplateParam = DemangleNumber();
- return Failed();
- }
- break;
- case '$':
- {
- char c = SafeGetChar(mMangledName, mCurIdx++);
- if (c == 'C')
- {
- DemangleCV();
- DemangleType();
- return true;
- }
- else if (c == 'Q')
- {
- DemangleCV();
- DemangleType();
- return true;
- }
- }
- break;
- }
- }
- break;
- case '_':
- {
- c = SafeGetChar(mMangledName, mCurIdx++);
- switch (c)
- {
- case 'D':
- return true;
- case 'E':
- return true;
- case 'F':
- return true;
- case 'G':
- return true;
- case 'H':
- return true;
- case 'I':
- return true;
- case 'J':
- return true;
- case 'K':
- return true;
- case 'L':
- return true;
- case 'M':
- return true;
- case 'W':
- return true;
- case 'N':
- return true;
- default:
- return Failed();
- break;
- }
- }
- break;
- case 'A':
- {
- DemangleModifiedType(false);
- }
- return true;
- case 'B':
- DemangleModifiedType(false);
- return true;
- case 'P':
- DemangleModifiedType(true);
- return true;
- case 'Q':
- DemangleModifiedType(true);
- return true;
- case 'R':
- DemangleModifiedType(true);
- return true;
- case 'S':
- DemangleModifiedType(true);
- return true;
- case 'T':
- // union
- DemangleScopedName();
- return true;
- case 'U':
- // struct
- DemangleScopedName();
- return true;
- case 'V':
- // class
- DemangleScopedName();
- return true;
- case 'W':
- // enum
- c = SafeGetChar(mMangledName, mCurIdx++);
- Require((c >= '0') && (c <= '8'));
- DemangleScopedName();
- return true;
- case 'C':
- return true;
- case 'D':
- return true;
- case 'E':
- return true;
- case 'F':
- return true;
- case 'G':
- return true;
- case 'H':
- return true;
- case 'I':
- return true;
- case 'J':
- return true;
- case 'K':
- return true;
- case 'M':
- return true;
- case 'N':
- return true;
- case 'O':
- return true;
- case 'X':
- return true;
- case '?':
- if (mInArgs)
- {
- int num = DemangleNumber();
- //
- }
- else
- {
- DemangleModifiedType(false);
- }
- break;
- default:
- return Failed();
- break;
- }
- return false;
- }
- int MsDemangleScanner::DemangleNumber()
- {
- char c = SafeGetChar(mMangledName, mCurIdx++);
- bool isSigned = false;
- if (c == '?')
- {
- isSigned = true;
- c = SafeGetChar(mMangledName, mCurIdx++);
- }
- if ((c >= '0') && (c <= '9'))
- {
- return c - '0' + 1;
- }
- int val = 0;
- while ((c >= 'A') && (c <= 'P'))
- {
- val = (val * 10) + (c - 'A');
- c = SafeGetChar(mMangledName, mCurIdx++);
- }
- if (c != '@')
- Failed();
- return val;
- }
- bool MsDemangleScanner::DemangleCV()
- {
- while (true)
- {
- char c = SafeGetChar(mMangledName, mCurIdx++);
- if (c == 'E')
- {
- // __ptr64
- }
- else if (c == 'F')
- {
- // Unaligned
- //BF_ASSERT("Unhandled");
- }
- else if (c == 'I')
- {
- // __restrict
- }
- else
- break;
- }
- mCurIdx--;
- char c = SafeGetChar(mMangledName, mCurIdx++);
- int constVal = 0;
- if ((c < 'A') || (c > 'X'))
- {
- return Failed();
- }
- constVal = c - 'A';
- return true;
- }
- bool MsDemangleScanner::DemangleName()
- {
- bool appendRetType = false;
- bool hasTemplateArgs = false;
- char c = SafeGetChar(mMangledName, mCurIdx++);
- if (c == '?')
- {
- // A ?? is always a function
- return true;
- }
- else
- {
- mCurIdx--;
- Require(DemangleScopedName());
- }
- c = SafeGetChar(mMangledName, mCurIdx++);
- if ((c >= '0') && (c <= '9'))
- {
- // Global variable / static member
- mIsData = true;
- return true;
- }
- // Not data
- return true;
- }
- void MsDemangleScanner::Process(const StringImpl& mangledName)
- {
- mMangledName = mangledName;
- char c = mangledName[mCurIdx++];
- BF_ASSERT(c == '?');
- DemangleName();
- if (mFailed)
- {
- mIsData = false;
- }
- }
- //////////////////////////////////////////////////////////////////////////
- String BfDemangler::Demangle(const StringImpl& mangledName, DbgLanguage language, Flags flags)
- {
- if (mangledName.IsEmpty())
- return "";
- if (mangledName[0] == '?')
- {
- MsDemangler demangler;
- demangler.mLanguage = language;
- demangler.mBeefFixed = (flags & BfDemangler::Flag_BeefFixed) != 0;
- return demangler.Demangle(mangledName);
- }
- else
- {
- DwDemangler demangler;
- demangler.mLanguage = language;
- demangler.mCaptureTargetType = (flags & BfDemangler::Flag_CaptureTargetType) != 0;
- demangler.mRawDemangle = (flags & BfDemangler::Flag_RawDemangle) != 0;
- demangler.mBeefFixed = (flags & BfDemangler::Flag_BeefFixed) != 0;
- return demangler.Demangle(mangledName);
- }
- }
- bool BfDemangler::IsData(const StringImpl& mangledName)
- {
- if (mangledName[0] == '?')
- {
- MsDemangleScanner demangler;
- demangler.Process(mangledName);
- return demangler.mIsData;
- }
- return false;
- }
|