Mangle.cpp revision 5f9e272e632e951b1efe824cd16acb4d96077930
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/raw_ostream.h" 2414110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne#include "llvm/Support/ErrorHandling.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) { 4314110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne Out << "__" << Outer << "_block_invoke_" << Context.getBlockId(BD, true); 4414110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne} 4514110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne 4614110477887e3dc168ffc6c191e72d705051f99ePeter Collingbournestatic void checkMangleDC(const DeclContext *DC, const BlockDecl *BD) { 4714110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne#ifndef NDEBUG 4814110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne const DeclContext *ExpectedDC = BD->getDeclContext(); 4914110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne while (isa<BlockDecl>(ExpectedDC) || isa<EnumDecl>(ExpectedDC)) 5014110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne ExpectedDC = ExpectedDC->getParent(); 517a614d8380297fcd2bc23986241905d97222948cRichard Smith // In-class initializers for non-static data members are lexically defined 527a614d8380297fcd2bc23986241905d97222948cRichard Smith // within the class, but are mangled as if they were specified as constructor 537a614d8380297fcd2bc23986241905d97222948cRichard Smith // member initializers. 547a614d8380297fcd2bc23986241905d97222948cRichard Smith if (isa<CXXRecordDecl>(ExpectedDC) && DC != ExpectedDC) 557a614d8380297fcd2bc23986241905d97222948cRichard Smith DC = DC->getParent(); 5614110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne assert(DC == ExpectedDC && "Given decl context did not match expected!"); 5714110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne#endif 5814110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne} 5914110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne 6014110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne} 6114110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne 6214110477887e3dc168ffc6c191e72d705051f99ePeter Collingbournevoid MangleContext::mangleGlobalBlock(const BlockDecl *BD, 635f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner raw_ostream &Out) { 6414110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne Out << "__block_global_" << getBlockId(BD, false); 6514110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne} 6614110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne 6714110477887e3dc168ffc6c191e72d705051f99ePeter Collingbournevoid MangleContext::mangleCtorBlock(const CXXConstructorDecl *CD, 6814110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne CXXCtorType CT, const BlockDecl *BD, 695f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner raw_ostream &ResStream) { 7014110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne checkMangleDC(CD, BD); 7114110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne llvm::SmallString<64> Buffer; 72c4850c2aa4c281a352e228aafc51fb1e30dcad02Rafael Espindola llvm::raw_svector_ostream Out(Buffer); 73c4850c2aa4c281a352e228aafc51fb1e30dcad02Rafael Espindola mangleCXXCtor(CD, CT, Out); 74c4850c2aa4c281a352e228aafc51fb1e30dcad02Rafael Espindola Out.flush(); 75c4850c2aa4c281a352e228aafc51fb1e30dcad02Rafael Espindola mangleFunctionBlock(*this, Buffer, BD, ResStream); 7614110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne} 7714110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne 7814110477887e3dc168ffc6c191e72d705051f99ePeter Collingbournevoid MangleContext::mangleDtorBlock(const CXXDestructorDecl *DD, 7914110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne CXXDtorType DT, const BlockDecl *BD, 805f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner raw_ostream &ResStream) { 8114110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne checkMangleDC(DD, BD); 8214110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne llvm::SmallString<64> Buffer; 83c4850c2aa4c281a352e228aafc51fb1e30dcad02Rafael Espindola llvm::raw_svector_ostream Out(Buffer); 84c4850c2aa4c281a352e228aafc51fb1e30dcad02Rafael Espindola mangleCXXDtor(DD, DT, Out); 85c4850c2aa4c281a352e228aafc51fb1e30dcad02Rafael Espindola Out.flush(); 86c4850c2aa4c281a352e228aafc51fb1e30dcad02Rafael Espindola mangleFunctionBlock(*this, Buffer, BD, ResStream); 8714110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne} 8814110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne 8914110477887e3dc168ffc6c191e72d705051f99ePeter Collingbournevoid MangleContext::mangleBlock(const DeclContext *DC, const BlockDecl *BD, 905f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner raw_ostream &Out) { 9114110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne assert(!isa<CXXConstructorDecl>(DC) && !isa<CXXDestructorDecl>(DC)); 9214110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne checkMangleDC(DC, BD); 9314110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne 9414110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne llvm::SmallString<64> Buffer; 95f0be979bddb8baa28e77693a3dc931e487b2a9f2Rafael Espindola llvm::raw_svector_ostream Stream(Buffer); 9614110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(DC)) { 97f0be979bddb8baa28e77693a3dc931e487b2a9f2Rafael Espindola mangleObjCMethodName(Method, Stream); 9814110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne } else { 9914110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne const NamedDecl *ND = cast<NamedDecl>(DC); 10014110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne if (IdentifierInfo *II = ND->getIdentifier()) 101f0be979bddb8baa28e77693a3dc931e487b2a9f2Rafael Espindola Stream << II->getName(); 10214110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne else { 10314110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne // FIXME: We were doing a mangleUnqualifiedName() before, but that's 10414110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne // a private member of a class that will soon itself be private to the 10514110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne // Itanium C++ ABI object. What should we do now? Right now, I'm just 10614110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne // calling the mangleName() method on the MangleContext; is there a 10714110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne // better way? 108f0be979bddb8baa28e77693a3dc931e487b2a9f2Rafael Espindola mangleName(ND, Stream); 10914110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne } 11014110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne } 111f0be979bddb8baa28e77693a3dc931e487b2a9f2Rafael Espindola Stream.flush(); 112c4850c2aa4c281a352e228aafc51fb1e30dcad02Rafael Espindola mangleFunctionBlock(*this, Buffer, BD, Out); 11314110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne} 11414110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne 11514110477887e3dc168ffc6c191e72d705051f99ePeter Collingbournevoid MangleContext::mangleObjCMethodName(const ObjCMethodDecl *MD, 1165f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner raw_ostream &Out) { 11714110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne llvm::SmallString<64> Name; 118f0be979bddb8baa28e77693a3dc931e487b2a9f2Rafael Espindola llvm::raw_svector_ostream OS(Name); 11914110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne 12014110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne const ObjCContainerDecl *CD = 12114110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne dyn_cast<ObjCContainerDecl>(MD->getDeclContext()); 12214110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne assert (CD && "Missing container decl in GetNameForMethod"); 12314110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne OS << (MD->isInstanceMethod() ? '-' : '+') << '[' << CD->getName(); 12414110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne if (const ObjCCategoryImplDecl *CID = dyn_cast<ObjCCategoryImplDecl>(CD)) 12514110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne OS << '(' << CID << ')'; 12614110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne OS << ' ' << MD->getSelector().getAsString() << ']'; 12714110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne 12814110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne Out << OS.str().size() << OS.str(); 12914110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne} 13014110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne 13114110477887e3dc168ffc6c191e72d705051f99ePeter Collingbournevoid MangleContext::mangleBlock(const BlockDecl *BD, 1325f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner raw_ostream &Out) { 13314110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne const DeclContext *DC = BD->getDeclContext(); 13414110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne while (isa<BlockDecl>(DC) || isa<EnumDecl>(DC)) 13514110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne DC = DC->getParent(); 13614110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne if (DC->isFunctionOrMethod()) 137c4850c2aa4c281a352e228aafc51fb1e30dcad02Rafael Espindola mangleBlock(DC, BD, Out); 13814110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne else 139c4850c2aa4c281a352e228aafc51fb1e30dcad02Rafael Espindola mangleGlobalBlock(BD, Out); 14014110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne} 141