Mangle.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601
  1. //===--- Mangle.cpp - Mangle C++ Names --------------------------*- C++ -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // Implements generic name mangling support for blocks and Objective-C.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. #include "clang/AST/Attr.h"
  13. #include "clang/AST/ASTContext.h"
  14. #include "clang/AST/Decl.h"
  15. #include "clang/AST/DeclCXX.h"
  16. #include "clang/AST/DeclObjC.h"
  17. #include "clang/AST/DeclTemplate.h"
  18. #include "clang/AST/ExprCXX.h"
  19. #include "clang/AST/Mangle.h"
  20. #include "clang/AST/VTableBuilder.h"
  21. #include "clang/Basic/ABI.h"
  22. #include "clang/Basic/SourceManager.h"
  23. #include "clang/Basic/TargetInfo.h"
  24. #include "llvm/ADT/StringExtras.h"
  25. #include "llvm/IR/DataLayout.h"
  26. #include "llvm/IR/Mangler.h"
  27. #include "llvm/Support/ErrorHandling.h"
  28. #include "llvm/Support/Format.h"
  29. #include "llvm/Support/raw_ostream.h"
  30. using namespace clang;
  31. // FIXME: For blocks we currently mimic GCC's mangling scheme, which leaves
  32. // much to be desired. Come up with a better mangling scheme.
  33. static void mangleFunctionBlock(MangleContext &Context,
  34. StringRef Outer,
  35. const BlockDecl *BD,
  36. raw_ostream &Out) {
  37. unsigned discriminator = Context.getBlockId(BD, true);
  38. if (discriminator == 0)
  39. Out << "__" << Outer << "_block_invoke";
  40. else
  41. Out << "__" << Outer << "_block_invoke_" << discriminator+1;
  42. }
  43. void MangleContext::anchor() { }
  44. enum CCMangling {
  45. CCM_Other,
  46. CCM_Fast,
  47. CCM_RegCall,
  48. CCM_Vector,
  49. CCM_Std,
  50. CCM_WasmMainArgcArgv
  51. };
  52. static bool isExternC(const NamedDecl *ND) {
  53. if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND))
  54. return FD->isExternC();
  55. if (const VarDecl *VD = dyn_cast<VarDecl>(ND))
  56. return VD->isExternC();
  57. return false;
  58. }
  59. static CCMangling getCallingConvMangling(const ASTContext &Context,
  60. const NamedDecl *ND) {
  61. const TargetInfo &TI = Context.getTargetInfo();
  62. const llvm::Triple &Triple = TI.getTriple();
  63. // On wasm, the argc/argv form of "main" is renamed so that the startup code
  64. // can call it with the correct function signature.
  65. // On Emscripten, users may be exporting "main" and expecting to call it
  66. // themselves, so we can't mangle it.
  67. if (Triple.isWasm() && !Triple.isOSEmscripten())
  68. if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND))
  69. if (FD->isMain() && FD->hasPrototype() && FD->param_size() == 2)
  70. return CCM_WasmMainArgcArgv;
  71. if (!Triple.isOSWindows() || !Triple.isX86())
  72. return CCM_Other;
  73. if (Context.getLangOpts().CPlusPlus && !isExternC(ND) &&
  74. TI.getCXXABI() == TargetCXXABI::Microsoft)
  75. return CCM_Other;
  76. const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND);
  77. if (!FD)
  78. return CCM_Other;
  79. QualType T = FD->getType();
  80. const FunctionType *FT = T->castAs<FunctionType>();
  81. CallingConv CC = FT->getCallConv();
  82. switch (CC) {
  83. default:
  84. return CCM_Other;
  85. case CC_X86FastCall:
  86. return CCM_Fast;
  87. case CC_X86StdCall:
  88. return CCM_Std;
  89. case CC_X86VectorCall:
  90. return CCM_Vector;
  91. }
  92. }
  93. bool MangleContext::shouldMangleDeclName(const NamedDecl *D) {
  94. const ASTContext &ASTContext = getASTContext();
  95. CCMangling CC = getCallingConvMangling(ASTContext, D);
  96. if (CC != CCM_Other)
  97. return true;
  98. // If the declaration has an owning module for linkage purposes that needs to
  99. // be mangled, we must mangle its name.
  100. if (!D->hasExternalFormalLinkage() && D->getOwningModuleForLinkage())
  101. return true;
  102. // C functions with internal linkage have to be mangled with option
  103. // -funique-internal-linkage-names.
  104. if (!getASTContext().getLangOpts().CPlusPlus &&
  105. isUniqueInternalLinkageDecl(D))
  106. return true;
  107. // In C, functions with no attributes never need to be mangled. Fastpath them.
  108. if (!getASTContext().getLangOpts().CPlusPlus && !D->hasAttrs())
  109. return false;
  110. // Any decl can be declared with __asm("foo") on it, and this takes precedence
  111. // over all other naming in the .o file.
  112. if (D->hasAttr<AsmLabelAttr>())
  113. return true;
  114. // Declarations that don't have identifier names always need to be mangled.
  115. if (isa<MSGuidDecl>(D))
  116. return true;
  117. return shouldMangleCXXName(D);
  118. }
  119. void MangleContext::mangleName(GlobalDecl GD, raw_ostream &Out) {
  120. const ASTContext &ASTContext = getASTContext();
  121. const NamedDecl *D = cast<NamedDecl>(GD.getDecl());
  122. // Any decl can be declared with __asm("foo") on it, and this takes precedence
  123. // over all other naming in the .o file.
  124. if (const AsmLabelAttr *ALA = D->getAttr<AsmLabelAttr>()) {
  125. // If we have an asm name, then we use it as the mangling.
  126. // If the label isn't literal, or if this is an alias for an LLVM intrinsic,
  127. // do not add a "\01" prefix.
  128. if (!ALA->getIsLiteralLabel() || ALA->getLabel().startswith("llvm.")) {
  129. Out << ALA->getLabel();
  130. return;
  131. }
  132. // Adding the prefix can cause problems when one file has a "foo" and
  133. // another has a "\01foo". That is known to happen on ELF with the
  134. // tricks normally used for producing aliases (PR9177). Fortunately the
  135. // llvm mangler on ELF is a nop, so we can just avoid adding the \01
  136. // marker.
  137. StringRef UserLabelPrefix =
  138. getASTContext().getTargetInfo().getUserLabelPrefix();
  139. #ifndef NDEBUG
  140. char GlobalPrefix =
  141. llvm::DataLayout(getASTContext().getTargetInfo().getDataLayoutString())
  142. .getGlobalPrefix();
  143. assert((UserLabelPrefix.empty() && !GlobalPrefix) ||
  144. (UserLabelPrefix.size() == 1 && UserLabelPrefix[0] == GlobalPrefix));
  145. #endif
  146. if (!UserLabelPrefix.empty())
  147. Out << '\01'; // LLVM IR Marker for __asm("foo")
  148. Out << ALA->getLabel();
  149. return;
  150. }
  151. if (auto *GD = dyn_cast<MSGuidDecl>(D))
  152. return mangleMSGuidDecl(GD, Out);
  153. CCMangling CC = getCallingConvMangling(ASTContext, D);
  154. if (CC == CCM_WasmMainArgcArgv) {
  155. Out << "__main_argc_argv";
  156. return;
  157. }
  158. bool MCXX = shouldMangleCXXName(D);
  159. const TargetInfo &TI = Context.getTargetInfo();
  160. if (CC == CCM_Other || (MCXX && TI.getCXXABI() == TargetCXXABI::Microsoft)) {
  161. if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D))
  162. mangleObjCMethodNameAsSourceName(OMD, Out);
  163. else
  164. mangleCXXName(GD, Out);
  165. return;
  166. }
  167. Out << '\01';
  168. if (CC == CCM_Std)
  169. Out << '_';
  170. else if (CC == CCM_Fast)
  171. Out << '@';
  172. else if (CC == CCM_RegCall)
  173. Out << "__regcall3__";
  174. if (!MCXX)
  175. Out << D->getIdentifier()->getName();
  176. else if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D))
  177. mangleObjCMethodNameAsSourceName(OMD, Out);
  178. else
  179. mangleCXXName(GD, Out);
  180. const FunctionDecl *FD = cast<FunctionDecl>(D);
  181. const FunctionType *FT = FD->getType()->castAs<FunctionType>();
  182. const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FT);
  183. if (CC == CCM_Vector)
  184. Out << '@';
  185. Out << '@';
  186. if (!Proto) {
  187. Out << '0';
  188. return;
  189. }
  190. assert(!Proto->isVariadic());
  191. unsigned ArgWords = 0;
  192. if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD))
  193. if (!MD->isStatic())
  194. ++ArgWords;
  195. for (const auto &AT : Proto->param_types()) {
  196. // If an argument type is incomplete there is no way to get its size to
  197. // correctly encode into the mangling scheme.
  198. // Follow GCCs behaviour by simply breaking out of the loop.
  199. if (AT->isIncompleteType())
  200. break;
  201. // Size should be aligned to pointer size.
  202. ArgWords +=
  203. llvm::alignTo(ASTContext.getTypeSize(AT), TI.getPointerWidth(0)) /
  204. TI.getPointerWidth(0);
  205. }
  206. Out << ((TI.getPointerWidth(0) / 8) * ArgWords);
  207. }
  208. void MangleContext::mangleMSGuidDecl(const MSGuidDecl *GD, raw_ostream &Out) {
  209. // For now, follow the MSVC naming convention for GUID objects on all
  210. // targets.
  211. MSGuidDecl::Parts P = GD->getParts();
  212. Out << llvm::format("_GUID_%08" PRIx32 "_%04" PRIx32 "_%04" PRIx32 "_",
  213. P.Part1, P.Part2, P.Part3);
  214. unsigned I = 0;
  215. for (uint8_t C : P.Part4And5) {
  216. Out << llvm::format("%02" PRIx8, C);
  217. if (++I == 2)
  218. Out << "_";
  219. }
  220. }
  221. void MangleContext::mangleGlobalBlock(const BlockDecl *BD,
  222. const NamedDecl *ID,
  223. raw_ostream &Out) {
  224. unsigned discriminator = getBlockId(BD, false);
  225. if (ID) {
  226. if (shouldMangleDeclName(ID))
  227. mangleName(ID, Out);
  228. else {
  229. Out << ID->getIdentifier()->getName();
  230. }
  231. }
  232. if (discriminator == 0)
  233. Out << "_block_invoke";
  234. else
  235. Out << "_block_invoke_" << discriminator+1;
  236. }
  237. void MangleContext::mangleCtorBlock(const CXXConstructorDecl *CD,
  238. CXXCtorType CT, const BlockDecl *BD,
  239. raw_ostream &ResStream) {
  240. SmallString<64> Buffer;
  241. llvm::raw_svector_ostream Out(Buffer);
  242. mangleName(GlobalDecl(CD, CT), Out);
  243. mangleFunctionBlock(*this, Buffer, BD, ResStream);
  244. }
  245. void MangleContext::mangleDtorBlock(const CXXDestructorDecl *DD,
  246. CXXDtorType DT, const BlockDecl *BD,
  247. raw_ostream &ResStream) {
  248. SmallString<64> Buffer;
  249. llvm::raw_svector_ostream Out(Buffer);
  250. mangleName(GlobalDecl(DD, DT), Out);
  251. mangleFunctionBlock(*this, Buffer, BD, ResStream);
  252. }
  253. void MangleContext::mangleBlock(const DeclContext *DC, const BlockDecl *BD,
  254. raw_ostream &Out) {
  255. assert(!isa<CXXConstructorDecl>(DC) && !isa<CXXDestructorDecl>(DC));
  256. SmallString<64> Buffer;
  257. llvm::raw_svector_ostream Stream(Buffer);
  258. if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(DC)) {
  259. mangleObjCMethodNameAsSourceName(Method, Stream);
  260. } else {
  261. assert((isa<NamedDecl>(DC) || isa<BlockDecl>(DC)) &&
  262. "expected a NamedDecl or BlockDecl");
  263. if (isa<BlockDecl>(DC))
  264. for (; DC && isa<BlockDecl>(DC); DC = DC->getParent())
  265. (void) getBlockId(cast<BlockDecl>(DC), true);
  266. assert((isa<TranslationUnitDecl>(DC) || isa<NamedDecl>(DC)) &&
  267. "expected a TranslationUnitDecl or a NamedDecl");
  268. if (const auto *CD = dyn_cast<CXXConstructorDecl>(DC))
  269. mangleCtorBlock(CD, /*CT*/ Ctor_Complete, BD, Out);
  270. else if (const auto *DD = dyn_cast<CXXDestructorDecl>(DC))
  271. mangleDtorBlock(DD, /*DT*/ Dtor_Complete, BD, Out);
  272. else if (auto ND = dyn_cast<NamedDecl>(DC)) {
  273. if (!shouldMangleDeclName(ND) && ND->getIdentifier())
  274. Stream << ND->getIdentifier()->getName();
  275. else {
  276. // FIXME: We were doing a mangleUnqualifiedName() before, but that's
  277. // a private member of a class that will soon itself be private to the
  278. // Itanium C++ ABI object. What should we do now? Right now, I'm just
  279. // calling the mangleName() method on the MangleContext; is there a
  280. // better way?
  281. mangleName(ND, Stream);
  282. }
  283. }
  284. }
  285. mangleFunctionBlock(*this, Buffer, BD, Out);
  286. }
  287. void MangleContext::mangleObjCMethodName(const ObjCMethodDecl *MD,
  288. raw_ostream &OS,
  289. bool includePrefixByte,
  290. bool includeCategoryNamespace) {
  291. if (getASTContext().getLangOpts().ObjCRuntime.isGNUFamily()) {
  292. // This is the mangling we've always used on the GNU runtimes, but it
  293. // has obvious collisions in the face of underscores within class
  294. // names, category names, and selectors; maybe we should improve it.
  295. OS << (MD->isClassMethod() ? "_c_" : "_i_")
  296. << MD->getClassInterface()->getName() << '_';
  297. if (includeCategoryNamespace) {
  298. if (auto category = MD->getCategory())
  299. OS << category->getName();
  300. }
  301. OS << '_';
  302. auto selector = MD->getSelector();
  303. for (unsigned slotIndex = 0,
  304. numArgs = selector.getNumArgs(),
  305. slotEnd = std::max(numArgs, 1U);
  306. slotIndex != slotEnd; ++slotIndex) {
  307. if (auto name = selector.getIdentifierInfoForSlot(slotIndex))
  308. OS << name->getName();
  309. // Replace all the positions that would've been ':' with '_'.
  310. // That's after each slot except that a unary selector doesn't
  311. // end in ':'.
  312. if (numArgs)
  313. OS << '_';
  314. }
  315. return;
  316. }
  317. // \01+[ContainerName(CategoryName) SelectorName]
  318. if (includePrefixByte) {
  319. OS << '\01';
  320. }
  321. OS << (MD->isInstanceMethod() ? '-' : '+') << '[';
  322. if (const auto *CID = MD->getCategory()) {
  323. OS << CID->getClassInterface()->getName();
  324. if (includeCategoryNamespace) {
  325. OS << '(' << *CID << ')';
  326. }
  327. } else if (const auto *CD =
  328. dyn_cast<ObjCContainerDecl>(MD->getDeclContext())) {
  329. OS << CD->getName();
  330. } else {
  331. llvm_unreachable("Unexpected ObjC method decl context");
  332. }
  333. OS << ' ';
  334. MD->getSelector().print(OS);
  335. OS << ']';
  336. }
  337. void MangleContext::mangleObjCMethodNameAsSourceName(const ObjCMethodDecl *MD,
  338. raw_ostream &Out) {
  339. SmallString<64> Name;
  340. llvm::raw_svector_ostream OS(Name);
  341. mangleObjCMethodName(MD, OS, /*includePrefixByte=*/false,
  342. /*includeCategoryNamespace=*/true);
  343. Out << OS.str().size() << OS.str();
  344. }
  345. class ASTNameGenerator::Implementation {
  346. std::unique_ptr<MangleContext> MC;
  347. llvm::DataLayout DL;
  348. public:
  349. explicit Implementation(ASTContext &Ctx)
  350. : MC(Ctx.createMangleContext()),
  351. DL(Ctx.getTargetInfo().getDataLayoutString()) {}
  352. bool writeName(const Decl *D, raw_ostream &OS) {
  353. // First apply frontend mangling.
  354. SmallString<128> FrontendBuf;
  355. llvm::raw_svector_ostream FrontendBufOS(FrontendBuf);
  356. if (auto *FD = dyn_cast<FunctionDecl>(D)) {
  357. if (FD->isDependentContext())
  358. return true;
  359. if (writeFuncOrVarName(FD, FrontendBufOS))
  360. return true;
  361. } else if (auto *VD = dyn_cast<VarDecl>(D)) {
  362. if (writeFuncOrVarName(VD, FrontendBufOS))
  363. return true;
  364. } else if (auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
  365. MC->mangleObjCMethodName(MD, OS, /*includePrefixByte=*/false,
  366. /*includeCategoryNamespace=*/true);
  367. return false;
  368. } else if (auto *ID = dyn_cast<ObjCInterfaceDecl>(D)) {
  369. writeObjCClassName(ID, FrontendBufOS);
  370. } else {
  371. return true;
  372. }
  373. // Now apply backend mangling.
  374. llvm::Mangler::getNameWithPrefix(OS, FrontendBufOS.str(), DL);
  375. return false;
  376. }
  377. std::string getName(const Decl *D) {
  378. std::string Name;
  379. {
  380. llvm::raw_string_ostream OS(Name);
  381. writeName(D, OS);
  382. }
  383. return Name;
  384. }
  385. enum ObjCKind {
  386. ObjCClass,
  387. ObjCMetaclass,
  388. };
  389. static StringRef getClassSymbolPrefix(ObjCKind Kind,
  390. const ASTContext &Context) {
  391. if (Context.getLangOpts().ObjCRuntime.isGNUFamily())
  392. return Kind == ObjCMetaclass ? "_OBJC_METACLASS_" : "_OBJC_CLASS_";
  393. return Kind == ObjCMetaclass ? "OBJC_METACLASS_$_" : "OBJC_CLASS_$_";
  394. }
  395. std::vector<std::string> getAllManglings(const ObjCContainerDecl *OCD) {
  396. StringRef ClassName;
  397. if (const auto *OID = dyn_cast<ObjCInterfaceDecl>(OCD))
  398. ClassName = OID->getObjCRuntimeNameAsString();
  399. else if (const auto *OID = dyn_cast<ObjCImplementationDecl>(OCD))
  400. ClassName = OID->getObjCRuntimeNameAsString();
  401. if (ClassName.empty())
  402. return {};
  403. auto Mangle = [&](ObjCKind Kind, StringRef ClassName) -> std::string {
  404. SmallString<40> Mangled;
  405. auto Prefix = getClassSymbolPrefix(Kind, OCD->getASTContext());
  406. llvm::Mangler::getNameWithPrefix(Mangled, Prefix + ClassName, DL);
  407. return std::string(Mangled.str());
  408. };
  409. return {
  410. Mangle(ObjCClass, ClassName),
  411. Mangle(ObjCMetaclass, ClassName),
  412. };
  413. }
  414. std::vector<std::string> getAllManglings(const Decl *D) {
  415. if (const auto *OCD = dyn_cast<ObjCContainerDecl>(D))
  416. return getAllManglings(OCD);
  417. if (!(isa<CXXRecordDecl>(D) || isa<CXXMethodDecl>(D)))
  418. return {};
  419. const NamedDecl *ND = cast<NamedDecl>(D);
  420. ASTContext &Ctx = ND->getASTContext();
  421. std::unique_ptr<MangleContext> M(Ctx.createMangleContext());
  422. std::vector<std::string> Manglings;
  423. auto hasDefaultCXXMethodCC = [](ASTContext &C, const CXXMethodDecl *MD) {
  424. auto DefaultCC = C.getDefaultCallingConvention(/*IsVariadic=*/false,
  425. /*IsCXXMethod=*/true);
  426. auto CC = MD->getType()->castAs<FunctionProtoType>()->getCallConv();
  427. return CC == DefaultCC;
  428. };
  429. if (const auto *CD = dyn_cast_or_null<CXXConstructorDecl>(ND)) {
  430. Manglings.emplace_back(getMangledStructor(CD, Ctor_Base));
  431. if (Ctx.getTargetInfo().getCXXABI().isItaniumFamily())
  432. if (!CD->getParent()->isAbstract())
  433. Manglings.emplace_back(getMangledStructor(CD, Ctor_Complete));
  434. if (Ctx.getTargetInfo().getCXXABI().isMicrosoft())
  435. if (CD->hasAttr<DLLExportAttr>() && CD->isDefaultConstructor())
  436. if (!(hasDefaultCXXMethodCC(Ctx, CD) && CD->getNumParams() == 0))
  437. Manglings.emplace_back(getMangledStructor(CD, Ctor_DefaultClosure));
  438. } else if (const auto *DD = dyn_cast_or_null<CXXDestructorDecl>(ND)) {
  439. Manglings.emplace_back(getMangledStructor(DD, Dtor_Base));
  440. if (Ctx.getTargetInfo().getCXXABI().isItaniumFamily()) {
  441. Manglings.emplace_back(getMangledStructor(DD, Dtor_Complete));
  442. if (DD->isVirtual())
  443. Manglings.emplace_back(getMangledStructor(DD, Dtor_Deleting));
  444. }
  445. } else if (const auto *MD = dyn_cast_or_null<CXXMethodDecl>(ND)) {
  446. Manglings.emplace_back(getName(ND));
  447. if (MD->isVirtual())
  448. if (const auto *TIV = Ctx.getVTableContext()->getThunkInfo(MD))
  449. for (const auto &T : *TIV)
  450. Manglings.emplace_back(getMangledThunk(MD, T));
  451. }
  452. return Manglings;
  453. }
  454. private:
  455. bool writeFuncOrVarName(const NamedDecl *D, raw_ostream &OS) {
  456. if (MC->shouldMangleDeclName(D)) {
  457. GlobalDecl GD;
  458. if (const auto *CtorD = dyn_cast<CXXConstructorDecl>(D))
  459. GD = GlobalDecl(CtorD, Ctor_Complete);
  460. else if (const auto *DtorD = dyn_cast<CXXDestructorDecl>(D))
  461. GD = GlobalDecl(DtorD, Dtor_Complete);
  462. else if (D->hasAttr<CUDAGlobalAttr>())
  463. GD = GlobalDecl(cast<FunctionDecl>(D));
  464. else
  465. GD = GlobalDecl(D);
  466. MC->mangleName(GD, OS);
  467. return false;
  468. } else {
  469. IdentifierInfo *II = D->getIdentifier();
  470. if (!II)
  471. return true;
  472. OS << II->getName();
  473. return false;
  474. }
  475. }
  476. void writeObjCClassName(const ObjCInterfaceDecl *D, raw_ostream &OS) {
  477. OS << getClassSymbolPrefix(ObjCClass, D->getASTContext());
  478. OS << D->getObjCRuntimeNameAsString();
  479. }
  480. std::string getMangledStructor(const NamedDecl *ND, unsigned StructorType) {
  481. std::string FrontendBuf;
  482. llvm::raw_string_ostream FOS(FrontendBuf);
  483. GlobalDecl GD;
  484. if (const auto *CD = dyn_cast_or_null<CXXConstructorDecl>(ND))
  485. GD = GlobalDecl(CD, static_cast<CXXCtorType>(StructorType));
  486. else if (const auto *DD = dyn_cast_or_null<CXXDestructorDecl>(ND))
  487. GD = GlobalDecl(DD, static_cast<CXXDtorType>(StructorType));
  488. MC->mangleName(GD, FOS);
  489. std::string BackendBuf;
  490. llvm::raw_string_ostream BOS(BackendBuf);
  491. llvm::Mangler::getNameWithPrefix(BOS, FOS.str(), DL);
  492. return BOS.str();
  493. }
  494. std::string getMangledThunk(const CXXMethodDecl *MD, const ThunkInfo &T) {
  495. std::string FrontendBuf;
  496. llvm::raw_string_ostream FOS(FrontendBuf);
  497. MC->mangleThunk(MD, T, FOS);
  498. std::string BackendBuf;
  499. llvm::raw_string_ostream BOS(BackendBuf);
  500. llvm::Mangler::getNameWithPrefix(BOS, FOS.str(), DL);
  501. return BOS.str();
  502. }
  503. };
  504. ASTNameGenerator::ASTNameGenerator(ASTContext &Ctx)
  505. : Impl(std::make_unique<Implementation>(Ctx)) {}
  506. ASTNameGenerator::~ASTNameGenerator() {}
  507. bool ASTNameGenerator::writeName(const Decl *D, raw_ostream &OS) {
  508. return Impl->writeName(D, OS);
  509. }
  510. std::string ASTNameGenerator::getName(const Decl *D) {
  511. return Impl->getName(D);
  512. }
  513. std::vector<std::string> ASTNameGenerator::getAllManglings(const Decl *D) {
  514. return Impl->getAllManglings(D);
  515. }