1218887Sdim//===--- Mangle.h - Mangle C++ Names ----------------------------*- C++ -*-===// 2218887Sdim// 3218887Sdim// The LLVM Compiler Infrastructure 4218887Sdim// 5218887Sdim// This file is distributed under the University of Illinois Open Source 6218887Sdim// License. See LICENSE.TXT for details. 7218887Sdim// 8218887Sdim//===----------------------------------------------------------------------===// 9218887Sdim// 10218887Sdim// Defines the C++ name mangling interface. 11218887Sdim// 12218887Sdim//===----------------------------------------------------------------------===// 13218887Sdim 14218887Sdim#ifndef LLVM_CLANG_AST_MANGLE_H 15218887Sdim#define LLVM_CLANG_AST_MANGLE_H 16218887Sdim 17218887Sdim#include "clang/AST/Type.h" 18218887Sdim#include "clang/Basic/ABI.h" 19218887Sdim#include "llvm/ADT/DenseMap.h" 20249423Sdim#include "llvm/ADT/SmallString.h" 21218887Sdim#include "llvm/ADT/StringRef.h" 22263508Sdim#include "llvm/Support/Casting.h" 23218887Sdim#include "llvm/Support/raw_ostream.h" 24218887Sdim 25218887Sdimnamespace clang { 26218887Sdim class ASTContext; 27218887Sdim class BlockDecl; 28218887Sdim class CXXConstructorDecl; 29218887Sdim class CXXDestructorDecl; 30218887Sdim class CXXMethodDecl; 31218887Sdim class FunctionDecl; 32218887Sdim class NamedDecl; 33218887Sdim class ObjCMethodDecl; 34218887Sdim class VarDecl; 35218887Sdim struct ThisAdjustment; 36218887Sdim struct ThunkInfo; 37218887Sdim 38218887Sdim/// MangleBuffer - a convenient class for storing a name which is 39218887Sdim/// either the result of a mangling or is a constant string with 40218887Sdim/// external memory ownership. 41218887Sdimclass MangleBuffer { 42218887Sdimpublic: 43226633Sdim void setString(StringRef Ref) { 44218887Sdim String = Ref; 45218887Sdim } 46218887Sdim 47226633Sdim SmallVectorImpl<char> &getBuffer() { 48218887Sdim return Buffer; 49218887Sdim } 50218887Sdim 51226633Sdim StringRef getString() const { 52218887Sdim if (!String.empty()) return String; 53218887Sdim return Buffer.str(); 54218887Sdim } 55218887Sdim 56226633Sdim operator StringRef() const { 57218887Sdim return getString(); 58218887Sdim } 59218887Sdim 60218887Sdimprivate: 61226633Sdim StringRef String; 62234353Sdim SmallString<256> Buffer; 63218887Sdim}; 64218887Sdim 65218887Sdim/// MangleContext - Context for tracking state which persists across multiple 66218887Sdim/// calls to the C++ name mangler. 67218887Sdimclass MangleContext { 68263508Sdimpublic: 69263508Sdim enum ManglerKind { 70263508Sdim MK_Itanium, 71263508Sdim MK_Microsoft 72263508Sdim }; 73263508Sdim 74263508Sdimprivate: 75234353Sdim virtual void anchor(); 76234353Sdim 77218887Sdim ASTContext &Context; 78226633Sdim DiagnosticsEngine &Diags; 79263508Sdim const ManglerKind Kind; 80218887Sdim 81218887Sdim llvm::DenseMap<const BlockDecl*, unsigned> GlobalBlockIds; 82218887Sdim llvm::DenseMap<const BlockDecl*, unsigned> LocalBlockIds; 83263508Sdim 84218887Sdimpublic: 85263508Sdim ManglerKind getKind() const { return Kind; } 86263508Sdim 87218887Sdim explicit MangleContext(ASTContext &Context, 88263508Sdim DiagnosticsEngine &Diags, 89263508Sdim ManglerKind Kind) 90263508Sdim : Context(Context), Diags(Diags), Kind(Kind) {} 91218887Sdim 92218887Sdim virtual ~MangleContext() { } 93218887Sdim 94218887Sdim ASTContext &getASTContext() const { return Context; } 95218887Sdim 96226633Sdim DiagnosticsEngine &getDiags() const { return Diags; } 97218887Sdim 98218887Sdim virtual void startNewFunction() { LocalBlockIds.clear(); } 99218887Sdim 100218887Sdim unsigned getBlockId(const BlockDecl *BD, bool Local) { 101218887Sdim llvm::DenseMap<const BlockDecl *, unsigned> &BlockIds 102218887Sdim = Local? LocalBlockIds : GlobalBlockIds; 103218887Sdim std::pair<llvm::DenseMap<const BlockDecl *, unsigned>::iterator, bool> 104218887Sdim Result = BlockIds.insert(std::make_pair(BD, BlockIds.size())); 105218887Sdim return Result.first->second; 106218887Sdim } 107218887Sdim 108218887Sdim /// @name Mangler Entry Points 109218887Sdim /// @{ 110218887Sdim 111263508Sdim bool shouldMangleDeclName(const NamedDecl *D); 112263508Sdim virtual bool shouldMangleCXXName(const NamedDecl *D) = 0; 113263508Sdim 114263508Sdim // FIXME: consider replacing raw_ostream & with something like SmallString &. 115263508Sdim void mangleName(const NamedDecl *D, raw_ostream &); 116263508Sdim virtual void mangleCXXName(const NamedDecl *D, raw_ostream &) = 0; 117218887Sdim virtual void mangleThunk(const CXXMethodDecl *MD, 118218887Sdim const ThunkInfo &Thunk, 119226633Sdim raw_ostream &) = 0; 120218887Sdim virtual void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type, 121218887Sdim const ThisAdjustment &ThisAdjustment, 122226633Sdim raw_ostream &) = 0; 123218887Sdim virtual void mangleReferenceTemporary(const VarDecl *D, 124226633Sdim raw_ostream &) = 0; 125226633Sdim virtual void mangleCXXRTTI(QualType T, raw_ostream &) = 0; 126226633Sdim virtual void mangleCXXRTTIName(QualType T, raw_ostream &) = 0; 127218887Sdim virtual void mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type, 128226633Sdim raw_ostream &) = 0; 129218887Sdim virtual void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type, 130226633Sdim raw_ostream &) = 0; 131218887Sdim 132218887Sdim void mangleGlobalBlock(const BlockDecl *BD, 133239462Sdim const NamedDecl *ID, 134226633Sdim raw_ostream &Out); 135218887Sdim void mangleCtorBlock(const CXXConstructorDecl *CD, CXXCtorType CT, 136226633Sdim const BlockDecl *BD, raw_ostream &Out); 137218887Sdim void mangleDtorBlock(const CXXDestructorDecl *CD, CXXDtorType DT, 138226633Sdim const BlockDecl *BD, raw_ostream &Out); 139218887Sdim void mangleBlock(const DeclContext *DC, const BlockDecl *BD, 140226633Sdim raw_ostream &Out); 141218887Sdim 142263508Sdim void mangleObjCMethodName(const ObjCMethodDecl *MD, raw_ostream &); 143218887Sdim 144263508Sdim virtual void mangleStaticGuardVariable(const VarDecl *D, raw_ostream &) = 0; 145263508Sdim 146263508Sdim virtual void mangleDynamicInitializer(const VarDecl *D, raw_ostream &) = 0; 147263508Sdim 148263508Sdim virtual void mangleDynamicAtExitDestructor(const VarDecl *D, 149263508Sdim raw_ostream &) = 0; 150263508Sdim 151263508Sdim /// Generates a unique string for an externally visible type for use with TBAA 152263508Sdim /// or type uniquing. 153263508Sdim /// TODO: Extend this to internal types by generating names that are unique 154263508Sdim /// across translation units so it can be used with LTO. 155263508Sdim virtual void mangleTypeName(QualType T, raw_ostream &) = 0; 156263508Sdim 157263508Sdim /// @} 158263508Sdim}; 159263508Sdim 160263508Sdimclass ItaniumMangleContext : public MangleContext { 161263508Sdimpublic: 162263508Sdim explicit ItaniumMangleContext(ASTContext &C, DiagnosticsEngine &D) 163263508Sdim : MangleContext(C, D, MK_Itanium) {} 164263508Sdim 165263508Sdim virtual void mangleCXXVTable(const CXXRecordDecl *RD, raw_ostream &) = 0; 166263508Sdim virtual void mangleCXXVTT(const CXXRecordDecl *RD, raw_ostream &) = 0; 167263508Sdim virtual void mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset, 168263508Sdim const CXXRecordDecl *Type, 169263508Sdim raw_ostream &) = 0; 170251662Sdim virtual void mangleItaniumThreadLocalInit(const VarDecl *D, 171263508Sdim raw_ostream &) = 0; 172251662Sdim virtual void mangleItaniumThreadLocalWrapper(const VarDecl *D, 173263508Sdim raw_ostream &) = 0; 174263508Sdim 175263508Sdim static bool classof(const MangleContext *C) { 176263508Sdim return C->getKind() == MK_Itanium; 177251662Sdim } 178251662Sdim 179263508Sdim static ItaniumMangleContext *create(ASTContext &Context, 180263508Sdim DiagnosticsEngine &Diags); 181218887Sdim}; 182218887Sdim 183263508Sdimclass MicrosoftMangleContext : public MangleContext { 184263508Sdimpublic: 185263508Sdim explicit MicrosoftMangleContext(ASTContext &C, DiagnosticsEngine &D) 186263508Sdim : MangleContext(C, D, MK_Microsoft) {} 187218887Sdim 188263508Sdim /// \brief Mangle vftable symbols. Only a subset of the bases along the path 189263508Sdim /// to the vftable are included in the name. It's up to the caller to pick 190263508Sdim /// them correctly. 191263508Sdim virtual void mangleCXXVFTable(const CXXRecordDecl *Derived, 192263508Sdim ArrayRef<const CXXRecordDecl *> BasePath, 193263508Sdim raw_ostream &Out) = 0; 194263508Sdim 195263508Sdim /// \brief Mangle vbtable symbols. Only a subset of the bases along the path 196263508Sdim /// to the vbtable are included in the name. It's up to the caller to pick 197263508Sdim /// them correctly. 198263508Sdim virtual void mangleCXXVBTable(const CXXRecordDecl *Derived, 199263508Sdim ArrayRef<const CXXRecordDecl *> BasePath, 200263508Sdim raw_ostream &Out) = 0; 201263508Sdim 202263508Sdim virtual void mangleVirtualMemPtrThunk(const CXXMethodDecl *MD, 203263508Sdim uint64_t OffsetInVFTable, 204263508Sdim raw_ostream &) = 0; 205263508Sdim 206263508Sdim static bool classof(const MangleContext *C) { 207263508Sdim return C->getKind() == MK_Microsoft; 208263508Sdim } 209263508Sdim 210263508Sdim static MicrosoftMangleContext *create(ASTContext &Context, 211263508Sdim DiagnosticsEngine &Diags); 212263508Sdim}; 213218887Sdim} 214218887Sdim 215218887Sdim#endif 216