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