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