Mangle.cpp revision f978059b82db8c0d849c5f992036210b5ca53200
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 6299ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikievoid MangleContext::anchor() { } 6399ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikie 6414110477887e3dc168ffc6c191e72d705051f99ePeter Collingbournevoid MangleContext::mangleGlobalBlock(const BlockDecl *BD, 655f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner raw_ostream &Out) { 6614110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne Out << "__block_global_" << getBlockId(BD, false); 6714110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne} 6814110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne 6914110477887e3dc168ffc6c191e72d705051f99ePeter Collingbournevoid MangleContext::mangleCtorBlock(const CXXConstructorDecl *CD, 7014110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne CXXCtorType CT, const BlockDecl *BD, 715f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner raw_ostream &ResStream) { 7214110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne checkMangleDC(CD, BD); 73f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<64> Buffer; 74c4850c2aa4c281a352e228aafc51fb1e30dcad02Rafael Espindola llvm::raw_svector_ostream Out(Buffer); 75c4850c2aa4c281a352e228aafc51fb1e30dcad02Rafael Espindola mangleCXXCtor(CD, CT, Out); 76c4850c2aa4c281a352e228aafc51fb1e30dcad02Rafael Espindola Out.flush(); 77c4850c2aa4c281a352e228aafc51fb1e30dcad02Rafael Espindola mangleFunctionBlock(*this, Buffer, BD, ResStream); 7814110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne} 7914110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne 8014110477887e3dc168ffc6c191e72d705051f99ePeter Collingbournevoid MangleContext::mangleDtorBlock(const CXXDestructorDecl *DD, 8114110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne CXXDtorType DT, const BlockDecl *BD, 825f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner raw_ostream &ResStream) { 8314110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne checkMangleDC(DD, BD); 84f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<64> Buffer; 85c4850c2aa4c281a352e228aafc51fb1e30dcad02Rafael Espindola llvm::raw_svector_ostream Out(Buffer); 86c4850c2aa4c281a352e228aafc51fb1e30dcad02Rafael Espindola mangleCXXDtor(DD, DT, Out); 87c4850c2aa4c281a352e228aafc51fb1e30dcad02Rafael Espindola Out.flush(); 88c4850c2aa4c281a352e228aafc51fb1e30dcad02Rafael Espindola mangleFunctionBlock(*this, Buffer, BD, ResStream); 8914110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne} 9014110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne 9114110477887e3dc168ffc6c191e72d705051f99ePeter Collingbournevoid MangleContext::mangleBlock(const DeclContext *DC, const BlockDecl *BD, 925f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner raw_ostream &Out) { 9314110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne assert(!isa<CXXConstructorDecl>(DC) && !isa<CXXDestructorDecl>(DC)); 9414110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne checkMangleDC(DC, BD); 9514110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne 96f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<64> Buffer; 97f0be979bddb8baa28e77693a3dc931e487b2a9f2Rafael Espindola llvm::raw_svector_ostream Stream(Buffer); 9814110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(DC)) { 99f0be979bddb8baa28e77693a3dc931e487b2a9f2Rafael Espindola mangleObjCMethodName(Method, Stream); 10014110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne } else { 10114110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne const NamedDecl *ND = cast<NamedDecl>(DC); 10214110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne if (IdentifierInfo *II = ND->getIdentifier()) 103f0be979bddb8baa28e77693a3dc931e487b2a9f2Rafael Espindola Stream << II->getName(); 10414110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne else { 10514110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne // FIXME: We were doing a mangleUnqualifiedName() before, but that's 10614110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne // a private member of a class that will soon itself be private to the 10714110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne // Itanium C++ ABI object. What should we do now? Right now, I'm just 10814110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne // calling the mangleName() method on the MangleContext; is there a 10914110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne // better way? 110f0be979bddb8baa28e77693a3dc931e487b2a9f2Rafael Espindola mangleName(ND, Stream); 11114110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne } 11214110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne } 113f0be979bddb8baa28e77693a3dc931e487b2a9f2Rafael Espindola Stream.flush(); 114c4850c2aa4c281a352e228aafc51fb1e30dcad02Rafael Espindola mangleFunctionBlock(*this, Buffer, BD, Out); 11514110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne} 11614110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne 11714110477887e3dc168ffc6c191e72d705051f99ePeter Collingbournevoid MangleContext::mangleObjCMethodName(const ObjCMethodDecl *MD, 1185f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner raw_ostream &Out) { 119f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<64> Name; 120f0be979bddb8baa28e77693a3dc931e487b2a9f2Rafael Espindola llvm::raw_svector_ostream OS(Name); 12114110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne 12214110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne const ObjCContainerDecl *CD = 12314110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne dyn_cast<ObjCContainerDecl>(MD->getDeclContext()); 12414110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne assert (CD && "Missing container decl in GetNameForMethod"); 12514110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne OS << (MD->isInstanceMethod() ? '-' : '+') << '[' << CD->getName(); 12614110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne if (const ObjCCategoryImplDecl *CID = dyn_cast<ObjCCategoryImplDecl>(CD)) 127f978059b82db8c0d849c5f992036210b5ca53200Benjamin Kramer OS << '(' << *CID << ')'; 12814110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne OS << ' ' << MD->getSelector().getAsString() << ']'; 12914110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne 13014110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne Out << OS.str().size() << OS.str(); 13114110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne} 13214110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne 13314110477887e3dc168ffc6c191e72d705051f99ePeter Collingbournevoid MangleContext::mangleBlock(const BlockDecl *BD, 1345f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner raw_ostream &Out) { 13514110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne const DeclContext *DC = BD->getDeclContext(); 13614110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne while (isa<BlockDecl>(DC) || isa<EnumDecl>(DC)) 13714110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne DC = DC->getParent(); 13814110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne if (DC->isFunctionOrMethod()) 139c4850c2aa4c281a352e228aafc51fb1e30dcad02Rafael Espindola mangleBlock(DC, BD, Out); 14014110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne else 141c4850c2aa4c281a352e228aafc51fb1e30dcad02Rafael Espindola mangleGlobalBlock(BD, Out); 14214110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne} 143