blob: 04f5dd6b21e089bf728495d1eac4310b9f7b07c6 [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"
Douglas Gregor5f2bfd42009-02-13 00:10:09 +000026
27namespace clang {
Anders Carlssonb73a5be2009-11-26 02:49:32 +000028 class ASTContext;
Douglas Gregor35415f52010-05-25 17:04:15 +000029 class BlockDecl;
Anders Carlssonb73a5be2009-11-26 02:49:32 +000030 class CXXConstructorDecl;
31 class CXXDestructorDecl;
Anders Carlsson19879c92010-03-23 17:17:29 +000032 class CXXMethodDecl;
Anders Carlssonb73a5be2009-11-26 02:49:32 +000033 class FunctionDecl;
34 class NamedDecl;
35 class VarDecl;
Mike Stump1eb44332009-09-09 15:08:12 +000036
Anders Carlssonb73a5be2009-11-26 02:49:32 +000037namespace CodeGen {
Douglas Gregor9ff659b2010-03-24 16:59:08 +000038 struct ThisAdjustment;
39 struct ThunkInfo;
John McCallf746aa62010-03-19 23:29:14 +000040
41/// MangleBuffer - a convenient class for storing a name which is
42/// either the result of a mangling or is a constant string with
43/// external memory ownership.
44class MangleBuffer {
45public:
46 void setString(llvm::StringRef Ref) {
47 String = Ref;
48 }
49
50 llvm::SmallVectorImpl<char> &getBuffer() {
51 return Buffer;
52 }
53
54 llvm::StringRef getString() const {
55 if (!String.empty()) return String;
56 return Buffer.str();
57 }
58
59 operator llvm::StringRef() const {
60 return getString();
61 }
62
63private:
64 llvm::StringRef String;
65 llvm::SmallString<256> Buffer;
66};
Anders Carlssonb73a5be2009-11-26 02:49:32 +000067
Daniel Dunbar1b077112009-11-21 09:06:10 +000068/// MangleContext - Context for tracking state which persists across multiple
69/// calls to the C++ name mangler.
70class MangleContext {
71 ASTContext &Context;
John McCall6ae1f352010-04-09 22:26:14 +000072 Diagnostic &Diags;
Anders Carlssonc4355b62009-10-07 01:45:02 +000073
Daniel Dunbar1b077112009-11-21 09:06:10 +000074 llvm::DenseMap<const TagDecl *, uint64_t> AnonStructIds;
Fariborz Jahanian4819ac42010-03-04 01:02:03 +000075 unsigned Discriminator;
76 llvm::DenseMap<const NamedDecl*, unsigned> Uniquifier;
Douglas Gregor35415f52010-05-25 17:04:15 +000077 llvm::DenseMap<const BlockDecl*, unsigned> GlobalBlockIds;
78 llvm::DenseMap<const BlockDecl*, unsigned> LocalBlockIds;
Fariborz Jahanian4819ac42010-03-04 01:02:03 +000079
Daniel Dunbar1b077112009-11-21 09:06:10 +000080public:
John McCall6ae1f352010-04-09 22:26:14 +000081 explicit MangleContext(ASTContext &Context,
82 Diagnostic &Diags)
83 : Context(Context), Diags(Diags) { }
Anders Carlssonb5404912009-10-07 01:06:45 +000084
Daniel Dunbar1b077112009-11-21 09:06:10 +000085 ASTContext &getASTContext() const { return Context; }
86
John McCall6ae1f352010-04-09 22:26:14 +000087 Diagnostic &getDiags() const { return Diags; }
88
Douglas Gregor35415f52010-05-25 17:04:15 +000089 void startNewFunction() { LocalBlockIds.clear(); }
90
Daniel Dunbar1b077112009-11-21 09:06:10 +000091 uint64_t getAnonymousStructId(const TagDecl *TD) {
92 std::pair<llvm::DenseMap<const TagDecl *,
93 uint64_t>::iterator, bool> Result =
94 AnonStructIds.insert(std::make_pair(TD, AnonStructIds.size()));
95 return Result.first->second;
96 }
97
Douglas Gregor35415f52010-05-25 17:04:15 +000098 unsigned getBlockId(const BlockDecl *BD, bool Local) {
99 llvm::DenseMap<const BlockDecl *, unsigned> &BlockIds
100 = Local? LocalBlockIds : GlobalBlockIds;
101 std::pair<llvm::DenseMap<const BlockDecl *, unsigned>::iterator, bool>
102 Result = BlockIds.insert(std::make_pair(BD, BlockIds.size()));
103 return Result.first->second;
104 }
105
Daniel Dunbar1b077112009-11-21 09:06:10 +0000106 /// @name Mangler Entry Points
107 /// @{
108
Daniel Dunbarf981bf82009-11-21 09:14:52 +0000109 bool shouldMangleDeclName(const NamedDecl *D);
Daniel Dunbarf981bf82009-11-21 09:14:52 +0000110 void mangleName(const NamedDecl *D, llvm::SmallVectorImpl<char> &);
Anders Carlsson19879c92010-03-23 17:17:29 +0000111 void mangleThunk(const CXXMethodDecl *MD,
112 const ThunkInfo &Thunk,
113 llvm::SmallVectorImpl<char> &);
Anders Carlsson19879c92010-03-23 17:17:29 +0000114 void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type,
115 const ThisAdjustment &ThisAdjustment,
116 llvm::SmallVectorImpl<char> &);
Daniel Dunbar94fd26d2009-11-21 09:06:22 +0000117 void mangleGuardVariable(const VarDecl *D, llvm::SmallVectorImpl<char> &);
Anders Carlsson046c2942010-04-17 20:15:18 +0000118 void mangleCXXVTable(const CXXRecordDecl *RD, llvm::SmallVectorImpl<char> &);
Daniel Dunbar94fd26d2009-11-21 09:06:22 +0000119 void mangleCXXVTT(const CXXRecordDecl *RD, llvm::SmallVectorImpl<char> &);
Anders Carlsson046c2942010-04-17 20:15:18 +0000120 void mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset,
Daniel Dunbar94fd26d2009-11-21 09:06:22 +0000121 const CXXRecordDecl *Type,
122 llvm::SmallVectorImpl<char> &);
Mike Stumpde050572009-12-02 18:57:08 +0000123 void mangleCXXRTTI(QualType T, llvm::SmallVectorImpl<char> &);
124 void mangleCXXRTTIName(QualType T, llvm::SmallVectorImpl<char> &);
Daniel Dunbar1b077112009-11-21 09:06:10 +0000125 void mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type,
Daniel Dunbar94fd26d2009-11-21 09:06:22 +0000126 llvm::SmallVectorImpl<char> &);
Daniel Dunbar1b077112009-11-21 09:06:10 +0000127 void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type,
Daniel Dunbar94fd26d2009-11-21 09:06:22 +0000128 llvm::SmallVectorImpl<char> &);
Douglas Gregor35415f52010-05-25 17:04:15 +0000129 void mangleBlock(const BlockDecl *BD, llvm::SmallVectorImpl<char> &);
130
Fariborz Jahanian4819ac42010-03-04 01:02:03 +0000131 void mangleInitDiscriminator() {
132 Discriminator = 0;
133 }
Daniel Dunbar1b077112009-11-21 09:06:10 +0000134
Fariborz Jahanian4819ac42010-03-04 01:02:03 +0000135 bool getNextDiscriminator(const NamedDecl *ND, unsigned &disc) {
136 unsigned &discriminator = Uniquifier[ND];
137 if (!discriminator)
138 discriminator = ++Discriminator;
139 if (discriminator == 1)
140 return false;
141 disc = discriminator-2;
142 return true;
143 }
Daniel Dunbar1b077112009-11-21 09:06:10 +0000144 /// @}
145};
Anders Carlssonb73a5be2009-11-26 02:49:32 +0000146
147}
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000148}
149
Mike Stump1eb44332009-09-09 15:08:12 +0000150#endif