Mangle.cpp revision 55fc873017f10f6f566b182b70f6fc22aefa3464
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//===----------------------------------------------------------------------===// 1314110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne#include "clang/AST/Mangle.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" 2014110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne#include "clang/Basic/ABI.h" 2114110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne#include "clang/Basic/SourceManager.h" 2214110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne#include "llvm/ADT/StringExtras.h" 2314110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne#include "llvm/Support/ErrorHandling.h" 2455fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "llvm/Support/raw_ostream.h" 2514110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne 2614110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne#define MANGLE_CHECKER 0 2714110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne 2814110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne#if MANGLE_CHECKER 2914110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne#include <cxxabi.h> 3014110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne#endif 3114110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne 3214110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourneusing namespace clang; 3314110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne 3414110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne// FIXME: For blocks we currently mimic GCC's mangling scheme, which leaves 3514110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne// much to be desired. Come up with a better mangling scheme. 3614110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne 3714110477887e3dc168ffc6c191e72d705051f99ePeter Collingbournenamespace { 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 5014110477887e3dc168ffc6c191e72d705051f99ePeter Collingbournestatic void checkMangleDC(const DeclContext *DC, const BlockDecl *BD) { 5114110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne#ifndef NDEBUG 5214110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne const DeclContext *ExpectedDC = BD->getDeclContext(); 5314110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne while (isa<BlockDecl>(ExpectedDC) || isa<EnumDecl>(ExpectedDC)) 5414110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne ExpectedDC = ExpectedDC->getParent(); 557a614d8380297fcd2bc23986241905d97222948cRichard Smith // In-class initializers for non-static data members are lexically defined 567a614d8380297fcd2bc23986241905d97222948cRichard Smith // within the class, but are mangled as if they were specified as constructor 577a614d8380297fcd2bc23986241905d97222948cRichard Smith // member initializers. 587a614d8380297fcd2bc23986241905d97222948cRichard Smith if (isa<CXXRecordDecl>(ExpectedDC) && DC != ExpectedDC) 597a614d8380297fcd2bc23986241905d97222948cRichard Smith DC = DC->getParent(); 6014110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne assert(DC == ExpectedDC && "Given decl context did not match expected!"); 6114110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne#endif 6214110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne} 6314110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne 6414110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne} 6514110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne 6699ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikievoid MangleContext::anchor() { } 6799ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikie 6814110477887e3dc168ffc6c191e72d705051f99ePeter Collingbournevoid MangleContext::mangleGlobalBlock(const BlockDecl *BD, 694904bf4e84cfb48080270ebaa9005327f18ab0e5Fariborz Jahanian const NamedDecl *ID, 705f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner raw_ostream &Out) { 714904bf4e84cfb48080270ebaa9005327f18ab0e5Fariborz Jahanian unsigned discriminator = getBlockId(BD, false); 724904bf4e84cfb48080270ebaa9005327f18ab0e5Fariborz Jahanian if (ID) { 734904bf4e84cfb48080270ebaa9005327f18ab0e5Fariborz Jahanian if (shouldMangleDeclName(ID)) 744904bf4e84cfb48080270ebaa9005327f18ab0e5Fariborz Jahanian mangleName(ID, Out); 754904bf4e84cfb48080270ebaa9005327f18ab0e5Fariborz Jahanian else { 764904bf4e84cfb48080270ebaa9005327f18ab0e5Fariborz Jahanian Out << ID->getIdentifier()->getName(); 774904bf4e84cfb48080270ebaa9005327f18ab0e5Fariborz Jahanian } 784904bf4e84cfb48080270ebaa9005327f18ab0e5Fariborz Jahanian } 794904bf4e84cfb48080270ebaa9005327f18ab0e5Fariborz Jahanian if (discriminator == 0) 804904bf4e84cfb48080270ebaa9005327f18ab0e5Fariborz Jahanian Out << "_block_invoke"; 814904bf4e84cfb48080270ebaa9005327f18ab0e5Fariborz Jahanian else 824904bf4e84cfb48080270ebaa9005327f18ab0e5Fariborz Jahanian Out << "_block_invoke_" << discriminator+1; 8314110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne} 8414110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne 8514110477887e3dc168ffc6c191e72d705051f99ePeter Collingbournevoid MangleContext::mangleCtorBlock(const CXXConstructorDecl *CD, 8614110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne CXXCtorType CT, const BlockDecl *BD, 875f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner raw_ostream &ResStream) { 8814110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne checkMangleDC(CD, BD); 89f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<64> Buffer; 90c4850c2aa4c281a352e228aafc51fb1e30dcad02Rafael Espindola llvm::raw_svector_ostream Out(Buffer); 91c4850c2aa4c281a352e228aafc51fb1e30dcad02Rafael Espindola mangleCXXCtor(CD, CT, Out); 92c4850c2aa4c281a352e228aafc51fb1e30dcad02Rafael Espindola Out.flush(); 93c4850c2aa4c281a352e228aafc51fb1e30dcad02Rafael Espindola mangleFunctionBlock(*this, Buffer, BD, ResStream); 9414110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne} 9514110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne 9614110477887e3dc168ffc6c191e72d705051f99ePeter Collingbournevoid MangleContext::mangleDtorBlock(const CXXDestructorDecl *DD, 9714110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne CXXDtorType DT, const BlockDecl *BD, 985f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner raw_ostream &ResStream) { 9914110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne checkMangleDC(DD, BD); 100f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<64> Buffer; 101c4850c2aa4c281a352e228aafc51fb1e30dcad02Rafael Espindola llvm::raw_svector_ostream Out(Buffer); 102c4850c2aa4c281a352e228aafc51fb1e30dcad02Rafael Espindola mangleCXXDtor(DD, DT, Out); 103c4850c2aa4c281a352e228aafc51fb1e30dcad02Rafael Espindola Out.flush(); 104c4850c2aa4c281a352e228aafc51fb1e30dcad02Rafael Espindola mangleFunctionBlock(*this, Buffer, BD, ResStream); 10514110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne} 10614110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne 10714110477887e3dc168ffc6c191e72d705051f99ePeter Collingbournevoid MangleContext::mangleBlock(const DeclContext *DC, const BlockDecl *BD, 1085f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner raw_ostream &Out) { 10914110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne assert(!isa<CXXConstructorDecl>(DC) && !isa<CXXDestructorDecl>(DC)); 11014110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne checkMangleDC(DC, BD); 11114110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne 112f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<64> Buffer; 113f0be979bddb8baa28e77693a3dc931e487b2a9f2Rafael Espindola llvm::raw_svector_ostream Stream(Buffer); 11414110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(DC)) { 115f0be979bddb8baa28e77693a3dc931e487b2a9f2Rafael Espindola mangleObjCMethodName(Method, Stream); 11614110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne } else { 11714110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne const NamedDecl *ND = cast<NamedDecl>(DC); 1184904bf4e84cfb48080270ebaa9005327f18ab0e5Fariborz Jahanian if (!shouldMangleDeclName(ND) && ND->getIdentifier()) 1194904bf4e84cfb48080270ebaa9005327f18ab0e5Fariborz Jahanian Stream << ND->getIdentifier()->getName(); 12014110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne else { 12114110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne // FIXME: We were doing a mangleUnqualifiedName() before, but that's 12214110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne // a private member of a class that will soon itself be private to the 12314110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne // Itanium C++ ABI object. What should we do now? Right now, I'm just 12414110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne // calling the mangleName() method on the MangleContext; is there a 12514110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne // better way? 126f0be979bddb8baa28e77693a3dc931e487b2a9f2Rafael Espindola mangleName(ND, Stream); 12714110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne } 12814110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne } 129f0be979bddb8baa28e77693a3dc931e487b2a9f2Rafael Espindola Stream.flush(); 130c4850c2aa4c281a352e228aafc51fb1e30dcad02Rafael Espindola mangleFunctionBlock(*this, Buffer, BD, Out); 13114110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne} 13214110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne 13314110477887e3dc168ffc6c191e72d705051f99ePeter Collingbournevoid MangleContext::mangleObjCMethodName(const ObjCMethodDecl *MD, 1345f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner raw_ostream &Out) { 135f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<64> Name; 136f0be979bddb8baa28e77693a3dc931e487b2a9f2Rafael Espindola llvm::raw_svector_ostream OS(Name); 13714110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne 13814110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne const ObjCContainerDecl *CD = 13914110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne dyn_cast<ObjCContainerDecl>(MD->getDeclContext()); 14014110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne assert (CD && "Missing container decl in GetNameForMethod"); 14114110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne OS << (MD->isInstanceMethod() ? '-' : '+') << '[' << CD->getName(); 14214110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne if (const ObjCCategoryImplDecl *CID = dyn_cast<ObjCCategoryImplDecl>(CD)) 143f978059b82db8c0d849c5f992036210b5ca53200Benjamin Kramer OS << '(' << *CID << ')'; 14414110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne OS << ' ' << MD->getSelector().getAsString() << ']'; 14514110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne 14614110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne Out << OS.str().size() << OS.str(); 14714110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne} 14814110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne 14914110477887e3dc168ffc6c191e72d705051f99ePeter Collingbournevoid MangleContext::mangleBlock(const BlockDecl *BD, 1504904bf4e84cfb48080270ebaa9005327f18ab0e5Fariborz Jahanian raw_ostream &Out, 1514904bf4e84cfb48080270ebaa9005327f18ab0e5Fariborz Jahanian const NamedDecl *ID) { 15214110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne const DeclContext *DC = BD->getDeclContext(); 15314110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne while (isa<BlockDecl>(DC) || isa<EnumDecl>(DC)) 15414110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne DC = DC->getParent(); 15514110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne if (DC->isFunctionOrMethod()) 156c4850c2aa4c281a352e228aafc51fb1e30dcad02Rafael Espindola mangleBlock(DC, BD, Out); 15714110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne else 1584904bf4e84cfb48080270ebaa9005327f18ab0e5Fariborz Jahanian mangleGlobalBlock(BD, ID, Out); 15914110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne} 160