blob: a12a140f725259978bb66fd85fdfbed538b3dd50 [file] [log] [blame]
Douglas Gregor6ec36682009-02-18 23:53:56 +00001//===--- Mangle.h - Mangle C++ Names ----------------------------*- C++ -*-===//
Douglas Gregor5f2bfd42009-02-13 00:10:09 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// Implements C++ name mangling according to the Itanium C++ ABI,
11// which is used in GCC 3.2 and newer (and many compilers that are
12// ABI-compatible with GCC):
13//
14// http://www.codesourcery.com/public/cxx-abi/abi.html
15//
16//===----------------------------------------------------------------------===//
Chris Lattnerca3f25c2009-03-21 08:24:40 +000017
Douglas Gregor5f2bfd42009-02-13 00:10:09 +000018#ifndef LLVM_CLANG_CODEGEN_MANGLE_H
19#define LLVM_CLANG_CODEGEN_MANGLE_H
20
Anders Carlsson3ac86b52009-04-15 05:36:58 +000021#include "CGCXX.h"
Mike Stumpf1216772009-07-31 18:25:34 +000022#include "clang/AST/Type.h"
Anders Carlssonc4355b62009-10-07 01:45:02 +000023#include "llvm/ADT/DenseMap.h"
John McCallf746aa62010-03-19 23:29:14 +000024#include "llvm/ADT/StringRef.h"
25#include "llvm/ADT/SmallString.h"
Charles Davis685b1d92010-05-26 18:25:27 +000026#include "llvm/Support/raw_ostream.h"
Douglas Gregor5f2bfd42009-02-13 00:10:09 +000027
28namespace clang {
Anders Carlssonb73a5be2009-11-26 02:49:32 +000029 class ASTContext;
Douglas Gregor35415f52010-05-25 17:04:15 +000030 class BlockDecl;
Anders Carlssonb73a5be2009-11-26 02:49:32 +000031 class CXXConstructorDecl;
32 class CXXDestructorDecl;
Anders Carlsson19879c92010-03-23 17:17:29 +000033 class CXXMethodDecl;
Anders Carlssonb73a5be2009-11-26 02:49:32 +000034 class FunctionDecl;
35 class NamedDecl;
Charles Davis685b1d92010-05-26 18:25:27 +000036 class ObjCMethodDecl;
Anders Carlssonb73a5be2009-11-26 02:49:32 +000037 class VarDecl;
Mike Stump1eb44332009-09-09 15:08:12 +000038
Anders Carlssonb73a5be2009-11-26 02:49:32 +000039namespace CodeGen {
Douglas Gregor9ff659b2010-03-24 16:59:08 +000040 struct ThisAdjustment;
41 struct ThunkInfo;
John McCallf746aa62010-03-19 23:29:14 +000042
43/// MangleBuffer - a convenient class for storing a name which is
44/// either the result of a mangling or is a constant string with
45/// external memory ownership.
46class MangleBuffer {
47public:
48 void setString(llvm::StringRef Ref) {
49 String = Ref;
50 }
51
52 llvm::SmallVectorImpl<char> &getBuffer() {
53 return Buffer;
54 }
55
56 llvm::StringRef getString() const {
57 if (!String.empty()) return String;
58 return Buffer.str();
59 }
60
61 operator llvm::StringRef() const {
62 return getString();
63 }
64
65private:
66 llvm::StringRef String;
67 llvm::SmallString<256> Buffer;
68};
Charles Davis685b1d92010-05-26 18:25:27 +000069
Daniel Dunbar1b077112009-11-21 09:06:10 +000070/// MangleContext - Context for tracking state which persists across multiple
71/// calls to the C++ name mangler.
72class MangleContext {
73 ASTContext &Context;
John McCall6ae1f352010-04-09 22:26:14 +000074 Diagnostic &Diags;
Anders Carlssonc4355b62009-10-07 01:45:02 +000075
Daniel Dunbar1b077112009-11-21 09:06:10 +000076 llvm::DenseMap<const TagDecl *, uint64_t> AnonStructIds;
Fariborz Jahanian4819ac42010-03-04 01:02:03 +000077 unsigned Discriminator;
78 llvm::DenseMap<const NamedDecl*, unsigned> Uniquifier;
Douglas Gregor35415f52010-05-25 17:04:15 +000079 llvm::DenseMap<const BlockDecl*, unsigned> GlobalBlockIds;
80 llvm::DenseMap<const BlockDecl*, unsigned> LocalBlockIds;
Fariborz Jahanian4819ac42010-03-04 01:02:03 +000081
Daniel Dunbar1b077112009-11-21 09:06:10 +000082public:
John McCall6ae1f352010-04-09 22:26:14 +000083 explicit MangleContext(ASTContext &Context,
84 Diagnostic &Diags)
85 : Context(Context), Diags(Diags) { }
Anders Carlssonb5404912009-10-07 01:06:45 +000086
Charles Davisc3926642010-06-09 23:25:41 +000087 virtual ~MangleContext() { }
88
Daniel Dunbar1b077112009-11-21 09:06:10 +000089 ASTContext &getASTContext() const { return Context; }
90
John McCall6ae1f352010-04-09 22:26:14 +000091 Diagnostic &getDiags() const { return Diags; }
92
Douglas Gregor35415f52010-05-25 17:04:15 +000093 void startNewFunction() { LocalBlockIds.clear(); }
94
Daniel Dunbar1b077112009-11-21 09:06:10 +000095 uint64_t getAnonymousStructId(const TagDecl *TD) {
96 std::pair<llvm::DenseMap<const TagDecl *,
97 uint64_t>::iterator, bool> Result =
98 AnonStructIds.insert(std::make_pair(TD, AnonStructIds.size()));
99 return Result.first->second;
100 }
101
Douglas Gregor35415f52010-05-25 17:04:15 +0000102 unsigned getBlockId(const BlockDecl *BD, bool Local) {
103 llvm::DenseMap<const BlockDecl *, unsigned> &BlockIds
104 = Local? LocalBlockIds : GlobalBlockIds;
105 std::pair<llvm::DenseMap<const BlockDecl *, unsigned>::iterator, bool>
106 Result = BlockIds.insert(std::make_pair(BD, BlockIds.size()));
107 return Result.first->second;
108 }
109
Daniel Dunbar1b077112009-11-21 09:06:10 +0000110 /// @name Mangler Entry Points
111 /// @{
112
Daniel Dunbarf981bf82009-11-21 09:14:52 +0000113 bool shouldMangleDeclName(const NamedDecl *D);
Charles Davisc3926642010-06-09 23:25:41 +0000114 virtual void mangleName(const NamedDecl *D, llvm::SmallVectorImpl<char> &);
115 virtual void mangleThunk(const CXXMethodDecl *MD,
116 const ThunkInfo &Thunk,
Anders Carlsson19879c92010-03-23 17:17:29 +0000117 llvm::SmallVectorImpl<char> &);
Charles Davisc3926642010-06-09 23:25:41 +0000118 virtual void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type,
119 const ThisAdjustment &ThisAdjustment,
120 llvm::SmallVectorImpl<char> &);
121 virtual void mangleGuardVariable(const VarDecl *D,
122 llvm::SmallVectorImpl<char> &);
123 virtual void mangleCXXVTable(const CXXRecordDecl *RD,
124 llvm::SmallVectorImpl<char> &);
125 virtual void mangleCXXVTT(const CXXRecordDecl *RD,
126 llvm::SmallVectorImpl<char> &);
127 virtual void mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset,
128 const CXXRecordDecl *Type,
129 llvm::SmallVectorImpl<char> &);
130 virtual void mangleCXXRTTI(QualType T, llvm::SmallVectorImpl<char> &);
131 virtual void mangleCXXRTTIName(QualType T, llvm::SmallVectorImpl<char> &);
132 virtual void mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type,
133 llvm::SmallVectorImpl<char> &);
134 virtual void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type,
135 llvm::SmallVectorImpl<char> &);
Douglas Gregor35415f52010-05-25 17:04:15 +0000136 void mangleBlock(const BlockDecl *BD, llvm::SmallVectorImpl<char> &);
137
Fariborz Jahanian4819ac42010-03-04 01:02:03 +0000138 void mangleInitDiscriminator() {
139 Discriminator = 0;
140 }
Daniel Dunbar1b077112009-11-21 09:06:10 +0000141
Fariborz Jahanian4819ac42010-03-04 01:02:03 +0000142 bool getNextDiscriminator(const NamedDecl *ND, unsigned &disc) {
143 unsigned &discriminator = Uniquifier[ND];
144 if (!discriminator)
145 discriminator = ++Discriminator;
146 if (discriminator == 1)
147 return false;
148 disc = discriminator-2;
149 return true;
150 }
Daniel Dunbar1b077112009-11-21 09:06:10 +0000151 /// @}
152};
Charles Davis685b1d92010-05-26 18:25:27 +0000153
154/// MiscNameMangler - Mangles Objective-C method names and blocks.
155class MiscNameMangler {
156 MangleContext &Context;
157 llvm::raw_svector_ostream Out;
Anders Carlssonb73a5be2009-11-26 02:49:32 +0000158
Charles Davis685b1d92010-05-26 18:25:27 +0000159 ASTContext &getASTContext() const { return Context.getASTContext(); }
160
161public:
162 MiscNameMangler(MangleContext &C, llvm::SmallVectorImpl<char> &Res);
163
164 llvm::raw_svector_ostream &getStream() { return Out; }
165
166 void mangleBlock(const BlockDecl *BD);
167 void mangleObjCMethodName(const ObjCMethodDecl *MD);
168};
169
Anders Carlssonb73a5be2009-11-26 02:49:32 +0000170}
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000171}
172
Mike Stump1eb44332009-09-09 15:08:12 +0000173#endif