blob: f1c5358bdd85065d58ab9d9f7d11a2e7d11e7138 [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
Daniel Dunbar1b077112009-11-21 09:06:10 +000087 ASTContext &getASTContext() const { return Context; }
88
John McCall6ae1f352010-04-09 22:26:14 +000089 Diagnostic &getDiags() const { return Diags; }
90
Douglas Gregor35415f52010-05-25 17:04:15 +000091 void startNewFunction() { LocalBlockIds.clear(); }
92
Daniel Dunbar1b077112009-11-21 09:06:10 +000093 uint64_t getAnonymousStructId(const TagDecl *TD) {
94 std::pair<llvm::DenseMap<const TagDecl *,
95 uint64_t>::iterator, bool> Result =
96 AnonStructIds.insert(std::make_pair(TD, AnonStructIds.size()));
97 return Result.first->second;
98 }
99
Douglas Gregor35415f52010-05-25 17:04:15 +0000100 unsigned getBlockId(const BlockDecl *BD, bool Local) {
101 llvm::DenseMap<const BlockDecl *, unsigned> &BlockIds
102 = Local? LocalBlockIds : GlobalBlockIds;
103 std::pair<llvm::DenseMap<const BlockDecl *, unsigned>::iterator, bool>
104 Result = BlockIds.insert(std::make_pair(BD, BlockIds.size()));
105 return Result.first->second;
106 }
107
Daniel Dunbar1b077112009-11-21 09:06:10 +0000108 /// @name Mangler Entry Points
109 /// @{
110
Daniel Dunbarf981bf82009-11-21 09:14:52 +0000111 bool shouldMangleDeclName(const NamedDecl *D);
Charles Davis685b1d92010-05-26 18:25:27 +0000112 virtual void mangleName(const NamedDecl *D, llvm::SmallVectorImpl<char> &);
113 virtual void mangleThunk(const CXXMethodDecl *MD,
114 const ThunkInfo &Thunk,
Anders Carlsson19879c92010-03-23 17:17:29 +0000115 llvm::SmallVectorImpl<char> &);
Charles Davis685b1d92010-05-26 18:25:27 +0000116 virtual void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type,
117 const ThisAdjustment &ThisAdjustment,
118 llvm::SmallVectorImpl<char> &);
119 virtual void mangleGuardVariable(const VarDecl *D,
120 llvm::SmallVectorImpl<char> &);
121 virtual void mangleCXXVTable(const CXXRecordDecl *RD,
122 llvm::SmallVectorImpl<char> &);
123 virtual void mangleCXXVTT(const CXXRecordDecl *RD,
124 llvm::SmallVectorImpl<char> &);
125 virtual void mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset,
126 const CXXRecordDecl *Type,
127 llvm::SmallVectorImpl<char> &);
128 virtual void mangleCXXRTTI(QualType T, llvm::SmallVectorImpl<char> &);
129 virtual void mangleCXXRTTIName(QualType T, llvm::SmallVectorImpl<char> &);
130 virtual void mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type,
131 llvm::SmallVectorImpl<char> &);
132 virtual void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type,
133 llvm::SmallVectorImpl<char> &);
Douglas Gregor35415f52010-05-25 17:04:15 +0000134 void mangleBlock(const BlockDecl *BD, llvm::SmallVectorImpl<char> &);
135
Fariborz Jahanian4819ac42010-03-04 01:02:03 +0000136 void mangleInitDiscriminator() {
137 Discriminator = 0;
138 }
Daniel Dunbar1b077112009-11-21 09:06:10 +0000139
Fariborz Jahanian4819ac42010-03-04 01:02:03 +0000140 bool getNextDiscriminator(const NamedDecl *ND, unsigned &disc) {
141 unsigned &discriminator = Uniquifier[ND];
142 if (!discriminator)
143 discriminator = ++Discriminator;
144 if (discriminator == 1)
145 return false;
146 disc = discriminator-2;
147 return true;
148 }
Daniel Dunbar1b077112009-11-21 09:06:10 +0000149 /// @}
150};
Charles Davis685b1d92010-05-26 18:25:27 +0000151
152/// MiscNameMangler - Mangles Objective-C method names and blocks.
153class MiscNameMangler {
154 MangleContext &Context;
155 llvm::raw_svector_ostream Out;
Anders Carlssonb73a5be2009-11-26 02:49:32 +0000156
Charles Davis685b1d92010-05-26 18:25:27 +0000157 ASTContext &getASTContext() const { return Context.getASTContext(); }
158
159public:
160 MiscNameMangler(MangleContext &C, llvm::SmallVectorImpl<char> &Res);
161
162 llvm::raw_svector_ostream &getStream() { return Out; }
163
164 void mangleBlock(const BlockDecl *BD);
165 void mangleObjCMethodName(const ObjCMethodDecl *MD);
166};
167
Anders Carlssonb73a5be2009-11-26 02:49:32 +0000168}
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000169}
170
Mike Stump1eb44332009-09-09 15:08:12 +0000171#endif