Mangle.cpp revision f0be979bddb8baa28e77693a3dc931e487b2a9f2
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,
4014110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne                                llvm::StringRef Outer,
4114110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne                                const BlockDecl *BD,
420e376a0ca8372c9e809d08a9db2fae98394878b8Rafael Espindola                                llvm::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();
5114110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne  assert(DC == ExpectedDC && "Given decl context did not match expected!");
5214110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne#endif
5314110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne}
5414110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne
5514110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne}
5614110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne
5714110477887e3dc168ffc6c191e72d705051f99ePeter Collingbournevoid MangleContext::mangleGlobalBlock(const BlockDecl *BD,
580e376a0ca8372c9e809d08a9db2fae98394878b8Rafael Espindola                                      llvm::raw_ostream &Out) {
5914110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne  Out << "__block_global_" << getBlockId(BD, false);
6014110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne}
6114110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne
6214110477887e3dc168ffc6c191e72d705051f99ePeter Collingbournevoid MangleContext::mangleCtorBlock(const CXXConstructorDecl *CD,
6314110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne                                    CXXCtorType CT, const BlockDecl *BD,
640e376a0ca8372c9e809d08a9db2fae98394878b8Rafael Espindola                                    llvm::raw_ostream &ResStream) {
6514110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne  checkMangleDC(CD, BD);
6614110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne  llvm::SmallString<64> Buffer;
67c4850c2aa4c281a352e228aafc51fb1e30dcad02Rafael Espindola  llvm::raw_svector_ostream Out(Buffer);
68c4850c2aa4c281a352e228aafc51fb1e30dcad02Rafael Espindola  mangleCXXCtor(CD, CT, Out);
69c4850c2aa4c281a352e228aafc51fb1e30dcad02Rafael Espindola  Out.flush();
70c4850c2aa4c281a352e228aafc51fb1e30dcad02Rafael Espindola  mangleFunctionBlock(*this, Buffer, BD, ResStream);
7114110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne}
7214110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne
7314110477887e3dc168ffc6c191e72d705051f99ePeter Collingbournevoid MangleContext::mangleDtorBlock(const CXXDestructorDecl *DD,
7414110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne                                    CXXDtorType DT, const BlockDecl *BD,
750e376a0ca8372c9e809d08a9db2fae98394878b8Rafael Espindola                                    llvm::raw_ostream &ResStream) {
7614110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne  checkMangleDC(DD, BD);
7714110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne  llvm::SmallString<64> Buffer;
78c4850c2aa4c281a352e228aafc51fb1e30dcad02Rafael Espindola  llvm::raw_svector_ostream Out(Buffer);
79c4850c2aa4c281a352e228aafc51fb1e30dcad02Rafael Espindola  mangleCXXDtor(DD, DT, Out);
80c4850c2aa4c281a352e228aafc51fb1e30dcad02Rafael Espindola  Out.flush();
81c4850c2aa4c281a352e228aafc51fb1e30dcad02Rafael Espindola  mangleFunctionBlock(*this, Buffer, BD, ResStream);
8214110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne}
8314110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne
8414110477887e3dc168ffc6c191e72d705051f99ePeter Collingbournevoid MangleContext::mangleBlock(const DeclContext *DC, const BlockDecl *BD,
850e376a0ca8372c9e809d08a9db2fae98394878b8Rafael Espindola                                llvm::raw_ostream &Out) {
8614110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne  assert(!isa<CXXConstructorDecl>(DC) && !isa<CXXDestructorDecl>(DC));
8714110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne  checkMangleDC(DC, BD);
8814110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne
8914110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne  llvm::SmallString<64> Buffer;
90f0be979bddb8baa28e77693a3dc931e487b2a9f2Rafael Espindola  llvm::raw_svector_ostream Stream(Buffer);
9114110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne  if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(DC)) {
92f0be979bddb8baa28e77693a3dc931e487b2a9f2Rafael Espindola    mangleObjCMethodName(Method, Stream);
9314110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne  } else {
9414110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne    const NamedDecl *ND = cast<NamedDecl>(DC);
9514110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne    if (IdentifierInfo *II = ND->getIdentifier())
96f0be979bddb8baa28e77693a3dc931e487b2a9f2Rafael Espindola      Stream << II->getName();
9714110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne    else {
9814110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne      // FIXME: We were doing a mangleUnqualifiedName() before, but that's
9914110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne      // a private member of a class that will soon itself be private to the
10014110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne      // Itanium C++ ABI object. What should we do now? Right now, I'm just
10114110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne      // calling the mangleName() method on the MangleContext; is there a
10214110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne      // better way?
103f0be979bddb8baa28e77693a3dc931e487b2a9f2Rafael Espindola      mangleName(ND, Stream);
10414110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne    }
10514110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne  }
106f0be979bddb8baa28e77693a3dc931e487b2a9f2Rafael Espindola  Stream.flush();
107c4850c2aa4c281a352e228aafc51fb1e30dcad02Rafael Espindola  mangleFunctionBlock(*this, Buffer, BD, Out);
10814110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne}
10914110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne
11014110477887e3dc168ffc6c191e72d705051f99ePeter Collingbournevoid MangleContext::mangleObjCMethodName(const ObjCMethodDecl *MD,
111f0be979bddb8baa28e77693a3dc931e487b2a9f2Rafael Espindola                                         llvm::raw_ostream &Out) {
11214110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne  llvm::SmallString<64> Name;
113f0be979bddb8baa28e77693a3dc931e487b2a9f2Rafael Espindola  llvm::raw_svector_ostream OS(Name);
11414110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne
11514110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne  const ObjCContainerDecl *CD =
11614110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne  dyn_cast<ObjCContainerDecl>(MD->getDeclContext());
11714110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne  assert (CD && "Missing container decl in GetNameForMethod");
11814110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne  OS << (MD->isInstanceMethod() ? '-' : '+') << '[' << CD->getName();
11914110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne  if (const ObjCCategoryImplDecl *CID = dyn_cast<ObjCCategoryImplDecl>(CD))
12014110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne    OS << '(' << CID << ')';
12114110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne  OS << ' ' << MD->getSelector().getAsString() << ']';
12214110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne
12314110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne  Out << OS.str().size() << OS.str();
12414110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne}
12514110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne
12614110477887e3dc168ffc6c191e72d705051f99ePeter Collingbournevoid MangleContext::mangleBlock(const BlockDecl *BD,
1270e376a0ca8372c9e809d08a9db2fae98394878b8Rafael Espindola                                llvm::raw_ostream &Out) {
12814110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne  const DeclContext *DC = BD->getDeclContext();
12914110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne  while (isa<BlockDecl>(DC) || isa<EnumDecl>(DC))
13014110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne    DC = DC->getParent();
13114110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne  if (DC->isFunctionOrMethod())
132c4850c2aa4c281a352e228aafc51fb1e30dcad02Rafael Espindola    mangleBlock(DC, BD, Out);
13314110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne  else
134c4850c2aa4c281a352e228aafc51fb1e30dcad02Rafael Espindola    mangleGlobalBlock(BD, Out);
13514110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne}
136