blob: 53a57d7de92cc2492a608c5f1f43aa2f4691d0ff [file] [log] [blame]
Douglas Gregor6ec36682009-02-18 23:53:56 +00001//===--- Mangle.cpp - 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//===----------------------------------------------------------------------===//
17#include "Mangle.h"
18#include "clang/AST/ASTContext.h"
19#include "clang/AST/Decl.h"
20#include "clang/AST/DeclCXX.h"
Anders Carlssona40c5e42009-03-07 22:03:21 +000021#include "clang/AST/DeclObjC.h"
Anders Carlsson7a0ba872009-05-15 16:09:15 +000022#include "clang/AST/DeclTemplate.h"
Douglas Gregor6ec36682009-02-18 23:53:56 +000023#include "clang/Basic/SourceManager.h"
Douglas Gregor5f2bfd42009-02-13 00:10:09 +000024#include "llvm/Support/Compiler.h"
25#include "llvm/Support/raw_ostream.h"
John McCallefe6aee2009-09-05 07:56:18 +000026#include "llvm/Support/ErrorHandling.h"
Douglas Gregor5f2bfd42009-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 Carlsson27ae5362009-04-17 01:58:57 +000034 const CXXMethodDecl *Structor;
35 unsigned StructorType;
Anders Carlsson3ac86b52009-04-15 05:36:58 +000036 CXXCtorType CtorType;
37
Douglas Gregor5f2bfd42009-02-13 00:10:09 +000038 public:
39 CXXNameMangler(ASTContext &C, llvm::raw_ostream &os)
Anders Carlsson27ae5362009-04-17 01:58:57 +000040 : Context(C), Out(os), Structor(0), StructorType(0) { }
Douglas Gregor5f2bfd42009-02-13 00:10:09 +000041
42 bool mangle(const NamedDecl *D);
Mike Stump77ca8f62009-09-05 07:20:32 +000043 void mangleCalloffset(int64_t nv, int64_t v);
44 void mangleThunk(const NamedDecl *ND, int64_t nv, int64_t v);
45 void mangleCovariantThunk(const NamedDecl *ND,
46 int64_t nv_t, int64_t v_t,
Mike Stump9124bcc2009-09-02 00:56:18 +000047 int64_t nv_r, int64_t v_r);
Anders Carlsson41aa8c12009-04-13 18:02:10 +000048 void mangleGuardVariable(const VarDecl *D);
Anders Carlsson27ae5362009-04-17 01:58:57 +000049
Mike Stumpf1216772009-07-31 18:25:34 +000050 void mangleCXXVtable(QualType Type);
Mike Stump738f8c22009-07-31 23:15:31 +000051 void mangleCXXRtti(QualType Type);
Anders Carlsson3ac86b52009-04-15 05:36:58 +000052 void mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type);
Anders Carlsson27ae5362009-04-17 01:58:57 +000053 void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type);
Anders Carlsson3ac86b52009-04-15 05:36:58 +000054
Anders Carlsson43f17402009-04-02 15:51:53 +000055 private:
56 bool mangleFunctionDecl(const FunctionDecl *FD);
57
Douglas Gregor5f2bfd42009-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 Carlsson1b42c792009-04-02 16:24:45 +000062 void mangleLocalName(const NamedDecl *ND);
Douglas Gregor5f2bfd42009-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 McCallefe6aee2009-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 Gregor5f2bfd42009-02-13 00:10:09 +000078 void mangleExpression(Expr *E);
Anders Carlsson3ac86b52009-04-15 05:36:58 +000079 void mangleCXXCtorType(CXXCtorType T);
Anders Carlsson27ae5362009-04-17 01:58:57 +000080 void mangleCXXDtorType(CXXDtorType T);
Anders Carlsson7a0ba872009-05-15 16:09:15 +000081
82 void mangleTemplateArgumentList(const TemplateArgumentList &L);
83 void mangleTemplateArgument(const TemplateArgument &A);
Douglas Gregor5f2bfd42009-02-13 00:10:09 +000084 };
85}
86
Anders Carlsson43f17402009-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 Stump141c5af2009-09-02 00:25:38 +000098 // Clang's "overloadable" attribute extension to C/C++ implies name mangling
99 // (always).
Argyrios Kyrtzidis40b598e2009-06-30 02:34:44 +0000100 if (!FD->hasAttr<OverloadableAttr>()) {
Chris Lattner783601d2009-06-13 23:34:16 +0000101 // C functions are not mangled, and "main" is never mangled.
John McCall07a5c222009-08-15 02:09:25 +0000102 if (!Context.getLangOptions().CPlusPlus || FD->isMain(Context))
Chris Lattner783601d2009-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 Carlsson43f17402009-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 Gregor5f2bfd42009-02-13 00:10:09 +0000120
121bool CXXNameMangler::mangle(const NamedDecl *D) {
Mike Stump141c5af2009-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.
Argyrios Kyrtzidis40b598e2009-06-30 02:34:44 +0000124 if (const AsmLabelAttr *ALA = D->getAttr<AsmLabelAttr>()) {
Chris Lattnerca3f25c2009-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 Gregor5f2bfd42009-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 Carlsson43f17402009-04-02 15:51:53 +0000136 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
137 return mangleFunctionDecl(FD);
Chris Lattnerbc7a0292009-03-21 06:19:20 +0000138
Anders Carlsson329749c2009-04-02 16:05:20 +0000139 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
140 if (!Context.getLangOptions().CPlusPlus ||
Anders Carlsson9ccb0652009-04-11 01:19:45 +0000141 isInCLinkageSpecification(D) ||
142 D->getDeclContext()->isTranslationUnit())
Anders Carlsson329749c2009-04-02 16:05:20 +0000143 return false;
144
145 Out << "_Z";
146 mangleName(VD);
147 return true;
148 }
149
Anders Carlsson43f17402009-04-02 15:51:53 +0000150 return false;
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000151}
152
Anders Carlsson3ac86b52009-04-15 05:36:58 +0000153void CXXNameMangler::mangleCXXCtor(const CXXConstructorDecl *D,
154 CXXCtorType Type) {
Anders Carlsson27ae5362009-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 Carlsson3ac86b52009-04-15 05:36:58 +0000167
168 mangle(D);
169}
170
Mike Stumpf1216772009-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 Stump738f8c22009-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 Carlsson41aa8c12009-04-13 18:02:10 +0000183void CXXNameMangler::mangleGuardVariable(const VarDecl *D)
184{
185 // <special-name> ::= GV <object name> # Guard variable for one-time
Mike Stumpf1216772009-07-31 18:25:34 +0000186 // # initialization
Anders Carlsson41aa8c12009-04-13 18:02:10 +0000187
188 Out << "_ZGV";
189 mangleName(D);
190}
191
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000192void CXXNameMangler::mangleFunctionEncoding(const FunctionDecl *FD) {
193 // <encoding> ::= <function name> <bare-function-type>
194 mangleName(FD);
Douglas Gregor1fd2dd12009-06-29 22:39:32 +0000195
Mike Stump141c5af2009-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 Gregor1fd2dd12009-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 Stump141c5af2009-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 Gregor1fd2dd12009-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 Gregor5f2bfd42009-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 Gregor6ec36682009-02-18 23:53:56 +0000225 return NS->getOriginalNamespace()->getIdentifier()->isStr("std");
Douglas Gregor5f2bfd42009-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 Carlsson1b42c792009-04-02 16:24:45 +0000241 } else if (isa<FunctionDecl>(ND->getDeclContext()))
242 mangleLocalName(ND);
243 else
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000244 mangleNestedName(ND);
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000245}
246
Mike Stump77ca8f62009-09-05 07:20:32 +0000247void CXXNameMangler::mangleCalloffset(int64_t nv, int64_t v) {
Mike Stump141c5af2009-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 Stump77ca8f62009-09-05 07:20:32 +0000253 if (v == 0) {
Mike Stump9124bcc2009-09-02 00:56:18 +0000254 Out << "h";
Mike Stump141c5af2009-09-02 00:25:38 +0000255 if (nv < 0) {
256 Out << "n";
257 nv = -nv;
258 }
259 Out << nv;
260 } else {
Mike Stump9124bcc2009-09-02 00:56:18 +0000261 Out << "v";
Mike Stump141c5af2009-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 Stump9124bcc2009-09-02 00:56:18 +0000275}
276
Mike Stump77ca8f62009-09-05 07:20:32 +0000277void CXXNameMangler::mangleThunk(const NamedDecl *D, int64_t nv, int64_t v) {
Mike Stump9124bcc2009-09-02 00:56:18 +0000278 // <special-name> ::= T <call-offset> <base encoding>
279 // # base is the nominal target function of thunk
280 Out << "_T";
Mike Stump77ca8f62009-09-05 07:20:32 +0000281 mangleCalloffset(nv, v);
Mike Stump9124bcc2009-09-02 00:56:18 +0000282 mangleName(D);
283}
284
285 void CXXNameMangler::mangleCovariantThunk(const NamedDecl *D,
Mike Stump77ca8f62009-09-05 07:20:32 +0000286 int64_t nv_t, int64_t v_t,
Mike Stump9124bcc2009-09-02 00:56:18 +0000287 int64_t nv_r, int64_t v_r) {
288 // <special-name> ::= Tc <call-offset> <call-offset> <base encoding>
289 // # base is the nominal target function of thunk
290 // # first call-offset is 'this' adjustment
291 // # second call-offset is result adjustment
292 Out << "_Tc";
Mike Stump77ca8f62009-09-05 07:20:32 +0000293 mangleCalloffset(nv_t, v_t);
294 mangleCalloffset(nv_r, v_r);
Mike Stump141c5af2009-09-02 00:25:38 +0000295 mangleName(D);
296}
297
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000298void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND) {
299 // <unqualified-name> ::= <operator-name>
300 // ::= <ctor-dtor-name>
301 // ::= <source-name>
302 DeclarationName Name = ND->getDeclName();
303 switch (Name.getNameKind()) {
304 case DeclarationName::Identifier:
305 mangleSourceName(Name.getAsIdentifierInfo());
306 break;
307
308 case DeclarationName::ObjCZeroArgSelector:
309 case DeclarationName::ObjCOneArgSelector:
310 case DeclarationName::ObjCMultiArgSelector:
311 assert(false && "Can't mangle Objective-C selector names here!");
312 break;
313
314 case DeclarationName::CXXConstructorName:
Anders Carlsson27ae5362009-04-17 01:58:57 +0000315 if (ND == Structor)
Mike Stump141c5af2009-09-02 00:25:38 +0000316 // If the named decl is the C++ constructor we're mangling, use the type
317 // we were given.
Anders Carlsson27ae5362009-04-17 01:58:57 +0000318 mangleCXXCtorType(static_cast<CXXCtorType>(StructorType));
Anders Carlsson3ac86b52009-04-15 05:36:58 +0000319 else
320 // Otherwise, use the complete constructor name. This is relevant if a
321 // class with a constructor is declared within a constructor.
322 mangleCXXCtorType(Ctor_Complete);
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000323 break;
324
325 case DeclarationName::CXXDestructorName:
Anders Carlsson27ae5362009-04-17 01:58:57 +0000326 if (ND == Structor)
Mike Stump141c5af2009-09-02 00:25:38 +0000327 // If the named decl is the C++ destructor we're mangling, use the type we
328 // were given.
Anders Carlsson27ae5362009-04-17 01:58:57 +0000329 mangleCXXDtorType(static_cast<CXXDtorType>(StructorType));
330 else
331 // Otherwise, use the complete destructor name. This is relevant if a
332 // class with a destructor is declared within a destructor.
333 mangleCXXDtorType(Dtor_Complete);
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000334 break;
335
336 case DeclarationName::CXXConversionFunctionName:
Douglas Gregor219cc612009-02-13 01:28:03 +0000337 // <operator-name> ::= cv <type> # (cast)
338 Out << "cv";
339 mangleType(Context.getCanonicalType(Name.getCXXNameType()));
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000340 break;
341
342 case DeclarationName::CXXOperatorName:
343 mangleOperatorName(Name.getCXXOverloadedOperator(),
344 cast<FunctionDecl>(ND)->getNumParams());
345 break;
346
347 case DeclarationName::CXXUsingDirective:
348 assert(false && "Can't mangle a using directive name!");
Douglas Gregor219cc612009-02-13 01:28:03 +0000349 break;
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000350 }
Douglas Gregor1fd2dd12009-06-29 22:39:32 +0000351
352 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(ND)) {
353 if (const TemplateArgumentList *TemplateArgs
354 = Function->getTemplateSpecializationArgs())
355 mangleTemplateArgumentList(*TemplateArgs);
356 }
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000357}
358
359void CXXNameMangler::mangleSourceName(const IdentifierInfo *II) {
360 // <source-name> ::= <positive length number> <identifier>
361 // <number> ::= [n] <non-negative decimal integer>
362 // <identifier> ::= <unqualified source code identifier>
363 Out << II->getLength() << II->getName();
364}
365
366void CXXNameMangler::mangleNestedName(const NamedDecl *ND) {
367 // <nested-name> ::= N [<CV-qualifiers>] <prefix> <unqualified-name> E
368 // ::= N [<CV-qualifiers>] <template-prefix> <template-args> E
369 // FIXME: no template support
370 Out << 'N';
371 if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(ND))
372 mangleCVQualifiers(Method->getTypeQualifiers());
373 manglePrefix(ND->getDeclContext());
374 mangleUnqualifiedName(ND);
375 Out << 'E';
376}
377
Anders Carlsson1b42c792009-04-02 16:24:45 +0000378void CXXNameMangler::mangleLocalName(const NamedDecl *ND) {
379 // <local-name> := Z <function encoding> E <entity name> [<discriminator>]
380 // := Z <function encoding> E s [<discriminator>]
381 // <discriminator> := _ <non-negative number>
382 Out << 'Z';
383 mangleFunctionEncoding(cast<FunctionDecl>(ND->getDeclContext()));
384 Out << 'E';
385 mangleSourceName(ND->getIdentifier());
386}
387
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000388void CXXNameMangler::manglePrefix(const DeclContext *DC) {
389 // <prefix> ::= <prefix> <unqualified-name>
390 // ::= <template-prefix> <template-args>
391 // ::= <template-param>
392 // ::= # empty
393 // ::= <substitution>
394 // FIXME: We only handle mangling of namespaces and classes at the moment.
Anders Carlssonc8dee9c2009-04-01 00:42:16 +0000395 if (!DC->getParent()->isTranslationUnit())
396 manglePrefix(DC->getParent());
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000397
398 if (const NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(DC))
399 mangleSourceName(Namespace->getIdentifier());
Anders Carlsson7a0ba872009-05-15 16:09:15 +0000400 else if (const RecordDecl *Record = dyn_cast<RecordDecl>(DC)) {
401 if (const ClassTemplateSpecializationDecl *D =
402 dyn_cast<ClassTemplateSpecializationDecl>(Record)) {
403 mangleType(QualType(D->getTypeForDecl(), 0));
404 } else
405 mangleSourceName(Record->getIdentifier());
406 }
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000407}
408
409void
410CXXNameMangler::mangleOperatorName(OverloadedOperatorKind OO, unsigned Arity) {
411 switch (OO) {
Sebastian Redl3201f6b2009-04-16 17:51:27 +0000412 // <operator-name> ::= nw # new
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000413 case OO_New: Out << "nw"; break;
414 // ::= na # new[]
415 case OO_Array_New: Out << "na"; break;
Sebastian Redl3201f6b2009-04-16 17:51:27 +0000416 // ::= dl # delete
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000417 case OO_Delete: Out << "dl"; break;
Sebastian Redl3201f6b2009-04-16 17:51:27 +0000418 // ::= da # delete[]
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000419 case OO_Array_Delete: Out << "da"; break;
420 // ::= ps # + (unary)
421 // ::= pl # +
422 case OO_Plus: Out << (Arity == 1? "ps" : "pl"); break;
Sebastian Redl3201f6b2009-04-16 17:51:27 +0000423 // ::= ng # - (unary)
424 // ::= mi # -
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000425 case OO_Minus: Out << (Arity == 1? "ng" : "mi"); break;
Sebastian Redl3201f6b2009-04-16 17:51:27 +0000426 // ::= ad # & (unary)
427 // ::= an # &
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000428 case OO_Amp: Out << (Arity == 1? "ad" : "an"); break;
Sebastian Redl3201f6b2009-04-16 17:51:27 +0000429 // ::= de # * (unary)
430 // ::= ml # *
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000431 case OO_Star: Out << (Arity == 1? "de" : "ml"); break;
Sebastian Redl3201f6b2009-04-16 17:51:27 +0000432 // ::= co # ~
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000433 case OO_Tilde: Out << "co"; break;
Sebastian Redl3201f6b2009-04-16 17:51:27 +0000434 // ::= dv # /
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000435 case OO_Slash: Out << "dv"; break;
Sebastian Redl3201f6b2009-04-16 17:51:27 +0000436 // ::= rm # %
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000437 case OO_Percent: Out << "rm"; break;
Sebastian Redl3201f6b2009-04-16 17:51:27 +0000438 // ::= or # |
439 case OO_Pipe: Out << "or"; break;
440 // ::= eo # ^
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000441 case OO_Caret: Out << "eo"; break;
Sebastian Redl3201f6b2009-04-16 17:51:27 +0000442 // ::= aS # =
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000443 case OO_Equal: Out << "aS"; break;
Sebastian Redl3201f6b2009-04-16 17:51:27 +0000444 // ::= pL # +=
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000445 case OO_PlusEqual: Out << "pL"; break;
Sebastian Redl3201f6b2009-04-16 17:51:27 +0000446 // ::= mI # -=
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000447 case OO_MinusEqual: Out << "mI"; break;
Sebastian Redl3201f6b2009-04-16 17:51:27 +0000448 // ::= mL # *=
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000449 case OO_StarEqual: Out << "mL"; break;
Sebastian Redl3201f6b2009-04-16 17:51:27 +0000450 // ::= dV # /=
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000451 case OO_SlashEqual: Out << "dV"; break;
Sebastian Redl3201f6b2009-04-16 17:51:27 +0000452 // ::= rM # %=
453 case OO_PercentEqual: Out << "rM"; break;
454 // ::= aN # &=
455 case OO_AmpEqual: Out << "aN"; break;
456 // ::= oR # |=
457 case OO_PipeEqual: Out << "oR"; break;
458 // ::= eO # ^=
459 case OO_CaretEqual: Out << "eO"; break;
460 // ::= ls # <<
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000461 case OO_LessLess: Out << "ls"; break;
Sebastian Redl3201f6b2009-04-16 17:51:27 +0000462 // ::= rs # >>
463 case OO_GreaterGreater: Out << "rs"; break;
464 // ::= lS # <<=
465 case OO_LessLessEqual: Out << "lS"; break;
466 // ::= rS # >>=
467 case OO_GreaterGreaterEqual: Out << "rS"; break;
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000468 // ::= eq # ==
469 case OO_EqualEqual: Out << "eq"; break;
Sebastian Redl3201f6b2009-04-16 17:51:27 +0000470 // ::= ne # !=
471 case OO_ExclaimEqual: Out << "ne"; break;
472 // ::= lt # <
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000473 case OO_Less: Out << "lt"; break;
Sebastian Redl3201f6b2009-04-16 17:51:27 +0000474 // ::= gt # >
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000475 case OO_Greater: Out << "gt"; break;
Sebastian Redl3201f6b2009-04-16 17:51:27 +0000476 // ::= le # <=
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000477 case OO_LessEqual: Out << "le"; break;
Sebastian Redl3201f6b2009-04-16 17:51:27 +0000478 // ::= ge # >=
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000479 case OO_GreaterEqual: Out << "ge"; break;
Sebastian Redl3201f6b2009-04-16 17:51:27 +0000480 // ::= nt # !
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000481 case OO_Exclaim: Out << "nt"; break;
Sebastian Redl3201f6b2009-04-16 17:51:27 +0000482 // ::= aa # &&
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000483 case OO_AmpAmp: Out << "aa"; break;
Sebastian Redl3201f6b2009-04-16 17:51:27 +0000484 // ::= oo # ||
485 case OO_PipePipe: Out << "oo"; break;
486 // ::= pp # ++
487 case OO_PlusPlus: Out << "pp"; break;
488 // ::= mm # --
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000489 case OO_MinusMinus: Out << "mm"; break;
Sebastian Redl3201f6b2009-04-16 17:51:27 +0000490 // ::= cm # ,
491 case OO_Comma: Out << "cm"; break;
492 // ::= pm # ->*
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000493 case OO_ArrowStar: Out << "pm"; break;
Sebastian Redl3201f6b2009-04-16 17:51:27 +0000494 // ::= pt # ->
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000495 case OO_Arrow: Out << "pt"; break;
Sebastian Redl3201f6b2009-04-16 17:51:27 +0000496 // ::= cl # ()
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000497 case OO_Call: Out << "cl"; break;
Sebastian Redl3201f6b2009-04-16 17:51:27 +0000498 // ::= ix # []
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000499 case OO_Subscript: Out << "ix"; break;
500 // UNSUPPORTED: ::= qu # ?
501
Sebastian Redl3201f6b2009-04-16 17:51:27 +0000502 case OO_None:
503 case OO_Conditional:
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000504 case NUM_OVERLOADED_OPERATORS:
Douglas Gregor6ec36682009-02-18 23:53:56 +0000505 assert(false && "Not an overloaded operator");
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000506 break;
507 }
508}
509
510void CXXNameMangler::mangleCVQualifiers(unsigned Quals) {
511 // <CV-qualifiers> ::= [r] [V] [K] # restrict (C99), volatile, const
512 if (Quals & QualType::Restrict)
513 Out << 'r';
514 if (Quals & QualType::Volatile)
515 Out << 'V';
516 if (Quals & QualType::Const)
517 Out << 'K';
518}
519
520void CXXNameMangler::mangleType(QualType T) {
Anders Carlsson4843e582009-03-10 17:07:44 +0000521 // Only operate on the canonical type!
522 T = Context.getCanonicalType(T);
523
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000524 // <type> ::= <CV-qualifiers> <type>
525 mangleCVQualifiers(T.getCVRQualifiers());
526
John McCallefe6aee2009-09-05 07:56:18 +0000527 switch (T->getTypeClass()) {
528#define ABSTRACT_TYPE(CLASS, PARENT)
529#define NON_CANONICAL_TYPE(CLASS, PARENT) \
530 case Type::CLASS: \
531 llvm::llvm_unreachable("can't mangle non-canonical type " #CLASS "Type"); \
532 return;
533#define TYPE(CLASS, PARENT) \
534 case Type::CLASS: \
535 return mangleType(static_cast<CLASS##Type*>(T.getTypePtr()));
536#include "clang/AST/TypeNodes.def"
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000537 }
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000538}
539
540void CXXNameMangler::mangleType(const BuiltinType *T) {
John McCallefe6aee2009-09-05 07:56:18 +0000541 // <type> ::= <builtin-type>
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000542 // <builtin-type> ::= v # void
543 // ::= w # wchar_t
544 // ::= b # bool
545 // ::= c # char
546 // ::= a # signed char
547 // ::= h # unsigned char
548 // ::= s # short
549 // ::= t # unsigned short
550 // ::= i # int
551 // ::= j # unsigned int
552 // ::= l # long
553 // ::= m # unsigned long
554 // ::= x # long long, __int64
555 // ::= y # unsigned long long, __int64
556 // ::= n # __int128
557 // UNSUPPORTED: ::= o # unsigned __int128
558 // ::= f # float
559 // ::= d # double
560 // ::= e # long double, __float80
561 // UNSUPPORTED: ::= g # __float128
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000562 // UNSUPPORTED: ::= Dd # IEEE 754r decimal floating point (64 bits)
563 // UNSUPPORTED: ::= De # IEEE 754r decimal floating point (128 bits)
564 // UNSUPPORTED: ::= Df # IEEE 754r decimal floating point (32 bits)
565 // UNSUPPORTED: ::= Dh # IEEE 754r half-precision floating point (16 bits)
Alisdair Meredithf5c209d2009-07-14 06:30:34 +0000566 // ::= Di # char32_t
567 // ::= Ds # char16_t
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000568 // ::= u <source-name> # vendor extended type
Sebastian Redl6e8ed162009-05-10 18:38:11 +0000569 // From our point of view, std::nullptr_t is a builtin, but as far as mangling
570 // is concerned, it's a type called std::nullptr_t.
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000571 switch (T->getKind()) {
572 case BuiltinType::Void: Out << 'v'; break;
573 case BuiltinType::Bool: Out << 'b'; break;
574 case BuiltinType::Char_U: case BuiltinType::Char_S: Out << 'c'; break;
575 case BuiltinType::UChar: Out << 'h'; break;
576 case BuiltinType::UShort: Out << 't'; break;
577 case BuiltinType::UInt: Out << 'j'; break;
578 case BuiltinType::ULong: Out << 'm'; break;
579 case BuiltinType::ULongLong: Out << 'y'; break;
Chris Lattner2df9ced2009-04-30 02:43:43 +0000580 case BuiltinType::UInt128: Out << 'o'; break;
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000581 case BuiltinType::SChar: Out << 'a'; break;
582 case BuiltinType::WChar: Out << 'w'; break;
Alisdair Meredithf5c209d2009-07-14 06:30:34 +0000583 case BuiltinType::Char16: Out << "Ds"; break;
584 case BuiltinType::Char32: Out << "Di"; break;
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000585 case BuiltinType::Short: Out << 's'; break;
586 case BuiltinType::Int: Out << 'i'; break;
587 case BuiltinType::Long: Out << 'l'; break;
588 case BuiltinType::LongLong: Out << 'x'; break;
Chris Lattner2df9ced2009-04-30 02:43:43 +0000589 case BuiltinType::Int128: Out << 'n'; break;
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000590 case BuiltinType::Float: Out << 'f'; break;
591 case BuiltinType::Double: Out << 'd'; break;
592 case BuiltinType::LongDouble: Out << 'e'; break;
Sebastian Redl6e8ed162009-05-10 18:38:11 +0000593 case BuiltinType::NullPtr: Out << "St9nullptr_t"; break;
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000594
595 case BuiltinType::Overload:
596 case BuiltinType::Dependent:
597 assert(false &&
598 "Overloaded and dependent types shouldn't get to name mangling");
599 break;
Anders Carlssone89d1592009-06-26 18:41:36 +0000600 case BuiltinType::UndeducedAuto:
601 assert(0 && "Should not see undeduced auto here");
602 break;
Steve Naroff9533a7f2009-07-22 17:14:51 +0000603 case BuiltinType::ObjCId: Out << "11objc_object"; break;
604 case BuiltinType::ObjCClass: Out << "10objc_class"; break;
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000605 }
606}
607
John McCallefe6aee2009-09-05 07:56:18 +0000608// <type> ::= <function-type>
609// <function-type> ::= F [Y] <bare-function-type> E
610void CXXNameMangler::mangleType(const FunctionProtoType *T) {
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000611 Out << 'F';
Mike Stumpf5408fe2009-05-16 07:57:57 +0000612 // FIXME: We don't have enough information in the AST to produce the 'Y'
613 // encoding for extern "C" function types.
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000614 mangleBareFunctionType(T, /*MangleReturnType=*/true);
615 Out << 'E';
616}
John McCallefe6aee2009-09-05 07:56:18 +0000617void CXXNameMangler::mangleType(const FunctionNoProtoType *T) {
618 llvm::llvm_unreachable("Can't mangle K&R function prototypes");
619}
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000620void CXXNameMangler::mangleBareFunctionType(const FunctionType *T,
621 bool MangleReturnType) {
John McCallefe6aee2009-09-05 07:56:18 +0000622 // We should never be mangling something without a prototype.
623 const FunctionProtoType *Proto = cast<FunctionProtoType>(T);
624
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000625 // <bare-function-type> ::= <signature type>+
626 if (MangleReturnType)
John McCallefe6aee2009-09-05 07:56:18 +0000627 mangleType(Proto->getResultType());
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000628
Anders Carlssonc6c91bc2009-04-01 00:15:23 +0000629 if (Proto->getNumArgs() == 0) {
630 Out << 'v';
631 return;
632 }
John McCallefe6aee2009-09-05 07:56:18 +0000633
Douglas Gregor72564e72009-02-26 23:50:07 +0000634 for (FunctionProtoType::arg_type_iterator Arg = Proto->arg_type_begin(),
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000635 ArgEnd = Proto->arg_type_end();
636 Arg != ArgEnd; ++Arg)
637 mangleType(*Arg);
Douglas Gregor219cc612009-02-13 01:28:03 +0000638
639 // <builtin-type> ::= z # ellipsis
640 if (Proto->isVariadic())
641 Out << 'z';
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000642}
643
John McCallefe6aee2009-09-05 07:56:18 +0000644// <type> ::= <class-enum-type>
645// <class-enum-type> ::= <name>
646void CXXNameMangler::mangleType(const EnumType *T) {
647 mangleType(static_cast<const TagType*>(T));
648}
649void CXXNameMangler::mangleType(const RecordType *T) {
650 mangleType(static_cast<const TagType*>(T));
651}
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000652void CXXNameMangler::mangleType(const TagType *T) {
Anders Carlsson4843e582009-03-10 17:07:44 +0000653 if (!T->getDecl()->getIdentifier())
654 mangleName(T->getDecl()->getTypedefForAnonDecl());
655 else
656 mangleName(T->getDecl());
Anders Carlsson7a0ba872009-05-15 16:09:15 +0000657
Mike Stump141c5af2009-09-02 00:25:38 +0000658 // If this is a class template specialization, mangle the template arguments.
Anders Carlsson7a0ba872009-05-15 16:09:15 +0000659 if (ClassTemplateSpecializationDecl *Spec
660 = dyn_cast<ClassTemplateSpecializationDecl>(T->getDecl()))
661 mangleTemplateArgumentList(Spec->getTemplateArgs());
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000662}
663
John McCallefe6aee2009-09-05 07:56:18 +0000664// <type> ::= <array-type>
665// <array-type> ::= A <positive dimension number> _ <element type>
666// ::= A [<dimension expression>] _ <element type>
667void CXXNameMangler::mangleType(const ConstantArrayType *T) {
668 Out << 'A' << T->getSize() << '_';
669 mangleType(T->getElementType());
670}
671void CXXNameMangler::mangleType(const VariableArrayType *T) {
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000672 Out << 'A';
John McCallefe6aee2009-09-05 07:56:18 +0000673 mangleExpression(T->getSizeExpr());
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000674 Out << '_';
675 mangleType(T->getElementType());
676}
John McCallefe6aee2009-09-05 07:56:18 +0000677void CXXNameMangler::mangleType(const DependentSizedArrayType *T) {
678 Out << 'A';
679 mangleExpression(T->getSizeExpr());
680 Out << '_';
681 mangleType(T->getElementType());
682}
683void CXXNameMangler::mangleType(const IncompleteArrayType *T) {
684 Out << 'A' << '_';
685 mangleType(T->getElementType());
686}
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000687
John McCallefe6aee2009-09-05 07:56:18 +0000688// <type> ::= <pointer-to-member-type>
689// <pointer-to-member-type> ::= M <class type> <member type>
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000690void CXXNameMangler::mangleType(const MemberPointerType *T) {
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000691 Out << 'M';
692 mangleType(QualType(T->getClass(), 0));
Anders Carlsson0e650012009-05-17 17:41:20 +0000693 QualType PointeeType = T->getPointeeType();
694 if (const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(PointeeType)) {
695 mangleCVQualifiers(FPT->getTypeQuals());
696 mangleType(FPT);
697 } else
698 mangleType(PointeeType);
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000699}
700
John McCallefe6aee2009-09-05 07:56:18 +0000701// <type> ::= <template-param>
702// <template-param> ::= T_ # first template parameter
703// ::= T <parameter-2 non-negative number> _
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000704void CXXNameMangler::mangleType(const TemplateTypeParmType *T) {
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000705 if (T->getIndex() == 0)
706 Out << "T_";
707 else
708 Out << 'T' << (T->getIndex() - 1) << '_';
709}
710
John McCallefe6aee2009-09-05 07:56:18 +0000711// FIXME: <type> ::= <template-template-param> <template-args>
712// FIXME: <type> ::= <substitution> # See Compression below
713
714// <type> ::= P <type> # pointer-to
715void CXXNameMangler::mangleType(const PointerType *T) {
716 Out << 'P';
717 mangleType(T->getPointeeType());
718}
719void CXXNameMangler::mangleType(const ObjCObjectPointerType *T) {
720 Out << 'P';
721 mangleType(T->getPointeeType());
722}
723
724// <type> ::= R <type> # reference-to
725void CXXNameMangler::mangleType(const LValueReferenceType *T) {
726 Out << 'R';
727 mangleType(T->getPointeeType());
728}
729
730// <type> ::= O <type> # rvalue reference-to (C++0x)
731void CXXNameMangler::mangleType(const RValueReferenceType *T) {
732 Out << 'O';
733 mangleType(T->getPointeeType());
734}
735
736// <type> ::= C <type> # complex pair (C 2000)
737void CXXNameMangler::mangleType(const ComplexType *T) {
738 Out << 'C';
739 mangleType(T->getElementType());
740}
741
742// GNU extension: vector types
743void CXXNameMangler::mangleType(const VectorType *T) {
744 Out << "U8__vector";
745 mangleType(T->getElementType());
746}
747void CXXNameMangler::mangleType(const ExtVectorType *T) {
748 mangleType(static_cast<const VectorType*>(T));
749}
750void CXXNameMangler::mangleType(const DependentSizedExtVectorType *T) {
751 Out << "U8__vector";
752 mangleType(T->getElementType());
753}
754
Anders Carlssona40c5e42009-03-07 22:03:21 +0000755void CXXNameMangler::mangleType(const ObjCInterfaceType *T) {
756 mangleSourceName(T->getDecl()->getIdentifier());
757}
758
John McCallefe6aee2009-09-05 07:56:18 +0000759void CXXNameMangler::mangleType(const BlockPointerType *T) {
760 assert(false && "can't mangle block pointer types yet");
761}
762
763void CXXNameMangler::mangleType(const FixedWidthIntType *T) {
764 assert(false && "can't mangle arbitary-precision integer type yet");
765}
766
767void CXXNameMangler::mangleType(const TemplateSpecializationType *T) {
768 // TSTs are never canonical unless they're dependent.
769 assert(false && "can't mangle dependent template specializations yet");
770}
771
772void CXXNameMangler::mangleType(const TypenameType *T) {
773 assert(false && "can't mangle dependent typenames yet");
774}
775
776// FIXME: For now, just drop all extension qualifiers on the floor.
777void CXXNameMangler::mangleType(const ExtQualType *T) {
778 mangleType(QualType(T->getBaseType(), 0));
779}
780
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000781void CXXNameMangler::mangleExpression(Expr *E) {
782 assert(false && "Cannot mangle expressions yet");
783}
784
John McCallefe6aee2009-09-05 07:56:18 +0000785// FIXME: <type> ::= G <type> # imaginary (C 2000)
786// FIXME: <type> ::= U <source-name> <type> # vendor extended type qualifier
787
Anders Carlsson3ac86b52009-04-15 05:36:58 +0000788void CXXNameMangler::mangleCXXCtorType(CXXCtorType T) {
789 // <ctor-dtor-name> ::= C1 # complete object constructor
790 // ::= C2 # base object constructor
791 // ::= C3 # complete object allocating constructor
792 //
793 switch (T) {
794 case Ctor_Complete:
795 Out << "C1";
796 break;
797 case Ctor_Base:
798 Out << "C2";
799 break;
800 case Ctor_CompleteAllocating:
801 Out << "C3";
802 break;
803 }
804}
805
Anders Carlsson27ae5362009-04-17 01:58:57 +0000806void CXXNameMangler::mangleCXXDtorType(CXXDtorType T) {
807 // <ctor-dtor-name> ::= D0 # deleting destructor
808 // ::= D1 # complete object destructor
809 // ::= D2 # base object destructor
810 //
811 switch (T) {
812 case Dtor_Deleting:
813 Out << "D0";
814 break;
815 case Dtor_Complete:
816 Out << "D1";
817 break;
818 case Dtor_Base:
819 Out << "D2";
820 break;
821 }
822}
823
Anders Carlsson7a0ba872009-05-15 16:09:15 +0000824void CXXNameMangler::mangleTemplateArgumentList(const TemplateArgumentList &L) {
825 // <template-args> ::= I <template-arg>+ E
826 Out << "I";
827
828 for (unsigned i = 0, e = L.size(); i != e; ++i) {
829 const TemplateArgument &A = L[i];
830
831 mangleTemplateArgument(A);
832 }
833
834 Out << "E";
835}
836
837void CXXNameMangler::mangleTemplateArgument(const TemplateArgument &A) {
838 // <template-arg> ::= <type> # type or template
839 // ::= X <expression> E # expression
840 // ::= <expr-primary> # simple expressions
841 // ::= I <template-arg>* E # argument pack
842 // ::= sp <expression> # pack expansion of (C++0x)
843 switch (A.getKind()) {
844 default:
845 assert(0 && "Unknown template argument kind!");
846 case TemplateArgument::Type:
847 mangleType(A.getAsType());
848 break;
849 case TemplateArgument::Integral:
850 // <expr-primary> ::= L <type> <value number> E # integer literal
851
852 Out << 'L';
853
854 mangleType(A.getIntegralType());
855
856 const llvm::APSInt *Integral = A.getAsIntegral();
857 if (A.getIntegralType()->isBooleanType()) {
858 // Boolean values are encoded as 0/1.
859 Out << (Integral->getBoolValue() ? '1' : '0');
860 } else {
861 if (Integral->isNegative())
862 Out << 'n';
863 Integral->abs().print(Out, false);
864 }
865
866 Out << 'E';
867 break;
868 }
869}
870
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000871namespace clang {
Mike Stump141c5af2009-09-02 00:25:38 +0000872 /// \brief Mangles the name of the declaration D and emits that name to the
873 /// given output stream.
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000874 ///
Mike Stump141c5af2009-09-02 00:25:38 +0000875 /// If the declaration D requires a mangled name, this routine will emit that
876 /// mangled name to \p os and return true. Otherwise, \p os will be unchanged
877 /// and this routine will return false. In this case, the caller should just
878 /// emit the identifier of the declaration (\c D->getIdentifier()) as its
879 /// name.
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000880 bool mangleName(const NamedDecl *D, ASTContext &Context,
881 llvm::raw_ostream &os) {
Anders Carlsson578aa642009-05-03 16:51:04 +0000882 assert(!isa<CXXConstructorDecl>(D) &&
883 "Use mangleCXXCtor for constructor decls!");
884 assert(!isa<CXXDestructorDecl>(D) &&
885 "Use mangleCXXDtor for destructor decls!");
886
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000887 CXXNameMangler Mangler(Context, os);
Douglas Gregor6ec36682009-02-18 23:53:56 +0000888 if (!Mangler.mangle(D))
889 return false;
890
891 os.flush();
892 return true;
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000893 }
Anders Carlsson41aa8c12009-04-13 18:02:10 +0000894
Mike Stump141c5af2009-09-02 00:25:38 +0000895 /// \brief Mangles the a thunk with the offset n for the declaration D and
896 /// emits that name to the given output stream.
Mike Stump77ca8f62009-09-05 07:20:32 +0000897 void mangleThunk(const NamedDecl *D, int64_t nv, int64_t v,
Mike Stump883f1272009-09-02 00:28:47 +0000898 ASTContext &Context, llvm::raw_ostream &os) {
Mike Stump141c5af2009-09-02 00:25:38 +0000899 // FIXME: Hum, we might have to thunk these, fix.
900 assert(!isa<CXXConstructorDecl>(D) &&
901 "Use mangleCXXCtor for constructor decls!");
902 assert(!isa<CXXDestructorDecl>(D) &&
903 "Use mangleCXXDtor for destructor decls!");
904
905 CXXNameMangler Mangler(Context, os);
Mike Stump77ca8f62009-09-05 07:20:32 +0000906 Mangler.mangleThunk(D, nv, v);
Mike Stump141c5af2009-09-02 00:25:38 +0000907 os.flush();
908 }
909
Mike Stump9124bcc2009-09-02 00:56:18 +0000910 /// \brief Mangles the a covariant thunk for the declaration D and emits that
911 /// name to the given output stream.
Mike Stump77ca8f62009-09-05 07:20:32 +0000912 void mangleCovariantThunk(const NamedDecl *D, int64_t nv_t, int64_t v_t,
913 int64_t nv_r, int64_t v_r, ASTContext &Context,
Mike Stump9124bcc2009-09-02 00:56:18 +0000914 llvm::raw_ostream &os) {
915 // FIXME: Hum, we might have to thunk these, fix.
916 assert(!isa<CXXConstructorDecl>(D) &&
917 "Use mangleCXXCtor for constructor decls!");
918 assert(!isa<CXXDestructorDecl>(D) &&
919 "Use mangleCXXDtor for destructor decls!");
920
921 CXXNameMangler Mangler(Context, os);
Mike Stump77ca8f62009-09-05 07:20:32 +0000922 Mangler.mangleCovariantThunk(D, nv_t, v_t, nv_r, v_r);
Mike Stump9124bcc2009-09-02 00:56:18 +0000923 os.flush();
924 }
925
Anders Carlsson3ac86b52009-04-15 05:36:58 +0000926 /// mangleGuardVariable - Returns the mangled name for a guard variable
927 /// for the passed in VarDecl.
Anders Carlsson41aa8c12009-04-13 18:02:10 +0000928 void mangleGuardVariable(const VarDecl *D, ASTContext &Context,
929 llvm::raw_ostream &os) {
930 CXXNameMangler Mangler(Context, os);
931 Mangler.mangleGuardVariable(D);
932
933 os.flush();
934 }
Anders Carlsson3ac86b52009-04-15 05:36:58 +0000935
936 void mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type,
937 ASTContext &Context, llvm::raw_ostream &os) {
938 CXXNameMangler Mangler(Context, os);
939 Mangler.mangleCXXCtor(D, Type);
940
941 os.flush();
942 }
Anders Carlsson27ae5362009-04-17 01:58:57 +0000943
944 void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type,
945 ASTContext &Context, llvm::raw_ostream &os) {
946 CXXNameMangler Mangler(Context, os);
947 Mangler.mangleCXXDtor(D, Type);
948
949 os.flush();
950 }
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000951
Mike Stumpf1216772009-07-31 18:25:34 +0000952 void mangleCXXVtable(QualType Type, ASTContext &Context,
953 llvm::raw_ostream &os) {
954 CXXNameMangler Mangler(Context, os);
955 Mangler.mangleCXXVtable(Type);
956
957 os.flush();
958 }
Mike Stump738f8c22009-07-31 23:15:31 +0000959
960 void mangleCXXRtti(QualType Type, ASTContext &Context,
961 llvm::raw_ostream &os) {
962 CXXNameMangler Mangler(Context, os);
963 Mangler.mangleCXXRtti(Type);
964
965 os.flush();
966 }
Mike Stumpf1216772009-07-31 18:25:34 +0000967}