blob: 04bd52b8d4b86dbf7ebe7dd55357e5d748cb5946 [file] [log] [blame]
Douglas Gregor3c3c4542009-02-18 23:53:56 +00001//===--- Mangle.cpp - Mangle C++ Names --------------------------*- C++ -*-===//
Douglas Gregor3556bc72009-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//===----------------------------------------------------------------------===//
17#include "Mangle.h"
18#include "clang/AST/ASTContext.h"
19#include "clang/AST/Decl.h"
20#include "clang/AST/DeclCXX.h"
Anders Carlssonfae45862009-03-07 22:03:21 +000021#include "clang/AST/DeclObjC.h"
Anders Carlssonb1008e42009-05-15 16:09:15 +000022#include "clang/AST/DeclTemplate.h"
Douglas Gregor3c3c4542009-02-18 23:53:56 +000023#include "clang/Basic/SourceManager.h"
Douglas Gregor3556bc72009-02-13 00:10:09 +000024#include "llvm/Support/Compiler.h"
25#include "llvm/Support/raw_ostream.h"
John McCallb16b5472009-09-05 07:56:18 +000026#include "llvm/Support/ErrorHandling.h"
Douglas Gregor3556bc72009-02-13 00:10:09 +000027using namespace clang;
28
29namespace {
30 class VISIBILITY_HIDDEN CXXNameMangler {
31 ASTContext &Context;
32 llvm::raw_ostream &Out;
33
Anders Carlsson4811c302009-04-17 01:58:57 +000034 const CXXMethodDecl *Structor;
35 unsigned StructorType;
Anders Carlsson6b6adf22009-04-15 05:36:58 +000036 CXXCtorType CtorType;
37
Douglas Gregor3556bc72009-02-13 00:10:09 +000038 public:
39 CXXNameMangler(ASTContext &C, llvm::raw_ostream &os)
Anders Carlsson4811c302009-04-17 01:58:57 +000040 : Context(C), Out(os), Structor(0), StructorType(0) { }
Douglas Gregor3556bc72009-02-13 00:10:09 +000041
42 bool mangle(const NamedDecl *D);
Mike Stump58256412009-09-05 07:20:32 +000043 void mangleCalloffset(int64_t nv, int64_t v);
Mike Stumpbb3126c2009-09-07 04:27:52 +000044 void mangleThunk(const FunctionDecl *FD, int64_t nv, int64_t v);
45 void mangleCovariantThunk(const FunctionDecl *FD,
Mike Stump58256412009-09-05 07:20:32 +000046 int64_t nv_t, int64_t v_t,
Mike Stump28db39b2009-09-02 00:56:18 +000047 int64_t nv_r, int64_t v_r);
Anders Carlsson53f73bc2009-04-13 18:02:10 +000048 void mangleGuardVariable(const VarDecl *D);
Anders Carlsson4811c302009-04-17 01:58:57 +000049
Mike Stump7e8c9932009-07-31 18:25:34 +000050 void mangleCXXVtable(QualType Type);
Mike Stump00df7d32009-07-31 23:15:31 +000051 void mangleCXXRtti(QualType Type);
Anders Carlsson6b6adf22009-04-15 05:36:58 +000052 void mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type);
Anders Carlsson4811c302009-04-17 01:58:57 +000053 void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type);
Anders Carlsson6b6adf22009-04-15 05:36:58 +000054
Anders Carlsson70cc0d22009-04-02 15:51:53 +000055 private:
56 bool mangleFunctionDecl(const FunctionDecl *FD);
57
Douglas Gregor3556bc72009-02-13 00:10:09 +000058 void mangleFunctionEncoding(const FunctionDecl *FD);
59 void mangleName(const NamedDecl *ND);
60 void mangleUnqualifiedName(const NamedDecl *ND);
61 void mangleSourceName(const IdentifierInfo *II);
Anders Carlssonfd8c56b2009-04-02 16:24:45 +000062 void mangleLocalName(const NamedDecl *ND);
Douglas Gregor3556bc72009-02-13 00:10:09 +000063 void mangleNestedName(const NamedDecl *ND);
64 void manglePrefix(const DeclContext *DC);
65 void mangleOperatorName(OverloadedOperatorKind OO, unsigned Arity);
66 void mangleCVQualifiers(unsigned Quals);
67 void mangleType(QualType T);
John McCallb16b5472009-09-05 07:56:18 +000068
69 // Declare manglers for every type class.
70#define ABSTRACT_TYPE(CLASS, PARENT)
71#define NON_CANONICAL_TYPE(CLASS, PARENT)
72#define TYPE(CLASS, PARENT) void mangleType(const CLASS##Type *T);
73#include "clang/AST/TypeNodes.def"
74
75 void mangleType(const TagType*);
76 void mangleBareFunctionType(const FunctionType *T,
77 bool MangleReturnType);
Douglas Gregor3556bc72009-02-13 00:10:09 +000078 void mangleExpression(Expr *E);
Anders Carlsson6b6adf22009-04-15 05:36:58 +000079 void mangleCXXCtorType(CXXCtorType T);
Anders Carlsson4811c302009-04-17 01:58:57 +000080 void mangleCXXDtorType(CXXDtorType T);
Anders Carlssonb1008e42009-05-15 16:09:15 +000081
82 void mangleTemplateArgumentList(const TemplateArgumentList &L);
83 void mangleTemplateArgument(const TemplateArgument &A);
Douglas Gregor3556bc72009-02-13 00:10:09 +000084 };
85}
86
Anders Carlsson70cc0d22009-04-02 15:51:53 +000087static bool isInCLinkageSpecification(const Decl *D) {
88 for (const DeclContext *DC = D->getDeclContext();
89 !DC->isTranslationUnit(); DC = DC->getParent()) {
90 if (const LinkageSpecDecl *Linkage = dyn_cast<LinkageSpecDecl>(DC))
91 return Linkage->getLanguage() == LinkageSpecDecl::lang_c;
92 }
93
94 return false;
95}
96
97bool CXXNameMangler::mangleFunctionDecl(const FunctionDecl *FD) {
Mike Stumpb29542f2009-09-02 00:25:38 +000098 // Clang's "overloadable" attribute extension to C/C++ implies name mangling
99 // (always).
Argiris Kirtzidisfe5f9732009-06-30 02:34:44 +0000100 if (!FD->hasAttr<OverloadableAttr>()) {
Chris Lattner0c032a42009-06-13 23:34:16 +0000101 // C functions are not mangled, and "main" is never mangled.
John McCallcb6dd8a2009-08-15 02:09:25 +0000102 if (!Context.getLangOptions().CPlusPlus || FD->isMain(Context))
Chris Lattner0c032a42009-06-13 23:34:16 +0000103 return false;
104
105 // No mangling in an "implicit extern C" header.
106 if (FD->getLocation().isValid() &&
107 Context.getSourceManager().isInExternCSystemHeader(FD->getLocation()))
108 return false;
109
110 // No name mangling in a C linkage specification.
111 if (isInCLinkageSpecification(FD))
112 return false;
113 }
Anders Carlsson70cc0d22009-04-02 15:51:53 +0000114
115 // If we get here, mangle the decl name!
116 Out << "_Z";
117 mangleFunctionEncoding(FD);
118 return true;
119}
Douglas Gregor3556bc72009-02-13 00:10:09 +0000120
121bool CXXNameMangler::mangle(const NamedDecl *D) {
Mike Stumpb29542f2009-09-02 00:25:38 +0000122 // Any decl can be declared with __asm("foo") on it, and this takes precedence
123 // over all other naming in the .o file.
Argiris Kirtzidisfe5f9732009-06-30 02:34:44 +0000124 if (const AsmLabelAttr *ALA = D->getAttr<AsmLabelAttr>()) {
Chris Lattner8af0e262009-03-21 08:24:40 +0000125 // If we have an asm name, then we use it as the mangling.
126 Out << '\01'; // LLVM IR Marker for __asm("foo")
127 Out << ALA->getLabel();
128 return true;
129 }
130
Douglas Gregor3556bc72009-02-13 00:10:09 +0000131 // <mangled-name> ::= _Z <encoding>
132 // ::= <data name>
133 // ::= <special-name>
134
135 // FIXME: Actually use a visitor to decode these?
Anders Carlsson70cc0d22009-04-02 15:51:53 +0000136 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
137 return mangleFunctionDecl(FD);
Chris Lattner5cbf5882009-03-21 06:19:20 +0000138
Anders Carlssonaf6bb352009-04-02 16:05:20 +0000139 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
140 if (!Context.getLangOptions().CPlusPlus ||
Anders Carlssonc3e84ae2009-04-11 01:19:45 +0000141 isInCLinkageSpecification(D) ||
142 D->getDeclContext()->isTranslationUnit())
Anders Carlssonaf6bb352009-04-02 16:05:20 +0000143 return false;
144
145 Out << "_Z";
146 mangleName(VD);
147 return true;
148 }
149
Anders Carlsson70cc0d22009-04-02 15:51:53 +0000150 return false;
Douglas Gregor3556bc72009-02-13 00:10:09 +0000151}
152
Anders Carlsson6b6adf22009-04-15 05:36:58 +0000153void CXXNameMangler::mangleCXXCtor(const CXXConstructorDecl *D,
154 CXXCtorType Type) {
Anders Carlsson4811c302009-04-17 01:58:57 +0000155 assert(!Structor && "Structor already set!");
156 Structor = D;
157 StructorType = Type;
158
159 mangle(D);
160}
161
162void CXXNameMangler::mangleCXXDtor(const CXXDestructorDecl *D,
163 CXXDtorType Type) {
164 assert(!Structor && "Structor already set!");
165 Structor = D;
166 StructorType = Type;
Anders Carlsson6b6adf22009-04-15 05:36:58 +0000167
168 mangle(D);
169}
170
Mike Stump7e8c9932009-07-31 18:25:34 +0000171void CXXNameMangler::mangleCXXVtable(QualType T) {
172 // <special-name> ::= TV <type> # virtual table
173 Out << "_ZTV";
174 mangleType(T);
175}
176
Mike Stump00df7d32009-07-31 23:15:31 +0000177void CXXNameMangler::mangleCXXRtti(QualType T) {
178 // <special-name> ::= TI <type> # typeinfo structure
179 Out << "_ZTI";
180 mangleType(T);
181}
182
Anders Carlsson53f73bc2009-04-13 18:02:10 +0000183void CXXNameMangler::mangleGuardVariable(const VarDecl *D)
184{
185 // <special-name> ::= GV <object name> # Guard variable for one-time
Mike Stump7e8c9932009-07-31 18:25:34 +0000186 // # initialization
Anders Carlsson53f73bc2009-04-13 18:02:10 +0000187
188 Out << "_ZGV";
189 mangleName(D);
190}
191
Douglas Gregor3556bc72009-02-13 00:10:09 +0000192void CXXNameMangler::mangleFunctionEncoding(const FunctionDecl *FD) {
193 // <encoding> ::= <function name> <bare-function-type>
194 mangleName(FD);
Douglas Gregor69678062009-06-29 22:39:32 +0000195
Mike Stumpb29542f2009-09-02 00:25:38 +0000196 // Whether the mangling of a function type includes the return type depends on
197 // the context and the nature of the function. The rules for deciding whether
198 // the return type is included are:
Douglas Gregor69678062009-06-29 22:39:32 +0000199 //
200 // 1. Template functions (names or types) have return types encoded, with
201 // the exceptions listed below.
202 // 2. Function types not appearing as part of a function name mangling,
203 // e.g. parameters, pointer types, etc., have return type encoded, with the
204 // exceptions listed below.
205 // 3. Non-template function names do not have return types encoded.
206 //
Mike Stumpb29542f2009-09-02 00:25:38 +0000207 // The exceptions mentioned in (1) and (2) above, for which the return type is
208 // never included, are
Douglas Gregor69678062009-06-29 22:39:32 +0000209 // 1. Constructors.
210 // 2. Destructors.
211 // 3. Conversion operator functions, e.g. operator int.
212 bool MangleReturnType = false;
213 if (FD->getPrimaryTemplate() &&
214 !(isa<CXXConstructorDecl>(FD) || isa<CXXDestructorDecl>(FD) ||
215 isa<CXXConversionDecl>(FD)))
216 MangleReturnType = true;
217 mangleBareFunctionType(FD->getType()->getAsFunctionType(), MangleReturnType);
Douglas Gregor3556bc72009-02-13 00:10:09 +0000218}
219
220static bool isStdNamespace(const DeclContext *DC) {
221 if (!DC->isNamespace() || !DC->getParent()->isTranslationUnit())
222 return false;
223
224 const NamespaceDecl *NS = cast<NamespaceDecl>(DC);
Douglas Gregor3c3c4542009-02-18 23:53:56 +0000225 return NS->getOriginalNamespace()->getIdentifier()->isStr("std");
Douglas Gregor3556bc72009-02-13 00:10:09 +0000226}
227
228void CXXNameMangler::mangleName(const NamedDecl *ND) {
229 // <name> ::= <nested-name>
230 // ::= <unscoped-name>
231 // ::= <unscoped-template-name> <template-args>
232 // ::= <local-name> # See Scope Encoding below
233 //
234 // <unscoped-name> ::= <unqualified-name>
235 // ::= St <unqualified-name> # ::std::
236 if (ND->getDeclContext()->isTranslationUnit())
237 mangleUnqualifiedName(ND);
238 else if (isStdNamespace(ND->getDeclContext())) {
239 Out << "St";
240 mangleUnqualifiedName(ND);
Anders Carlssonfd8c56b2009-04-02 16:24:45 +0000241 } else if (isa<FunctionDecl>(ND->getDeclContext()))
242 mangleLocalName(ND);
243 else
Douglas Gregor3556bc72009-02-13 00:10:09 +0000244 mangleNestedName(ND);
Douglas Gregor3556bc72009-02-13 00:10:09 +0000245}
246
Mike Stump58256412009-09-05 07:20:32 +0000247void CXXNameMangler::mangleCalloffset(int64_t nv, int64_t v) {
Mike Stumpb29542f2009-09-02 00:25:38 +0000248 // <call-offset> ::= h <nv-offset> _
249 // ::= v <v-offset> _
250 // <nv-offset> ::= <offset number> # non-virtual base override
251 // <v-offset> ::= <offset nubmer> _ <virtual offset number>
252 // # virtual base override, with vcall offset
Mike Stump58256412009-09-05 07:20:32 +0000253 if (v == 0) {
Mike Stump28db39b2009-09-02 00:56:18 +0000254 Out << "h";
Mike Stumpb29542f2009-09-02 00:25:38 +0000255 if (nv < 0) {
256 Out << "n";
257 nv = -nv;
258 }
259 Out << nv;
260 } else {
Mike Stump28db39b2009-09-02 00:56:18 +0000261 Out << "v";
Mike Stumpb29542f2009-09-02 00:25:38 +0000262 if (nv < 0) {
263 Out << "n";
264 nv = -nv;
265 }
266 Out << nv;
267 Out << "_";
268 if (v < 0) {
269 Out << "n";
270 v = -v;
271 }
272 Out << v;
273 }
274 Out << "_";
Mike Stump28db39b2009-09-02 00:56:18 +0000275}
276
Mike Stumpbb3126c2009-09-07 04:27:52 +0000277void CXXNameMangler::mangleThunk(const FunctionDecl *FD, int64_t nv,
278 int64_t v) {
Mike Stump28db39b2009-09-02 00:56:18 +0000279 // <special-name> ::= T <call-offset> <base encoding>
280 // # base is the nominal target function of thunk
Mike Stumpbb3126c2009-09-07 04:27:52 +0000281 Out << "_ZT";
Mike Stump58256412009-09-05 07:20:32 +0000282 mangleCalloffset(nv, v);
Mike Stumpbb3126c2009-09-07 04:27:52 +0000283 mangleFunctionEncoding(FD);
Mike Stump28db39b2009-09-02 00:56:18 +0000284}
285
Mike Stumpbb3126c2009-09-07 04:27:52 +0000286 void CXXNameMangler::mangleCovariantThunk(const FunctionDecl *FD,
Mike Stump58256412009-09-05 07:20:32 +0000287 int64_t nv_t, int64_t v_t,
Mike Stump28db39b2009-09-02 00:56:18 +0000288 int64_t nv_r, int64_t v_r) {
289 // <special-name> ::= Tc <call-offset> <call-offset> <base encoding>
290 // # base is the nominal target function of thunk
291 // # first call-offset is 'this' adjustment
292 // # second call-offset is result adjustment
Mike Stumpbb3126c2009-09-07 04:27:52 +0000293 Out << "_ZTc";
Mike Stump58256412009-09-05 07:20:32 +0000294 mangleCalloffset(nv_t, v_t);
295 mangleCalloffset(nv_r, v_r);
Mike Stumpbb3126c2009-09-07 04:27:52 +0000296 mangleFunctionEncoding(FD);
Mike Stumpb29542f2009-09-02 00:25:38 +0000297}
298
Douglas Gregor3556bc72009-02-13 00:10:09 +0000299void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND) {
300 // <unqualified-name> ::= <operator-name>
301 // ::= <ctor-dtor-name>
302 // ::= <source-name>
303 DeclarationName Name = ND->getDeclName();
304 switch (Name.getNameKind()) {
305 case DeclarationName::Identifier:
306 mangleSourceName(Name.getAsIdentifierInfo());
307 break;
308
309 case DeclarationName::ObjCZeroArgSelector:
310 case DeclarationName::ObjCOneArgSelector:
311 case DeclarationName::ObjCMultiArgSelector:
312 assert(false && "Can't mangle Objective-C selector names here!");
313 break;
314
315 case DeclarationName::CXXConstructorName:
Anders Carlsson4811c302009-04-17 01:58:57 +0000316 if (ND == Structor)
Mike Stumpb29542f2009-09-02 00:25:38 +0000317 // If the named decl is the C++ constructor we're mangling, use the type
318 // we were given.
Anders Carlsson4811c302009-04-17 01:58:57 +0000319 mangleCXXCtorType(static_cast<CXXCtorType>(StructorType));
Anders Carlsson6b6adf22009-04-15 05:36:58 +0000320 else
321 // Otherwise, use the complete constructor name. This is relevant if a
322 // class with a constructor is declared within a constructor.
323 mangleCXXCtorType(Ctor_Complete);
Douglas Gregor3556bc72009-02-13 00:10:09 +0000324 break;
325
326 case DeclarationName::CXXDestructorName:
Anders Carlsson4811c302009-04-17 01:58:57 +0000327 if (ND == Structor)
Mike Stumpb29542f2009-09-02 00:25:38 +0000328 // If the named decl is the C++ destructor we're mangling, use the type we
329 // were given.
Anders Carlsson4811c302009-04-17 01:58:57 +0000330 mangleCXXDtorType(static_cast<CXXDtorType>(StructorType));
331 else
332 // Otherwise, use the complete destructor name. This is relevant if a
333 // class with a destructor is declared within a destructor.
334 mangleCXXDtorType(Dtor_Complete);
Douglas Gregor3556bc72009-02-13 00:10:09 +0000335 break;
336
337 case DeclarationName::CXXConversionFunctionName:
Douglas Gregor77cfb3c2009-02-13 01:28:03 +0000338 // <operator-name> ::= cv <type> # (cast)
339 Out << "cv";
340 mangleType(Context.getCanonicalType(Name.getCXXNameType()));
Douglas Gregor3556bc72009-02-13 00:10:09 +0000341 break;
342
343 case DeclarationName::CXXOperatorName:
344 mangleOperatorName(Name.getCXXOverloadedOperator(),
345 cast<FunctionDecl>(ND)->getNumParams());
346 break;
347
348 case DeclarationName::CXXUsingDirective:
349 assert(false && "Can't mangle a using directive name!");
Douglas Gregor77cfb3c2009-02-13 01:28:03 +0000350 break;
Douglas Gregor3556bc72009-02-13 00:10:09 +0000351 }
Douglas Gregor69678062009-06-29 22:39:32 +0000352
353 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(ND)) {
354 if (const TemplateArgumentList *TemplateArgs
355 = Function->getTemplateSpecializationArgs())
356 mangleTemplateArgumentList(*TemplateArgs);
357 }
Douglas Gregor3556bc72009-02-13 00:10:09 +0000358}
359
360void CXXNameMangler::mangleSourceName(const IdentifierInfo *II) {
361 // <source-name> ::= <positive length number> <identifier>
362 // <number> ::= [n] <non-negative decimal integer>
363 // <identifier> ::= <unqualified source code identifier>
364 Out << II->getLength() << II->getName();
365}
366
367void CXXNameMangler::mangleNestedName(const NamedDecl *ND) {
368 // <nested-name> ::= N [<CV-qualifiers>] <prefix> <unqualified-name> E
369 // ::= N [<CV-qualifiers>] <template-prefix> <template-args> E
370 // FIXME: no template support
371 Out << 'N';
372 if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(ND))
373 mangleCVQualifiers(Method->getTypeQualifiers());
374 manglePrefix(ND->getDeclContext());
375 mangleUnqualifiedName(ND);
376 Out << 'E';
377}
378
Anders Carlssonfd8c56b2009-04-02 16:24:45 +0000379void CXXNameMangler::mangleLocalName(const NamedDecl *ND) {
380 // <local-name> := Z <function encoding> E <entity name> [<discriminator>]
381 // := Z <function encoding> E s [<discriminator>]
382 // <discriminator> := _ <non-negative number>
383 Out << 'Z';
384 mangleFunctionEncoding(cast<FunctionDecl>(ND->getDeclContext()));
385 Out << 'E';
386 mangleSourceName(ND->getIdentifier());
387}
388
Douglas Gregor3556bc72009-02-13 00:10:09 +0000389void CXXNameMangler::manglePrefix(const DeclContext *DC) {
390 // <prefix> ::= <prefix> <unqualified-name>
391 // ::= <template-prefix> <template-args>
392 // ::= <template-param>
393 // ::= # empty
394 // ::= <substitution>
395 // FIXME: We only handle mangling of namespaces and classes at the moment.
Anders Carlsson8c4c12a2009-04-01 00:42:16 +0000396 if (!DC->getParent()->isTranslationUnit())
397 manglePrefix(DC->getParent());
Douglas Gregor3556bc72009-02-13 00:10:09 +0000398
399 if (const NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(DC))
400 mangleSourceName(Namespace->getIdentifier());
Anders Carlssonb1008e42009-05-15 16:09:15 +0000401 else if (const RecordDecl *Record = dyn_cast<RecordDecl>(DC)) {
402 if (const ClassTemplateSpecializationDecl *D =
403 dyn_cast<ClassTemplateSpecializationDecl>(Record)) {
404 mangleType(QualType(D->getTypeForDecl(), 0));
405 } else
406 mangleSourceName(Record->getIdentifier());
407 }
Douglas Gregor3556bc72009-02-13 00:10:09 +0000408}
409
410void
411CXXNameMangler::mangleOperatorName(OverloadedOperatorKind OO, unsigned Arity) {
412 switch (OO) {
Sebastian Redlbd261962009-04-16 17:51:27 +0000413 // <operator-name> ::= nw # new
Douglas Gregor3556bc72009-02-13 00:10:09 +0000414 case OO_New: Out << "nw"; break;
415 // ::= na # new[]
416 case OO_Array_New: Out << "na"; break;
Sebastian Redlbd261962009-04-16 17:51:27 +0000417 // ::= dl # delete
Douglas Gregor3556bc72009-02-13 00:10:09 +0000418 case OO_Delete: Out << "dl"; break;
Sebastian Redlbd261962009-04-16 17:51:27 +0000419 // ::= da # delete[]
Douglas Gregor3556bc72009-02-13 00:10:09 +0000420 case OO_Array_Delete: Out << "da"; break;
421 // ::= ps # + (unary)
422 // ::= pl # +
423 case OO_Plus: Out << (Arity == 1? "ps" : "pl"); break;
Sebastian Redlbd261962009-04-16 17:51:27 +0000424 // ::= ng # - (unary)
425 // ::= mi # -
Douglas Gregor3556bc72009-02-13 00:10:09 +0000426 case OO_Minus: Out << (Arity == 1? "ng" : "mi"); break;
Sebastian Redlbd261962009-04-16 17:51:27 +0000427 // ::= ad # & (unary)
428 // ::= an # &
Douglas Gregor3556bc72009-02-13 00:10:09 +0000429 case OO_Amp: Out << (Arity == 1? "ad" : "an"); break;
Sebastian Redlbd261962009-04-16 17:51:27 +0000430 // ::= de # * (unary)
431 // ::= ml # *
Douglas Gregor3556bc72009-02-13 00:10:09 +0000432 case OO_Star: Out << (Arity == 1? "de" : "ml"); break;
Sebastian Redlbd261962009-04-16 17:51:27 +0000433 // ::= co # ~
Douglas Gregor3556bc72009-02-13 00:10:09 +0000434 case OO_Tilde: Out << "co"; break;
Sebastian Redlbd261962009-04-16 17:51:27 +0000435 // ::= dv # /
Douglas Gregor3556bc72009-02-13 00:10:09 +0000436 case OO_Slash: Out << "dv"; break;
Sebastian Redlbd261962009-04-16 17:51:27 +0000437 // ::= rm # %
Douglas Gregor3556bc72009-02-13 00:10:09 +0000438 case OO_Percent: Out << "rm"; break;
Sebastian Redlbd261962009-04-16 17:51:27 +0000439 // ::= or # |
440 case OO_Pipe: Out << "or"; break;
441 // ::= eo # ^
Douglas Gregor3556bc72009-02-13 00:10:09 +0000442 case OO_Caret: Out << "eo"; break;
Sebastian Redlbd261962009-04-16 17:51:27 +0000443 // ::= aS # =
Douglas Gregor3556bc72009-02-13 00:10:09 +0000444 case OO_Equal: Out << "aS"; break;
Sebastian Redlbd261962009-04-16 17:51:27 +0000445 // ::= pL # +=
Douglas Gregor3556bc72009-02-13 00:10:09 +0000446 case OO_PlusEqual: Out << "pL"; break;
Sebastian Redlbd261962009-04-16 17:51:27 +0000447 // ::= mI # -=
Douglas Gregor3556bc72009-02-13 00:10:09 +0000448 case OO_MinusEqual: Out << "mI"; break;
Sebastian Redlbd261962009-04-16 17:51:27 +0000449 // ::= mL # *=
Douglas Gregor3556bc72009-02-13 00:10:09 +0000450 case OO_StarEqual: Out << "mL"; break;
Sebastian Redlbd261962009-04-16 17:51:27 +0000451 // ::= dV # /=
Douglas Gregor3556bc72009-02-13 00:10:09 +0000452 case OO_SlashEqual: Out << "dV"; break;
Sebastian Redlbd261962009-04-16 17:51:27 +0000453 // ::= rM # %=
454 case OO_PercentEqual: Out << "rM"; break;
455 // ::= aN # &=
456 case OO_AmpEqual: Out << "aN"; break;
457 // ::= oR # |=
458 case OO_PipeEqual: Out << "oR"; break;
459 // ::= eO # ^=
460 case OO_CaretEqual: Out << "eO"; break;
461 // ::= ls # <<
Douglas Gregor3556bc72009-02-13 00:10:09 +0000462 case OO_LessLess: Out << "ls"; break;
Sebastian Redlbd261962009-04-16 17:51:27 +0000463 // ::= rs # >>
464 case OO_GreaterGreater: Out << "rs"; break;
465 // ::= lS # <<=
466 case OO_LessLessEqual: Out << "lS"; break;
467 // ::= rS # >>=
468 case OO_GreaterGreaterEqual: Out << "rS"; break;
Douglas Gregor3556bc72009-02-13 00:10:09 +0000469 // ::= eq # ==
470 case OO_EqualEqual: Out << "eq"; break;
Sebastian Redlbd261962009-04-16 17:51:27 +0000471 // ::= ne # !=
472 case OO_ExclaimEqual: Out << "ne"; break;
473 // ::= lt # <
Douglas Gregor3556bc72009-02-13 00:10:09 +0000474 case OO_Less: Out << "lt"; break;
Sebastian Redlbd261962009-04-16 17:51:27 +0000475 // ::= gt # >
Douglas Gregor3556bc72009-02-13 00:10:09 +0000476 case OO_Greater: Out << "gt"; break;
Sebastian Redlbd261962009-04-16 17:51:27 +0000477 // ::= le # <=
Douglas Gregor3556bc72009-02-13 00:10:09 +0000478 case OO_LessEqual: Out << "le"; break;
Sebastian Redlbd261962009-04-16 17:51:27 +0000479 // ::= ge # >=
Douglas Gregor3556bc72009-02-13 00:10:09 +0000480 case OO_GreaterEqual: Out << "ge"; break;
Sebastian Redlbd261962009-04-16 17:51:27 +0000481 // ::= nt # !
Douglas Gregor3556bc72009-02-13 00:10:09 +0000482 case OO_Exclaim: Out << "nt"; break;
Sebastian Redlbd261962009-04-16 17:51:27 +0000483 // ::= aa # &&
Douglas Gregor3556bc72009-02-13 00:10:09 +0000484 case OO_AmpAmp: Out << "aa"; break;
Sebastian Redlbd261962009-04-16 17:51:27 +0000485 // ::= oo # ||
486 case OO_PipePipe: Out << "oo"; break;
487 // ::= pp # ++
488 case OO_PlusPlus: Out << "pp"; break;
489 // ::= mm # --
Douglas Gregor3556bc72009-02-13 00:10:09 +0000490 case OO_MinusMinus: Out << "mm"; break;
Sebastian Redlbd261962009-04-16 17:51:27 +0000491 // ::= cm # ,
492 case OO_Comma: Out << "cm"; break;
493 // ::= pm # ->*
Douglas Gregor3556bc72009-02-13 00:10:09 +0000494 case OO_ArrowStar: Out << "pm"; break;
Sebastian Redlbd261962009-04-16 17:51:27 +0000495 // ::= pt # ->
Douglas Gregor3556bc72009-02-13 00:10:09 +0000496 case OO_Arrow: Out << "pt"; break;
Sebastian Redlbd261962009-04-16 17:51:27 +0000497 // ::= cl # ()
Douglas Gregor3556bc72009-02-13 00:10:09 +0000498 case OO_Call: Out << "cl"; break;
Sebastian Redlbd261962009-04-16 17:51:27 +0000499 // ::= ix # []
Douglas Gregor3556bc72009-02-13 00:10:09 +0000500 case OO_Subscript: Out << "ix"; break;
501 // UNSUPPORTED: ::= qu # ?
502
Sebastian Redlbd261962009-04-16 17:51:27 +0000503 case OO_None:
504 case OO_Conditional:
Douglas Gregor3556bc72009-02-13 00:10:09 +0000505 case NUM_OVERLOADED_OPERATORS:
Douglas Gregor3c3c4542009-02-18 23:53:56 +0000506 assert(false && "Not an overloaded operator");
Douglas Gregor3556bc72009-02-13 00:10:09 +0000507 break;
508 }
509}
510
511void CXXNameMangler::mangleCVQualifiers(unsigned Quals) {
512 // <CV-qualifiers> ::= [r] [V] [K] # restrict (C99), volatile, const
513 if (Quals & QualType::Restrict)
514 Out << 'r';
515 if (Quals & QualType::Volatile)
516 Out << 'V';
517 if (Quals & QualType::Const)
518 Out << 'K';
519}
520
521void CXXNameMangler::mangleType(QualType T) {
Anders Carlssonfdaed4c2009-03-10 17:07:44 +0000522 // Only operate on the canonical type!
523 T = Context.getCanonicalType(T);
524
Douglas Gregor3556bc72009-02-13 00:10:09 +0000525 // <type> ::= <CV-qualifiers> <type>
526 mangleCVQualifiers(T.getCVRQualifiers());
527
John McCallb16b5472009-09-05 07:56:18 +0000528 switch (T->getTypeClass()) {
529#define ABSTRACT_TYPE(CLASS, PARENT)
530#define NON_CANONICAL_TYPE(CLASS, PARENT) \
531 case Type::CLASS: \
532 llvm::llvm_unreachable("can't mangle non-canonical type " #CLASS "Type"); \
533 return;
534#define TYPE(CLASS, PARENT) \
535 case Type::CLASS: \
536 return mangleType(static_cast<CLASS##Type*>(T.getTypePtr()));
537#include "clang/AST/TypeNodes.def"
Douglas Gregor3556bc72009-02-13 00:10:09 +0000538 }
Douglas Gregor3556bc72009-02-13 00:10:09 +0000539}
540
541void CXXNameMangler::mangleType(const BuiltinType *T) {
John McCallb16b5472009-09-05 07:56:18 +0000542 // <type> ::= <builtin-type>
Douglas Gregor3556bc72009-02-13 00:10:09 +0000543 // <builtin-type> ::= v # void
544 // ::= w # wchar_t
545 // ::= b # bool
546 // ::= c # char
547 // ::= a # signed char
548 // ::= h # unsigned char
549 // ::= s # short
550 // ::= t # unsigned short
551 // ::= i # int
552 // ::= j # unsigned int
553 // ::= l # long
554 // ::= m # unsigned long
555 // ::= x # long long, __int64
556 // ::= y # unsigned long long, __int64
557 // ::= n # __int128
558 // UNSUPPORTED: ::= o # unsigned __int128
559 // ::= f # float
560 // ::= d # double
561 // ::= e # long double, __float80
562 // UNSUPPORTED: ::= g # __float128
Douglas Gregor3556bc72009-02-13 00:10:09 +0000563 // UNSUPPORTED: ::= Dd # IEEE 754r decimal floating point (64 bits)
564 // UNSUPPORTED: ::= De # IEEE 754r decimal floating point (128 bits)
565 // UNSUPPORTED: ::= Df # IEEE 754r decimal floating point (32 bits)
566 // UNSUPPORTED: ::= Dh # IEEE 754r half-precision floating point (16 bits)
Alisdair Meredith2bcacb62009-07-14 06:30:34 +0000567 // ::= Di # char32_t
568 // ::= Ds # char16_t
Douglas Gregor3556bc72009-02-13 00:10:09 +0000569 // ::= u <source-name> # vendor extended type
Sebastian Redl5d0ead72009-05-10 18:38:11 +0000570 // From our point of view, std::nullptr_t is a builtin, but as far as mangling
571 // is concerned, it's a type called std::nullptr_t.
Douglas Gregor3556bc72009-02-13 00:10:09 +0000572 switch (T->getKind()) {
573 case BuiltinType::Void: Out << 'v'; break;
574 case BuiltinType::Bool: Out << 'b'; break;
575 case BuiltinType::Char_U: case BuiltinType::Char_S: Out << 'c'; break;
576 case BuiltinType::UChar: Out << 'h'; break;
577 case BuiltinType::UShort: Out << 't'; break;
578 case BuiltinType::UInt: Out << 'j'; break;
579 case BuiltinType::ULong: Out << 'm'; break;
580 case BuiltinType::ULongLong: Out << 'y'; break;
Chris Lattner6cc7e412009-04-30 02:43:43 +0000581 case BuiltinType::UInt128: Out << 'o'; break;
Douglas Gregor3556bc72009-02-13 00:10:09 +0000582 case BuiltinType::SChar: Out << 'a'; break;
583 case BuiltinType::WChar: Out << 'w'; break;
Alisdair Meredith2bcacb62009-07-14 06:30:34 +0000584 case BuiltinType::Char16: Out << "Ds"; break;
585 case BuiltinType::Char32: Out << "Di"; break;
Douglas Gregor3556bc72009-02-13 00:10:09 +0000586 case BuiltinType::Short: Out << 's'; break;
587 case BuiltinType::Int: Out << 'i'; break;
588 case BuiltinType::Long: Out << 'l'; break;
589 case BuiltinType::LongLong: Out << 'x'; break;
Chris Lattner6cc7e412009-04-30 02:43:43 +0000590 case BuiltinType::Int128: Out << 'n'; break;
Douglas Gregor3556bc72009-02-13 00:10:09 +0000591 case BuiltinType::Float: Out << 'f'; break;
592 case BuiltinType::Double: Out << 'd'; break;
593 case BuiltinType::LongDouble: Out << 'e'; break;
Sebastian Redl5d0ead72009-05-10 18:38:11 +0000594 case BuiltinType::NullPtr: Out << "St9nullptr_t"; break;
Douglas Gregor3556bc72009-02-13 00:10:09 +0000595
596 case BuiltinType::Overload:
597 case BuiltinType::Dependent:
598 assert(false &&
599 "Overloaded and dependent types shouldn't get to name mangling");
600 break;
Anders Carlsson4a8498c2009-06-26 18:41:36 +0000601 case BuiltinType::UndeducedAuto:
602 assert(0 && "Should not see undeduced auto here");
603 break;
Steve Naroff0b60cf82009-07-22 17:14:51 +0000604 case BuiltinType::ObjCId: Out << "11objc_object"; break;
605 case BuiltinType::ObjCClass: Out << "10objc_class"; break;
Douglas Gregor3556bc72009-02-13 00:10:09 +0000606 }
607}
608
John McCallb16b5472009-09-05 07:56:18 +0000609// <type> ::= <function-type>
610// <function-type> ::= F [Y] <bare-function-type> E
611void CXXNameMangler::mangleType(const FunctionProtoType *T) {
Douglas Gregor3556bc72009-02-13 00:10:09 +0000612 Out << 'F';
Mike Stumpba2cb0e2009-05-16 07:57:57 +0000613 // FIXME: We don't have enough information in the AST to produce the 'Y'
614 // encoding for extern "C" function types.
Douglas Gregor3556bc72009-02-13 00:10:09 +0000615 mangleBareFunctionType(T, /*MangleReturnType=*/true);
616 Out << 'E';
617}
John McCallb16b5472009-09-05 07:56:18 +0000618void CXXNameMangler::mangleType(const FunctionNoProtoType *T) {
619 llvm::llvm_unreachable("Can't mangle K&R function prototypes");
620}
Douglas Gregor3556bc72009-02-13 00:10:09 +0000621void CXXNameMangler::mangleBareFunctionType(const FunctionType *T,
622 bool MangleReturnType) {
John McCallb16b5472009-09-05 07:56:18 +0000623 // We should never be mangling something without a prototype.
624 const FunctionProtoType *Proto = cast<FunctionProtoType>(T);
625
Douglas Gregor3556bc72009-02-13 00:10:09 +0000626 // <bare-function-type> ::= <signature type>+
627 if (MangleReturnType)
John McCallb16b5472009-09-05 07:56:18 +0000628 mangleType(Proto->getResultType());
Douglas Gregor3556bc72009-02-13 00:10:09 +0000629
Anders Carlsson51e65522009-04-01 00:15:23 +0000630 if (Proto->getNumArgs() == 0) {
631 Out << 'v';
632 return;
633 }
John McCallb16b5472009-09-05 07:56:18 +0000634
Douglas Gregor4fa58902009-02-26 23:50:07 +0000635 for (FunctionProtoType::arg_type_iterator Arg = Proto->arg_type_begin(),
Douglas Gregor3556bc72009-02-13 00:10:09 +0000636 ArgEnd = Proto->arg_type_end();
637 Arg != ArgEnd; ++Arg)
638 mangleType(*Arg);
Douglas Gregor77cfb3c2009-02-13 01:28:03 +0000639
640 // <builtin-type> ::= z # ellipsis
641 if (Proto->isVariadic())
642 Out << 'z';
Douglas Gregor3556bc72009-02-13 00:10:09 +0000643}
644
John McCallb16b5472009-09-05 07:56:18 +0000645// <type> ::= <class-enum-type>
646// <class-enum-type> ::= <name>
647void CXXNameMangler::mangleType(const EnumType *T) {
648 mangleType(static_cast<const TagType*>(T));
649}
650void CXXNameMangler::mangleType(const RecordType *T) {
651 mangleType(static_cast<const TagType*>(T));
652}
Douglas Gregor3556bc72009-02-13 00:10:09 +0000653void CXXNameMangler::mangleType(const TagType *T) {
Anders Carlssonfdaed4c2009-03-10 17:07:44 +0000654 if (!T->getDecl()->getIdentifier())
655 mangleName(T->getDecl()->getTypedefForAnonDecl());
656 else
657 mangleName(T->getDecl());
Anders Carlssonb1008e42009-05-15 16:09:15 +0000658
Mike Stumpb29542f2009-09-02 00:25:38 +0000659 // If this is a class template specialization, mangle the template arguments.
Anders Carlssonb1008e42009-05-15 16:09:15 +0000660 if (ClassTemplateSpecializationDecl *Spec
661 = dyn_cast<ClassTemplateSpecializationDecl>(T->getDecl()))
662 mangleTemplateArgumentList(Spec->getTemplateArgs());
Douglas Gregor3556bc72009-02-13 00:10:09 +0000663}
664
John McCallb16b5472009-09-05 07:56:18 +0000665// <type> ::= <array-type>
666// <array-type> ::= A <positive dimension number> _ <element type>
667// ::= A [<dimension expression>] _ <element type>
668void CXXNameMangler::mangleType(const ConstantArrayType *T) {
669 Out << 'A' << T->getSize() << '_';
670 mangleType(T->getElementType());
671}
672void CXXNameMangler::mangleType(const VariableArrayType *T) {
Douglas Gregor3556bc72009-02-13 00:10:09 +0000673 Out << 'A';
John McCallb16b5472009-09-05 07:56:18 +0000674 mangleExpression(T->getSizeExpr());
Douglas Gregor3556bc72009-02-13 00:10:09 +0000675 Out << '_';
676 mangleType(T->getElementType());
677}
John McCallb16b5472009-09-05 07:56:18 +0000678void CXXNameMangler::mangleType(const DependentSizedArrayType *T) {
679 Out << 'A';
680 mangleExpression(T->getSizeExpr());
681 Out << '_';
682 mangleType(T->getElementType());
683}
684void CXXNameMangler::mangleType(const IncompleteArrayType *T) {
685 Out << 'A' << '_';
686 mangleType(T->getElementType());
687}
Douglas Gregor3556bc72009-02-13 00:10:09 +0000688
John McCallb16b5472009-09-05 07:56:18 +0000689// <type> ::= <pointer-to-member-type>
690// <pointer-to-member-type> ::= M <class type> <member type>
Douglas Gregor3556bc72009-02-13 00:10:09 +0000691void CXXNameMangler::mangleType(const MemberPointerType *T) {
Douglas Gregor3556bc72009-02-13 00:10:09 +0000692 Out << 'M';
693 mangleType(QualType(T->getClass(), 0));
Anders Carlsson0b17ef42009-05-17 17:41:20 +0000694 QualType PointeeType = T->getPointeeType();
695 if (const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(PointeeType)) {
696 mangleCVQualifiers(FPT->getTypeQuals());
697 mangleType(FPT);
698 } else
699 mangleType(PointeeType);
Douglas Gregor3556bc72009-02-13 00:10:09 +0000700}
701
John McCallb16b5472009-09-05 07:56:18 +0000702// <type> ::= <template-param>
703// <template-param> ::= T_ # first template parameter
704// ::= T <parameter-2 non-negative number> _
Douglas Gregor3556bc72009-02-13 00:10:09 +0000705void CXXNameMangler::mangleType(const TemplateTypeParmType *T) {
Douglas Gregor3556bc72009-02-13 00:10:09 +0000706 if (T->getIndex() == 0)
707 Out << "T_";
708 else
709 Out << 'T' << (T->getIndex() - 1) << '_';
710}
711
John McCallb16b5472009-09-05 07:56:18 +0000712// FIXME: <type> ::= <template-template-param> <template-args>
713// FIXME: <type> ::= <substitution> # See Compression below
714
715// <type> ::= P <type> # pointer-to
716void CXXNameMangler::mangleType(const PointerType *T) {
717 Out << 'P';
718 mangleType(T->getPointeeType());
719}
720void CXXNameMangler::mangleType(const ObjCObjectPointerType *T) {
721 Out << 'P';
722 mangleType(T->getPointeeType());
723}
724
725// <type> ::= R <type> # reference-to
726void CXXNameMangler::mangleType(const LValueReferenceType *T) {
727 Out << 'R';
728 mangleType(T->getPointeeType());
729}
730
731// <type> ::= O <type> # rvalue reference-to (C++0x)
732void CXXNameMangler::mangleType(const RValueReferenceType *T) {
733 Out << 'O';
734 mangleType(T->getPointeeType());
735}
736
737// <type> ::= C <type> # complex pair (C 2000)
738void CXXNameMangler::mangleType(const ComplexType *T) {
739 Out << 'C';
740 mangleType(T->getElementType());
741}
742
743// GNU extension: vector types
744void CXXNameMangler::mangleType(const VectorType *T) {
745 Out << "U8__vector";
746 mangleType(T->getElementType());
747}
748void CXXNameMangler::mangleType(const ExtVectorType *T) {
749 mangleType(static_cast<const VectorType*>(T));
750}
751void CXXNameMangler::mangleType(const DependentSizedExtVectorType *T) {
752 Out << "U8__vector";
753 mangleType(T->getElementType());
754}
755
Anders Carlssonfae45862009-03-07 22:03:21 +0000756void CXXNameMangler::mangleType(const ObjCInterfaceType *T) {
757 mangleSourceName(T->getDecl()->getIdentifier());
758}
759
John McCallb16b5472009-09-05 07:56:18 +0000760void CXXNameMangler::mangleType(const BlockPointerType *T) {
761 assert(false && "can't mangle block pointer types yet");
762}
763
764void CXXNameMangler::mangleType(const FixedWidthIntType *T) {
765 assert(false && "can't mangle arbitary-precision integer type yet");
766}
767
768void CXXNameMangler::mangleType(const TemplateSpecializationType *T) {
769 // TSTs are never canonical unless they're dependent.
770 assert(false && "can't mangle dependent template specializations yet");
771}
772
773void CXXNameMangler::mangleType(const TypenameType *T) {
774 assert(false && "can't mangle dependent typenames yet");
775}
776
777// FIXME: For now, just drop all extension qualifiers on the floor.
778void CXXNameMangler::mangleType(const ExtQualType *T) {
779 mangleType(QualType(T->getBaseType(), 0));
780}
781
Douglas Gregor3556bc72009-02-13 00:10:09 +0000782void CXXNameMangler::mangleExpression(Expr *E) {
783 assert(false && "Cannot mangle expressions yet");
784}
785
John McCallb16b5472009-09-05 07:56:18 +0000786// FIXME: <type> ::= G <type> # imaginary (C 2000)
787// FIXME: <type> ::= U <source-name> <type> # vendor extended type qualifier
788
Anders Carlsson6b6adf22009-04-15 05:36:58 +0000789void CXXNameMangler::mangleCXXCtorType(CXXCtorType T) {
790 // <ctor-dtor-name> ::= C1 # complete object constructor
791 // ::= C2 # base object constructor
792 // ::= C3 # complete object allocating constructor
793 //
794 switch (T) {
795 case Ctor_Complete:
796 Out << "C1";
797 break;
798 case Ctor_Base:
799 Out << "C2";
800 break;
801 case Ctor_CompleteAllocating:
802 Out << "C3";
803 break;
804 }
805}
806
Anders Carlsson4811c302009-04-17 01:58:57 +0000807void CXXNameMangler::mangleCXXDtorType(CXXDtorType T) {
808 // <ctor-dtor-name> ::= D0 # deleting destructor
809 // ::= D1 # complete object destructor
810 // ::= D2 # base object destructor
811 //
812 switch (T) {
813 case Dtor_Deleting:
814 Out << "D0";
815 break;
816 case Dtor_Complete:
817 Out << "D1";
818 break;
819 case Dtor_Base:
820 Out << "D2";
821 break;
822 }
823}
824
Anders Carlssonb1008e42009-05-15 16:09:15 +0000825void CXXNameMangler::mangleTemplateArgumentList(const TemplateArgumentList &L) {
826 // <template-args> ::= I <template-arg>+ E
827 Out << "I";
828
829 for (unsigned i = 0, e = L.size(); i != e; ++i) {
830 const TemplateArgument &A = L[i];
831
832 mangleTemplateArgument(A);
833 }
834
835 Out << "E";
836}
837
838void CXXNameMangler::mangleTemplateArgument(const TemplateArgument &A) {
839 // <template-arg> ::= <type> # type or template
840 // ::= X <expression> E # expression
841 // ::= <expr-primary> # simple expressions
842 // ::= I <template-arg>* E # argument pack
843 // ::= sp <expression> # pack expansion of (C++0x)
844 switch (A.getKind()) {
845 default:
846 assert(0 && "Unknown template argument kind!");
847 case TemplateArgument::Type:
848 mangleType(A.getAsType());
849 break;
850 case TemplateArgument::Integral:
851 // <expr-primary> ::= L <type> <value number> E # integer literal
852
853 Out << 'L';
854
855 mangleType(A.getIntegralType());
856
857 const llvm::APSInt *Integral = A.getAsIntegral();
858 if (A.getIntegralType()->isBooleanType()) {
859 // Boolean values are encoded as 0/1.
860 Out << (Integral->getBoolValue() ? '1' : '0');
861 } else {
862 if (Integral->isNegative())
863 Out << 'n';
864 Integral->abs().print(Out, false);
865 }
866
867 Out << 'E';
868 break;
869 }
870}
871
Douglas Gregor3556bc72009-02-13 00:10:09 +0000872namespace clang {
Mike Stumpb29542f2009-09-02 00:25:38 +0000873 /// \brief Mangles the name of the declaration D and emits that name to the
874 /// given output stream.
Douglas Gregor3556bc72009-02-13 00:10:09 +0000875 ///
Mike Stumpb29542f2009-09-02 00:25:38 +0000876 /// If the declaration D requires a mangled name, this routine will emit that
877 /// mangled name to \p os and return true. Otherwise, \p os will be unchanged
878 /// and this routine will return false. In this case, the caller should just
879 /// emit the identifier of the declaration (\c D->getIdentifier()) as its
880 /// name.
Douglas Gregor3556bc72009-02-13 00:10:09 +0000881 bool mangleName(const NamedDecl *D, ASTContext &Context,
882 llvm::raw_ostream &os) {
Anders Carlsson7bb19882009-05-03 16:51:04 +0000883 assert(!isa<CXXConstructorDecl>(D) &&
884 "Use mangleCXXCtor for constructor decls!");
885 assert(!isa<CXXDestructorDecl>(D) &&
886 "Use mangleCXXDtor for destructor decls!");
887
Douglas Gregor3556bc72009-02-13 00:10:09 +0000888 CXXNameMangler Mangler(Context, os);
Douglas Gregor3c3c4542009-02-18 23:53:56 +0000889 if (!Mangler.mangle(D))
890 return false;
891
892 os.flush();
893 return true;
Douglas Gregor3556bc72009-02-13 00:10:09 +0000894 }
Anders Carlsson53f73bc2009-04-13 18:02:10 +0000895
Mike Stumpb29542f2009-09-02 00:25:38 +0000896 /// \brief Mangles the a thunk with the offset n for the declaration D and
897 /// emits that name to the given output stream.
Mike Stumpbb3126c2009-09-07 04:27:52 +0000898 void mangleThunk(const FunctionDecl *FD, int64_t nv, int64_t v,
Mike Stumpeeba4ad2009-09-02 00:28:47 +0000899 ASTContext &Context, llvm::raw_ostream &os) {
Mike Stumpb29542f2009-09-02 00:25:38 +0000900 // FIXME: Hum, we might have to thunk these, fix.
Mike Stumpbb3126c2009-09-07 04:27:52 +0000901 assert(!isa<CXXConstructorDecl>(FD) &&
Mike Stumpb29542f2009-09-02 00:25:38 +0000902 "Use mangleCXXCtor for constructor decls!");
Mike Stumpbb3126c2009-09-07 04:27:52 +0000903 assert(!isa<CXXDestructorDecl>(FD) &&
Mike Stumpb29542f2009-09-02 00:25:38 +0000904 "Use mangleCXXDtor for destructor decls!");
905
906 CXXNameMangler Mangler(Context, os);
Mike Stumpbb3126c2009-09-07 04:27:52 +0000907 Mangler.mangleThunk(FD, nv, v);
Mike Stumpb29542f2009-09-02 00:25:38 +0000908 os.flush();
909 }
910
Mike Stump28db39b2009-09-02 00:56:18 +0000911 /// \brief Mangles the a covariant thunk for the declaration D and emits that
912 /// name to the given output stream.
Mike Stumpbb3126c2009-09-07 04:27:52 +0000913 void mangleCovariantThunk(const FunctionDecl *FD, int64_t nv_t, int64_t v_t,
Mike Stump58256412009-09-05 07:20:32 +0000914 int64_t nv_r, int64_t v_r, ASTContext &Context,
Mike Stump28db39b2009-09-02 00:56:18 +0000915 llvm::raw_ostream &os) {
916 // FIXME: Hum, we might have to thunk these, fix.
Mike Stumpbb3126c2009-09-07 04:27:52 +0000917 assert(!isa<CXXConstructorDecl>(FD) &&
Mike Stump28db39b2009-09-02 00:56:18 +0000918 "Use mangleCXXCtor for constructor decls!");
Mike Stumpbb3126c2009-09-07 04:27:52 +0000919 assert(!isa<CXXDestructorDecl>(FD) &&
Mike Stump28db39b2009-09-02 00:56:18 +0000920 "Use mangleCXXDtor for destructor decls!");
921
922 CXXNameMangler Mangler(Context, os);
Mike Stumpbb3126c2009-09-07 04:27:52 +0000923 Mangler.mangleCovariantThunk(FD, nv_t, v_t, nv_r, v_r);
Mike Stump28db39b2009-09-02 00:56:18 +0000924 os.flush();
925 }
926
Anders Carlsson6b6adf22009-04-15 05:36:58 +0000927 /// mangleGuardVariable - Returns the mangled name for a guard variable
928 /// for the passed in VarDecl.
Anders Carlsson53f73bc2009-04-13 18:02:10 +0000929 void mangleGuardVariable(const VarDecl *D, ASTContext &Context,
930 llvm::raw_ostream &os) {
931 CXXNameMangler Mangler(Context, os);
932 Mangler.mangleGuardVariable(D);
933
934 os.flush();
935 }
Anders Carlsson6b6adf22009-04-15 05:36:58 +0000936
937 void mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type,
938 ASTContext &Context, llvm::raw_ostream &os) {
939 CXXNameMangler Mangler(Context, os);
940 Mangler.mangleCXXCtor(D, Type);
941
942 os.flush();
943 }
Anders Carlsson4811c302009-04-17 01:58:57 +0000944
945 void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type,
946 ASTContext &Context, llvm::raw_ostream &os) {
947 CXXNameMangler Mangler(Context, os);
948 Mangler.mangleCXXDtor(D, Type);
949
950 os.flush();
951 }
Douglas Gregor3556bc72009-02-13 00:10:09 +0000952
Mike Stump7e8c9932009-07-31 18:25:34 +0000953 void mangleCXXVtable(QualType Type, ASTContext &Context,
954 llvm::raw_ostream &os) {
955 CXXNameMangler Mangler(Context, os);
956 Mangler.mangleCXXVtable(Type);
957
958 os.flush();
959 }
Mike Stump00df7d32009-07-31 23:15:31 +0000960
961 void mangleCXXRtti(QualType Type, ASTContext &Context,
962 llvm::raw_ostream &os) {
963 CXXNameMangler Mangler(Context, os);
964 Mangler.mangleCXXRtti(Type);
965
966 os.flush();
967 }
Mike Stump7e8c9932009-07-31 18:25:34 +0000968}