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