blob: 948a66f665a06de874e55c7dccb38285fa2260bb [file] [log] [blame]
Charles Davis74ce8592010-06-09 23:25:41 +00001//===--- MicrosoftCXXABI.cpp - Emit LLVM Code from ASTs for a Module ------===//
2//
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// This provides C++ code generation targetting the Microsoft Visual C++ ABI.
11// The class in this file generates structures that follow the Microsoft
12// Visual C++ ABI, which is actually not very well documented at all outside
13// of Microsoft.
14//
15//===----------------------------------------------------------------------===//
16
17#include "CGCXXABI.h"
18#include "CodeGenModule.h"
19#include "Mangle.h"
20#include "clang/AST/ASTContext.h"
21#include "clang/AST/Decl.h"
22#include "clang/AST/DeclCXX.h"
23#include "clang/AST/DeclTemplate.h"
24#include "clang/AST/ExprCXX.h"
25#include "CGVTables.h"
26
27using namespace clang;
28using namespace CodeGen;
29
30namespace {
31
Charles Davis9af2d4a2010-06-11 03:07:32 +000032/// MicrosoftCXXNameMangler - Manage the mangling of a single name for the
33/// Microsoft Visual C++ ABI.
34class MicrosoftCXXNameMangler {
35 MangleContext &Context;
36 llvm::raw_svector_ostream Out;
37
38 ASTContext &getASTContext() const { return Context.getASTContext(); }
39
40public:
41 MicrosoftCXXNameMangler(MangleContext &C, llvm::SmallVectorImpl<char> &Res)
42 : Context(C), Out(Res) { }
43
44 llvm::raw_svector_ostream &getStream() { return Out; }
45
46 void mangle(const NamedDecl *D, llvm::StringRef Prefix = "?");
47 void mangleName(const NamedDecl *ND);
48
49private:
50 void mangleUnqualifiedName(const NamedDecl *ND) {
51 mangleUnqualifiedName(ND, ND->getDeclName());
52 }
53 void mangleUnqualifiedName(const NamedDecl *ND, DeclarationName Name);
54 void mangleSourceName(const IdentifierInfo *II);
55 void manglePostfix(const DeclContext *DC, bool NoFunction=false);
56
57 void mangleObjCMethodName(const ObjCMethodDecl *MD);
58
59};
60
Charles Davis74ce8592010-06-09 23:25:41 +000061/// MicrosoftMangleContext - Overrides the default MangleContext for the
62/// Microsoft Visual C++ ABI.
63class MicrosoftMangleContext : public MangleContext {
64public:
65 MicrosoftMangleContext(ASTContext &Context,
66 Diagnostic &Diags) : MangleContext(Context, Diags) { }
67 virtual void mangleName(const NamedDecl *D, llvm::SmallVectorImpl<char> &);
68 virtual void mangleThunk(const CXXMethodDecl *MD,
69 const ThunkInfo &Thunk,
70 llvm::SmallVectorImpl<char> &);
71 virtual void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type,
72 const ThisAdjustment &ThisAdjustment,
73 llvm::SmallVectorImpl<char> &);
74 virtual void mangleGuardVariable(const VarDecl *D,
75 llvm::SmallVectorImpl<char> &);
76 virtual void mangleCXXVTable(const CXXRecordDecl *RD,
77 llvm::SmallVectorImpl<char> &);
78 virtual void mangleCXXVTT(const CXXRecordDecl *RD,
79 llvm::SmallVectorImpl<char> &);
80 virtual void mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset,
81 const CXXRecordDecl *Type,
82 llvm::SmallVectorImpl<char> &);
83 virtual void mangleCXXRTTI(QualType T, llvm::SmallVectorImpl<char> &);
84 virtual void mangleCXXRTTIName(QualType T, llvm::SmallVectorImpl<char> &);
85 virtual void mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type,
86 llvm::SmallVectorImpl<char> &);
87 virtual void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type,
88 llvm::SmallVectorImpl<char> &);
89};
90
91class MicrosoftCXXABI : public CXXABI {
92 MicrosoftMangleContext MangleCtx;
93public:
94 MicrosoftCXXABI(CodeGenModule &CGM)
95 : MangleCtx(CGM.getContext(), CGM.getDiags()) {}
96
97 MicrosoftMangleContext &getMangleContext() {
98 return MangleCtx;
99 }
100};
101
102}
103
Charles Davis9af2d4a2010-06-11 03:07:32 +0000104void MicrosoftCXXNameMangler::mangle(const NamedDecl *D,
105 llvm::StringRef Prefix) {
106 // MSVC doesn't mangle C++ names the same way it mangles extern "C" names.
107 // Therefore it's really important that we don't decorate the
108 // name with leading underscores or leading/trailing at signs. So, emit a
109 // asm marker at the start so we get the name right.
110 Out << '\01'; // LLVM IR Marker for __asm("foo")
111
112 // Any decl can be declared with __asm("foo") on it, and this takes precedence
113 // over all other naming in the .o file.
114 if (const AsmLabelAttr *ALA = D->getAttr<AsmLabelAttr>()) {
115 // If we have an asm name, then we use it as the mangling.
116 Out << ALA->getLabel();
117 return;
118 }
119
120 // <mangled-name> ::= ? <name> <type>
121 Out << Prefix;
122 mangleName(D);
123 // TODO: Mangle type.
124}
125
126void MicrosoftCXXNameMangler::mangleName(const NamedDecl *ND) {
127 // <name> ::= <unscoped-name> {[<named-scope>]+ | [<nested-name>]}? @
128 const DeclContext *DC = ND->getDeclContext();
129
130 // Always start with the unqualified name.
131 mangleUnqualifiedName(ND);
132
133 // If this is an extern variable declared locally, the relevant DeclContext
134 // is that of the containing namespace, or the translation unit.
135 if (isa<FunctionDecl>(DC) && ND->hasLinkage())
136 while (!DC->isNamespace() && !DC->isTranslationUnit())
137 DC = DC->getParent();
138
139 manglePostfix(DC);
140
141 // Terminate the whole name with an '@'.
142 Out << '@';
143}
144
145void
146MicrosoftCXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND,
147 DeclarationName Name) {
148 // <unqualified-name> ::= <operator-name>
149 // ::= <ctor-dtor-name>
150 // ::= <source-name>
151 switch (Name.getNameKind()) {
152 case DeclarationName::Identifier: {
153 if (const IdentifierInfo *II = Name.getAsIdentifierInfo()) {
154 mangleSourceName(II);
155 break;
156 }
157
158 // Otherwise, an anonymous entity. We must have a declaration.
159 assert(ND && "mangling empty name without declaration");
160
161 if (const NamespaceDecl *NS = dyn_cast<NamespaceDecl>(ND)) {
162 if (NS->isAnonymousNamespace()) {
163 Out << "?A";
164 break;
165 }
166 }
167
168 // We must have an anonymous struct.
169 const TagDecl *TD = cast<TagDecl>(ND);
170 if (const TypedefDecl *D = TD->getTypedefForAnonDecl()) {
171 assert(TD->getDeclContext() == D->getDeclContext() &&
172 "Typedef should not be in another decl context!");
173 assert(D->getDeclName().getAsIdentifierInfo() &&
174 "Typedef was not named!");
175 mangleSourceName(D->getDeclName().getAsIdentifierInfo());
176 break;
177 }
178
179 // TODO: How does VC mangle anonymous structs?
180 assert(false && "Don't know how to mangle anonymous types yet!");
181 break;
182 }
183
184 case DeclarationName::ObjCZeroArgSelector:
185 case DeclarationName::ObjCOneArgSelector:
186 case DeclarationName::ObjCMultiArgSelector:
187 assert(false && "Can't mangle Objective-C selector names here!");
188 break;
189
190 case DeclarationName::CXXConstructorName:
191 assert(false && "Can't mangle constructors yet!");
192 break;
193
194 case DeclarationName::CXXDestructorName:
195 assert(false && "Can't mangle destructors yet!");
196 break;
197
198 case DeclarationName::CXXConversionFunctionName:
199 // <operator-name> ::= ?B # (cast)
200 // The target type is encoded as the return type.
201 Out << "?B";
202 break;
203
204 case DeclarationName::CXXOperatorName:
205 assert(false && "Can't mangle operators yet!");
206
207 case DeclarationName::CXXLiteralOperatorName:
208 // FIXME: Was this added in VS2010? Does MS even know how to mangle this?
209 assert(false && "Don't know how to mangle literal operators yet!");
210 break;
211
212 case DeclarationName::CXXUsingDirective:
213 assert(false && "Can't mangle a using directive name!");
214 break;
215 }
216}
217
218void MicrosoftCXXNameMangler::manglePostfix(const DeclContext *DC,
219 bool NoFunction) {
220 // <postfix> ::= <unqualified-name> [<postfix>]
221 // ::= <template-postfix> <template-args> [<postfix>]
222 // ::= <template-param>
223 // ::= <substitution> [<postfix>]
224
225 if (!DC) return;
226
227 while (isa<LinkageSpecDecl>(DC))
228 DC = DC->getParent();
229
230 if (DC->isTranslationUnit())
231 return;
232
233 if (const BlockDecl *BD = dyn_cast<BlockDecl>(DC)) {
234 llvm::SmallString<64> Name;
235 Context.mangleBlock(BD, Name);
236 Out << Name << '@';
237 return manglePostfix(DC->getParent(), NoFunction);
238 }
239
240 if (NoFunction && (isa<FunctionDecl>(DC) || isa<ObjCMethodDecl>(DC)))
241 return;
242 else if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(DC))
243 mangleObjCMethodName(Method);
244 else {
245 mangleUnqualifiedName(cast<NamedDecl>(DC));
246 manglePostfix(DC->getParent(), NoFunction);
247 }
248}
249
250void MicrosoftCXXNameMangler::mangleSourceName(const IdentifierInfo *II) {
251 // <source name> ::= <identifier> @
252 Out << II->getName() << '@';
253}
254
255void MicrosoftCXXNameMangler::mangleObjCMethodName(const ObjCMethodDecl *MD) {
256 llvm::SmallString<64> Buffer;
257 MiscNameMangler(Context, Buffer).mangleObjCMethodName(MD);
258 Out << Buffer;
259}
260
Charles Davis74ce8592010-06-09 23:25:41 +0000261void MicrosoftMangleContext::mangleName(const NamedDecl *D,
262 llvm::SmallVectorImpl<char> &Name) {
Charles Davis9af2d4a2010-06-11 03:07:32 +0000263 assert((isa<FunctionDecl>(D) || isa<VarDecl>(D)) &&
264 "Invalid mangleName() call, argument is not a variable or function!");
265 assert(!isa<CXXConstructorDecl>(D) && !isa<CXXDestructorDecl>(D) &&
266 "Invalid mangleName() call on 'structor decl!");
267
268 PrettyStackTraceDecl CrashInfo(D, SourceLocation(),
269 getASTContext().getSourceManager(),
270 "Mangling declaration");
271
272 MicrosoftCXXNameMangler Mangler(*this, Name);
273 return Mangler.mangle(D);
Charles Davis74ce8592010-06-09 23:25:41 +0000274}
275void MicrosoftMangleContext::mangleThunk(const CXXMethodDecl *MD,
276 const ThunkInfo &Thunk,
277 llvm::SmallVectorImpl<char> &) {
278 assert(false && "Can't yet mangle thunks!");
279}
280void MicrosoftMangleContext::mangleCXXDtorThunk(const CXXDestructorDecl *DD,
281 CXXDtorType Type,
282 const ThisAdjustment &,
283 llvm::SmallVectorImpl<char> &) {
284 assert(false && "Can't yet mangle destructor thunks!");
285}
286void MicrosoftMangleContext::mangleGuardVariable(const VarDecl *D,
287 llvm::SmallVectorImpl<char> &) {
288 assert(false && "Can't yet mangle guard variables!");
289}
290void MicrosoftMangleContext::mangleCXXVTable(const CXXRecordDecl *RD,
291 llvm::SmallVectorImpl<char> &) {
292 assert(false && "Can't yet mangle virtual tables!");
293}
294void MicrosoftMangleContext::mangleCXXVTT(const CXXRecordDecl *RD,
295 llvm::SmallVectorImpl<char> &) {
296 llvm_unreachable("The MS C++ ABI does not have virtual table tables!");
297}
298void MicrosoftMangleContext::mangleCXXCtorVTable(const CXXRecordDecl *RD,
299 int64_t Offset,
300 const CXXRecordDecl *Type,
301 llvm::SmallVectorImpl<char> &) {
302 llvm_unreachable("The MS C++ ABI does not have constructor vtables!");
303}
304void MicrosoftMangleContext::mangleCXXRTTI(QualType T,
305 llvm::SmallVectorImpl<char> &) {
306 assert(false && "Can't yet mangle RTTI!");
307}
308void MicrosoftMangleContext::mangleCXXRTTIName(QualType T,
309 llvm::SmallVectorImpl<char> &) {
310 assert(false && "Can't yet mangle RTTI names!");
311}
312void MicrosoftMangleContext::mangleCXXCtor(const CXXConstructorDecl *D,
313 CXXCtorType Type,
314 llvm::SmallVectorImpl<char> &) {
315 assert(false && "Can't yet mangle constructors!");
316}
317void MicrosoftMangleContext::mangleCXXDtor(const CXXDestructorDecl *D,
318 CXXDtorType Type,
319 llvm::SmallVectorImpl<char> &) {
320 assert(false && "Can't yet mangle destructors!");
321}
322
Charles Davis95a546e2010-06-11 01:06:47 +0000323CXXABI *clang::CodeGen::CreateMicrosoftCXXABI(CodeGenModule &CGM) {
Charles Davis74ce8592010-06-09 23:25:41 +0000324 return new MicrosoftCXXABI(CGM);
325}
326