114110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne//===--- Mangle.cpp - Mangle C++ Names --------------------------*- C++ -*-===//
214110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne//
314110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne//                     The LLVM Compiler Infrastructure
414110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne//
514110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne// This file is distributed under the University of Illinois Open Source
614110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne// License. See LICENSE.TXT for details.
714110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne//
814110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne//===----------------------------------------------------------------------===//
914110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne//
1014110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne// Implements generic name mangling support for blocks and Objective-C.
1114110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne//
1214110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne//===----------------------------------------------------------------------===//
13d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola#include "clang/AST/Attr.h"
1414110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne#include "clang/AST/ASTContext.h"
1514110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne#include "clang/AST/Decl.h"
1614110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne#include "clang/AST/DeclCXX.h"
1714110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne#include "clang/AST/DeclObjC.h"
1814110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne#include "clang/AST/DeclTemplate.h"
1914110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne#include "clang/AST/ExprCXX.h"
20651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include "clang/AST/Mangle.h"
2114110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne#include "clang/Basic/ABI.h"
2214110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne#include "clang/Basic/SourceManager.h"
23d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola#include "clang/Basic/TargetInfo.h"
2414110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne#include "llvm/ADT/StringExtras.h"
2514110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne#include "llvm/Support/ErrorHandling.h"
2655fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "llvm/Support/raw_ostream.h"
2714110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne
2814110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne#define MANGLE_CHECKER 0
2914110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne
3014110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne#if MANGLE_CHECKER
3114110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne#include <cxxabi.h>
3214110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne#endif
3314110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne
3414110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourneusing namespace clang;
3514110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne
3614110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne// FIXME: For blocks we currently mimic GCC's mangling scheme, which leaves
3714110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne// much to be desired. Come up with a better mangling scheme.
3814110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne
3914110477887e3dc168ffc6c191e72d705051f99ePeter Collingbournestatic void mangleFunctionBlock(MangleContext &Context,
405f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                                StringRef Outer,
4114110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne                                const BlockDecl *BD,
425f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                                raw_ostream &Out) {
434904bf4e84cfb48080270ebaa9005327f18ab0e5Fariborz Jahanian  unsigned discriminator = Context.getBlockId(BD, true);
444904bf4e84cfb48080270ebaa9005327f18ab0e5Fariborz Jahanian  if (discriminator == 0)
454904bf4e84cfb48080270ebaa9005327f18ab0e5Fariborz Jahanian    Out << "__" << Outer << "_block_invoke";
464904bf4e84cfb48080270ebaa9005327f18ab0e5Fariborz Jahanian  else
474904bf4e84cfb48080270ebaa9005327f18ab0e5Fariborz Jahanian    Out << "__" << Outer << "_block_invoke_" << discriminator+1;
4814110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne}
4914110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne
5099ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikievoid MangleContext::anchor() { }
5199ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikie
52d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindolaenum StdOrFastCC {
53d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  SOF_OTHER,
54d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  SOF_FAST,
55d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  SOF_STD
56d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola};
57d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola
58d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindolastatic bool isExternC(const NamedDecl *ND) {
59d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND))
60d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola    return FD->isExternC();
61d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  return cast<VarDecl>(ND)->isExternC();
62d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola}
63d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola
64d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindolastatic StdOrFastCC getStdOrFastCallMangling(const ASTContext &Context,
65d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola                                            const NamedDecl *ND) {
66d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  const TargetInfo &TI = Context.getTargetInfo();
67651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  const llvm::Triple &Triple = TI.getTriple();
68d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  if (!Triple.isOSWindows() || Triple.getArch() != llvm::Triple::x86)
69d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola    return SOF_OTHER;
70d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola
71d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  if (Context.getLangOpts().CPlusPlus && !isExternC(ND) &&
72d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola      TI.getCXXABI() == TargetCXXABI::Microsoft)
73d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola    return SOF_OTHER;
74d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola
75d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND);
76d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  if (!FD)
77d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola    return SOF_OTHER;
78d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  QualType T = FD->getType();
79d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola
80d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  const FunctionType *FT = T->castAs<FunctionType>();
81d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola
82d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  CallingConv CC = FT->getCallConv();
83d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  switch (CC) {
84d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  default:
85d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola    return SOF_OTHER;
86d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  case CC_X86FastCall:
87d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola    return SOF_FAST;
88d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  case CC_X86StdCall:
89d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola    return SOF_STD;
90d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  }
91d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola}
92d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola
93d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindolabool MangleContext::shouldMangleDeclName(const NamedDecl *D) {
94d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  const ASTContext &ASTContext = getASTContext();
95d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola
96d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  StdOrFastCC CC = getStdOrFastCallMangling(ASTContext, D);
97d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  if (CC != SOF_OTHER)
98d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola    return true;
99d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola
100d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  // In C, functions with no attributes never need to be mangled. Fastpath them.
101d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  if (!getASTContext().getLangOpts().CPlusPlus && !D->hasAttrs())
102d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola    return false;
103d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola
104d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  // Any decl can be declared with __asm("foo") on it, and this takes precedence
105d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  // over all other naming in the .o file.
106d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  if (D->hasAttr<AsmLabelAttr>())
107d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola    return true;
108d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola
109d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  return shouldMangleCXXName(D);
110d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola}
111d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola
112d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindolavoid MangleContext::mangleName(const NamedDecl *D, raw_ostream &Out) {
113d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  // Any decl can be declared with __asm("foo") on it, and this takes precedence
114d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  // over all other naming in the .o file.
115d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  if (const AsmLabelAttr *ALA = D->getAttr<AsmLabelAttr>()) {
116d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola    // If we have an asm name, then we use it as the mangling.
117d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola
118d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola    // Adding the prefix can cause problems when one file has a "foo" and
119d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola    // another has a "\01foo". That is known to happen on ELF with the
120d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola    // tricks normally used for producing aliases (PR9177). Fortunately the
121d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola    // llvm mangler on ELF is a nop, so we can just avoid adding the \01
122d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola    // marker.  We also avoid adding the marker if this is an alias for an
123d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola    // LLVM intrinsic.
124d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola    StringRef UserLabelPrefix =
125d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola        getASTContext().getTargetInfo().getUserLabelPrefix();
126d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola    if (!UserLabelPrefix.empty() && !ALA->getLabel().startswith("llvm."))
127d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola      Out << '\01'; // LLVM IR Marker for __asm("foo")
128d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola
129d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola    Out << ALA->getLabel();
130d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola    return;
131d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  }
132d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola
133d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  const ASTContext &ASTContext = getASTContext();
134d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  StdOrFastCC CC = getStdOrFastCallMangling(ASTContext, D);
135d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  bool MCXX = shouldMangleCXXName(D);
136d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  const TargetInfo &TI = Context.getTargetInfo();
137d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  if (CC == SOF_OTHER || (MCXX && TI.getCXXABI() == TargetCXXABI::Microsoft)) {
138d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola    mangleCXXName(D, Out);
139d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola    return;
140d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  }
141d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola
142d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  Out << '\01';
143d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  if (CC == SOF_STD)
144d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola    Out << '_';
145d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  else
146d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola    Out << '@';
147d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola
148d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  if (!MCXX)
149d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola    Out << D->getIdentifier()->getName();
150d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  else
151d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola    mangleCXXName(D, Out);
152d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola
153d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  const FunctionDecl *FD = cast<FunctionDecl>(D);
154d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  const FunctionType *FT = FD->getType()->castAs<FunctionType>();
155d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FT);
156d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  Out << '@';
157d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  if (!Proto) {
158d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola    Out << '0';
159d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola    return;
160d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  }
161d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  assert(!Proto->isVariadic());
162d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  unsigned ArgWords = 0;
163d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD))
164d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola    if (!MD->isStatic())
165d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola      ++ArgWords;
166651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  for (const auto &AT : Proto->param_types())
167d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola    // Size should be aligned to DWORD boundary
168d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola    ArgWords += llvm::RoundUpToAlignment(ASTContext.getTypeSize(AT), 32) / 32;
169d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  Out << 4 * ArgWords;
170d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola}
171d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola
17214110477887e3dc168ffc6c191e72d705051f99ePeter Collingbournevoid MangleContext::mangleGlobalBlock(const BlockDecl *BD,
1734904bf4e84cfb48080270ebaa9005327f18ab0e5Fariborz Jahanian                                      const NamedDecl *ID,
1745f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                                      raw_ostream &Out) {
1754904bf4e84cfb48080270ebaa9005327f18ab0e5Fariborz Jahanian  unsigned discriminator = getBlockId(BD, false);
1764904bf4e84cfb48080270ebaa9005327f18ab0e5Fariborz Jahanian  if (ID) {
1774904bf4e84cfb48080270ebaa9005327f18ab0e5Fariborz Jahanian    if (shouldMangleDeclName(ID))
1784904bf4e84cfb48080270ebaa9005327f18ab0e5Fariborz Jahanian      mangleName(ID, Out);
1794904bf4e84cfb48080270ebaa9005327f18ab0e5Fariborz Jahanian    else {
1804904bf4e84cfb48080270ebaa9005327f18ab0e5Fariborz Jahanian      Out << ID->getIdentifier()->getName();
1814904bf4e84cfb48080270ebaa9005327f18ab0e5Fariborz Jahanian    }
1824904bf4e84cfb48080270ebaa9005327f18ab0e5Fariborz Jahanian  }
1834904bf4e84cfb48080270ebaa9005327f18ab0e5Fariborz Jahanian  if (discriminator == 0)
1844904bf4e84cfb48080270ebaa9005327f18ab0e5Fariborz Jahanian    Out << "_block_invoke";
1854904bf4e84cfb48080270ebaa9005327f18ab0e5Fariborz Jahanian  else
1864904bf4e84cfb48080270ebaa9005327f18ab0e5Fariborz Jahanian    Out << "_block_invoke_" << discriminator+1;
18714110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne}
18814110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne
18914110477887e3dc168ffc6c191e72d705051f99ePeter Collingbournevoid MangleContext::mangleCtorBlock(const CXXConstructorDecl *CD,
19014110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne                                    CXXCtorType CT, const BlockDecl *BD,
1915f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                                    raw_ostream &ResStream) {
192f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith  SmallString<64> Buffer;
193c4850c2aa4c281a352e228aafc51fb1e30dcad02Rafael Espindola  llvm::raw_svector_ostream Out(Buffer);
194c4850c2aa4c281a352e228aafc51fb1e30dcad02Rafael Espindola  mangleCXXCtor(CD, CT, Out);
195c4850c2aa4c281a352e228aafc51fb1e30dcad02Rafael Espindola  Out.flush();
196c4850c2aa4c281a352e228aafc51fb1e30dcad02Rafael Espindola  mangleFunctionBlock(*this, Buffer, BD, ResStream);
19714110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne}
19814110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne
19914110477887e3dc168ffc6c191e72d705051f99ePeter Collingbournevoid MangleContext::mangleDtorBlock(const CXXDestructorDecl *DD,
20014110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne                                    CXXDtorType DT, const BlockDecl *BD,
2015f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                                    raw_ostream &ResStream) {
202f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith  SmallString<64> Buffer;
203c4850c2aa4c281a352e228aafc51fb1e30dcad02Rafael Espindola  llvm::raw_svector_ostream Out(Buffer);
204c4850c2aa4c281a352e228aafc51fb1e30dcad02Rafael Espindola  mangleCXXDtor(DD, DT, Out);
205c4850c2aa4c281a352e228aafc51fb1e30dcad02Rafael Espindola  Out.flush();
206c4850c2aa4c281a352e228aafc51fb1e30dcad02Rafael Espindola  mangleFunctionBlock(*this, Buffer, BD, ResStream);
20714110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne}
20814110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne
20914110477887e3dc168ffc6c191e72d705051f99ePeter Collingbournevoid MangleContext::mangleBlock(const DeclContext *DC, const BlockDecl *BD,
2105f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                                raw_ostream &Out) {
21114110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne  assert(!isa<CXXConstructorDecl>(DC) && !isa<CXXDestructorDecl>(DC));
21214110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne
213f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith  SmallString<64> Buffer;
214f0be979bddb8baa28e77693a3dc931e487b2a9f2Rafael Espindola  llvm::raw_svector_ostream Stream(Buffer);
21514110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne  if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(DC)) {
216f0be979bddb8baa28e77693a3dc931e487b2a9f2Rafael Espindola    mangleObjCMethodName(Method, Stream);
21714110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne  } else {
21814110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne    const NamedDecl *ND = cast<NamedDecl>(DC);
2194904bf4e84cfb48080270ebaa9005327f18ab0e5Fariborz Jahanian    if (!shouldMangleDeclName(ND) && ND->getIdentifier())
2204904bf4e84cfb48080270ebaa9005327f18ab0e5Fariborz Jahanian      Stream << ND->getIdentifier()->getName();
22114110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne    else {
22214110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne      // FIXME: We were doing a mangleUnqualifiedName() before, but that's
22314110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne      // a private member of a class that will soon itself be private to the
22414110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne      // Itanium C++ ABI object. What should we do now? Right now, I'm just
22514110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne      // calling the mangleName() method on the MangleContext; is there a
22614110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne      // better way?
227f0be979bddb8baa28e77693a3dc931e487b2a9f2Rafael Espindola      mangleName(ND, Stream);
22814110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne    }
22914110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne  }
230f0be979bddb8baa28e77693a3dc931e487b2a9f2Rafael Espindola  Stream.flush();
231c4850c2aa4c281a352e228aafc51fb1e30dcad02Rafael Espindola  mangleFunctionBlock(*this, Buffer, BD, Out);
23214110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne}
23314110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne
23414110477887e3dc168ffc6c191e72d705051f99ePeter Collingbournevoid MangleContext::mangleObjCMethodName(const ObjCMethodDecl *MD,
2355f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                                         raw_ostream &Out) {
236f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith  SmallString<64> Name;
237f0be979bddb8baa28e77693a3dc931e487b2a9f2Rafael Espindola  llvm::raw_svector_ostream OS(Name);
23814110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne
23914110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne  const ObjCContainerDecl *CD =
24014110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne  dyn_cast<ObjCContainerDecl>(MD->getDeclContext());
24114110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne  assert (CD && "Missing container decl in GetNameForMethod");
24214110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne  OS << (MD->isInstanceMethod() ? '-' : '+') << '[' << CD->getName();
24314110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne  if (const ObjCCategoryImplDecl *CID = dyn_cast<ObjCCategoryImplDecl>(CD))
244f978059b82db8c0d849c5f992036210b5ca53200Benjamin Kramer    OS << '(' << *CID << ')';
245651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  OS << ' ';
246651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  MD->getSelector().print(OS);
247651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  OS << ']';
24814110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne
24914110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne  Out << OS.str().size() << OS.str();
25014110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne}
251