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
52176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesenum CCMangling {
53176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  CCM_Other,
54176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  CCM_Fast,
55176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  CCM_Vector,
56176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  CCM_Std
57d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola};
58d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola
59d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindolastatic bool isExternC(const NamedDecl *ND) {
60d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND))
61d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola    return FD->isExternC();
62d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  return cast<VarDecl>(ND)->isExternC();
63d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola}
64d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola
65176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesstatic CCMangling getCallingConvMangling(const ASTContext &Context,
66176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                                         const NamedDecl *ND) {
67d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  const TargetInfo &TI = Context.getTargetInfo();
68651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  const llvm::Triple &Triple = TI.getTriple();
69176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  if (!Triple.isOSWindows() ||
70176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      !(Triple.getArch() == llvm::Triple::x86 ||
71176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines        Triple.getArch() == llvm::Triple::x86_64))
72176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    return CCM_Other;
73d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola
74d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  if (Context.getLangOpts().CPlusPlus && !isExternC(ND) &&
75d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola      TI.getCXXABI() == TargetCXXABI::Microsoft)
76176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    return CCM_Other;
77d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola
78d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND);
79d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  if (!FD)
80176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    return CCM_Other;
81d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  QualType T = FD->getType();
82d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola
83d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  const FunctionType *FT = T->castAs<FunctionType>();
84d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola
85d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  CallingConv CC = FT->getCallConv();
86d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  switch (CC) {
87d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  default:
88176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    return CCM_Other;
89d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  case CC_X86FastCall:
90176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    return CCM_Fast;
91d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  case CC_X86StdCall:
92176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    return CCM_Std;
93176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  case CC_X86VectorCall:
94176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    return CCM_Vector;
95d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  }
96d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola}
97d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola
98d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindolabool MangleContext::shouldMangleDeclName(const NamedDecl *D) {
99d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  const ASTContext &ASTContext = getASTContext();
100d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola
101176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  CCMangling CC = getCallingConvMangling(ASTContext, D);
102176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  if (CC != CCM_Other)
103d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola    return true;
104d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola
105d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  // In C, functions with no attributes never need to be mangled. Fastpath them.
106d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  if (!getASTContext().getLangOpts().CPlusPlus && !D->hasAttrs())
107d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola    return false;
108d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola
109d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  // Any decl can be declared with __asm("foo") on it, and this takes precedence
110d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  // over all other naming in the .o file.
111d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  if (D->hasAttr<AsmLabelAttr>())
112d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola    return true;
113d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola
114d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  return shouldMangleCXXName(D);
115d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola}
116d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola
117d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindolavoid MangleContext::mangleName(const NamedDecl *D, raw_ostream &Out) {
118d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  // Any decl can be declared with __asm("foo") on it, and this takes precedence
119d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  // over all other naming in the .o file.
120d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  if (const AsmLabelAttr *ALA = D->getAttr<AsmLabelAttr>()) {
121d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola    // If we have an asm name, then we use it as the mangling.
122d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola
123d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola    // Adding the prefix can cause problems when one file has a "foo" and
124d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola    // another has a "\01foo". That is known to happen on ELF with the
125d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola    // tricks normally used for producing aliases (PR9177). Fortunately the
126d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola    // llvm mangler on ELF is a nop, so we can just avoid adding the \01
127d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola    // marker.  We also avoid adding the marker if this is an alias for an
128d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola    // LLVM intrinsic.
1294967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    char GlobalPrefix =
1304967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        getASTContext().getTargetInfo().getDataLayout().getGlobalPrefix();
1314967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    if (GlobalPrefix && !ALA->getLabel().startswith("llvm."))
132d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola      Out << '\01'; // LLVM IR Marker for __asm("foo")
133d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola
134d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola    Out << ALA->getLabel();
135d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola    return;
136d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  }
137d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola
138d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  const ASTContext &ASTContext = getASTContext();
139176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  CCMangling CC = getCallingConvMangling(ASTContext, D);
140d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  bool MCXX = shouldMangleCXXName(D);
141d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  const TargetInfo &TI = Context.getTargetInfo();
142176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  if (CC == CCM_Other || (MCXX && TI.getCXXABI() == TargetCXXABI::Microsoft)) {
143176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D))
144176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      mangleObjCMethodName(OMD, Out);
145176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    else
146176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      mangleCXXName(D, Out);
147d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola    return;
148d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  }
149d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola
150d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  Out << '\01';
151176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  if (CC == CCM_Std)
152d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola    Out << '_';
153176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  else if (CC == CCM_Fast)
154d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola    Out << '@';
155d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola
156d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  if (!MCXX)
157d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola    Out << D->getIdentifier()->getName();
158176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  else if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D))
159176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    mangleObjCMethodName(OMD, Out);
160d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  else
161d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola    mangleCXXName(D, Out);
162d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola
163d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  const FunctionDecl *FD = cast<FunctionDecl>(D);
164d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  const FunctionType *FT = FD->getType()->castAs<FunctionType>();
165d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FT);
166176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  if (CC == CCM_Vector)
167176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    Out << '@';
168d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  Out << '@';
169d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  if (!Proto) {
170d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola    Out << '0';
171d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola    return;
172d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  }
173d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  assert(!Proto->isVariadic());
174d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  unsigned ArgWords = 0;
175d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola  if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD))
176d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola    if (!MD->isStatic())
177d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola      ++ArgWords;
178651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  for (const auto &AT : Proto->param_types())
179176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    // Size should be aligned to pointer size.
1804967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    ArgWords +=
1814967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        llvm::alignTo(ASTContext.getTypeSize(AT), TI.getPointerWidth(0)) /
1824967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        TI.getPointerWidth(0);
183176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  Out << ((TI.getPointerWidth(0) / 8) * ArgWords);
184d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola}
185d6be277ba4bf271c6de8ffcc8c46f060c8cbd4d5Rafael Espindola
18614110477887e3dc168ffc6c191e72d705051f99ePeter Collingbournevoid MangleContext::mangleGlobalBlock(const BlockDecl *BD,
1874904bf4e84cfb48080270ebaa9005327f18ab0e5Fariborz Jahanian                                      const NamedDecl *ID,
1885f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                                      raw_ostream &Out) {
1894904bf4e84cfb48080270ebaa9005327f18ab0e5Fariborz Jahanian  unsigned discriminator = getBlockId(BD, false);
1904904bf4e84cfb48080270ebaa9005327f18ab0e5Fariborz Jahanian  if (ID) {
1914904bf4e84cfb48080270ebaa9005327f18ab0e5Fariborz Jahanian    if (shouldMangleDeclName(ID))
1924904bf4e84cfb48080270ebaa9005327f18ab0e5Fariborz Jahanian      mangleName(ID, Out);
1934904bf4e84cfb48080270ebaa9005327f18ab0e5Fariborz Jahanian    else {
1944904bf4e84cfb48080270ebaa9005327f18ab0e5Fariborz Jahanian      Out << ID->getIdentifier()->getName();
1954904bf4e84cfb48080270ebaa9005327f18ab0e5Fariborz Jahanian    }
1964904bf4e84cfb48080270ebaa9005327f18ab0e5Fariborz Jahanian  }
1974904bf4e84cfb48080270ebaa9005327f18ab0e5Fariborz Jahanian  if (discriminator == 0)
1984904bf4e84cfb48080270ebaa9005327f18ab0e5Fariborz Jahanian    Out << "_block_invoke";
1994904bf4e84cfb48080270ebaa9005327f18ab0e5Fariborz Jahanian  else
2004904bf4e84cfb48080270ebaa9005327f18ab0e5Fariborz Jahanian    Out << "_block_invoke_" << discriminator+1;
20114110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne}
20214110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne
20314110477887e3dc168ffc6c191e72d705051f99ePeter Collingbournevoid MangleContext::mangleCtorBlock(const CXXConstructorDecl *CD,
20414110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne                                    CXXCtorType CT, const BlockDecl *BD,
2055f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                                    raw_ostream &ResStream) {
206f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith  SmallString<64> Buffer;
207c4850c2aa4c281a352e228aafc51fb1e30dcad02Rafael Espindola  llvm::raw_svector_ostream Out(Buffer);
208c4850c2aa4c281a352e228aafc51fb1e30dcad02Rafael Espindola  mangleCXXCtor(CD, CT, Out);
209c4850c2aa4c281a352e228aafc51fb1e30dcad02Rafael Espindola  mangleFunctionBlock(*this, Buffer, BD, ResStream);
21014110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne}
21114110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne
21214110477887e3dc168ffc6c191e72d705051f99ePeter Collingbournevoid MangleContext::mangleDtorBlock(const CXXDestructorDecl *DD,
21314110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne                                    CXXDtorType DT, const BlockDecl *BD,
2145f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                                    raw_ostream &ResStream) {
215f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith  SmallString<64> Buffer;
216c4850c2aa4c281a352e228aafc51fb1e30dcad02Rafael Espindola  llvm::raw_svector_ostream Out(Buffer);
217c4850c2aa4c281a352e228aafc51fb1e30dcad02Rafael Espindola  mangleCXXDtor(DD, DT, Out);
218c4850c2aa4c281a352e228aafc51fb1e30dcad02Rafael Espindola  mangleFunctionBlock(*this, Buffer, BD, ResStream);
21914110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne}
22014110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne
22114110477887e3dc168ffc6c191e72d705051f99ePeter Collingbournevoid MangleContext::mangleBlock(const DeclContext *DC, const BlockDecl *BD,
2225f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                                raw_ostream &Out) {
22314110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne  assert(!isa<CXXConstructorDecl>(DC) && !isa<CXXDestructorDecl>(DC));
22414110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne
225f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith  SmallString<64> Buffer;
226f0be979bddb8baa28e77693a3dc931e487b2a9f2Rafael Espindola  llvm::raw_svector_ostream Stream(Buffer);
22714110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne  if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(DC)) {
228f0be979bddb8baa28e77693a3dc931e487b2a9f2Rafael Espindola    mangleObjCMethodName(Method, Stream);
22914110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne  } else {
230176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    assert((isa<NamedDecl>(DC) || isa<BlockDecl>(DC)) &&
231176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines           "expected a NamedDecl or BlockDecl");
232176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    if (isa<BlockDecl>(DC))
233176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      for (; DC && isa<BlockDecl>(DC); DC = DC->getParent())
234176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines        (void) getBlockId(cast<BlockDecl>(DC), true);
235176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    assert((isa<TranslationUnitDecl>(DC) || isa<NamedDecl>(DC)) &&
236176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines           "expected a TranslationUnitDecl or a NamedDecl");
2370e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    if (const auto *CD = dyn_cast<CXXConstructorDecl>(DC))
2380e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      mangleCtorBlock(CD, /*CT*/ Ctor_Complete, BD, Out);
2390e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    else if (const auto *DD = dyn_cast<CXXDestructorDecl>(DC))
2400e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      mangleDtorBlock(DD, /*DT*/ Dtor_Complete, BD, Out);
2410e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    else if (auto ND = dyn_cast<NamedDecl>(DC)) {
242176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      if (!shouldMangleDeclName(ND) && ND->getIdentifier())
243176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines        Stream << ND->getIdentifier()->getName();
244176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      else {
245176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines        // FIXME: We were doing a mangleUnqualifiedName() before, but that's
246176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines        // a private member of a class that will soon itself be private to the
247176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines        // Itanium C++ ABI object. What should we do now? Right now, I'm just
248176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines        // calling the mangleName() method on the MangleContext; is there a
249176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines        // better way?
250176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines        mangleName(ND, Stream);
251176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      }
25214110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne    }
25314110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne  }
254c4850c2aa4c281a352e228aafc51fb1e30dcad02Rafael Espindola  mangleFunctionBlock(*this, Buffer, BD, Out);
25514110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne}
25614110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne
2574967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarvoid MangleContext::mangleObjCMethodNameWithoutSize(const ObjCMethodDecl *MD,
2584967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                                    raw_ostream &OS) {
25914110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne  const ObjCContainerDecl *CD =
26014110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne  dyn_cast<ObjCContainerDecl>(MD->getDeclContext());
26114110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne  assert (CD && "Missing container decl in GetNameForMethod");
26214110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne  OS << (MD->isInstanceMethod() ? '-' : '+') << '[' << CD->getName();
26314110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne  if (const ObjCCategoryImplDecl *CID = dyn_cast<ObjCCategoryImplDecl>(CD))
264f978059b82db8c0d849c5f992036210b5ca53200Benjamin Kramer    OS << '(' << *CID << ')';
265651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  OS << ' ';
266651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  MD->getSelector().print(OS);
267651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  OS << ']';
2684967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar}
2694967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
2704967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarvoid MangleContext::mangleObjCMethodName(const ObjCMethodDecl *MD,
2714967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                         raw_ostream &Out) {
2724967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  SmallString<64> Name;
2734967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  llvm::raw_svector_ostream OS(Name);
2744967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
2754967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  mangleObjCMethodNameWithoutSize(MD, OS);
27614110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne  Out << OS.str().size() << OS.str();
27714110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne}
278