blob: c8d9de2d3304af561c6b7ffbe556d74c81026b6c [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"
Douglas Gregor6ec36682009-02-18 23:53:56 +000022#include "clang/Basic/SourceManager.h"
Douglas Gregor5f2bfd42009-02-13 00:10:09 +000023#include "llvm/Support/Compiler.h"
24#include "llvm/Support/raw_ostream.h"
25using namespace clang;
26
27namespace {
28 class VISIBILITY_HIDDEN CXXNameMangler {
29 ASTContext &Context;
30 llvm::raw_ostream &Out;
31
Anders Carlsson3ac86b52009-04-15 05:36:58 +000032 const CXXConstructorDecl *Ctor;
33 CXXCtorType CtorType;
34
Douglas Gregor5f2bfd42009-02-13 00:10:09 +000035 public:
36 CXXNameMangler(ASTContext &C, llvm::raw_ostream &os)
Anders Carlsson3ac86b52009-04-15 05:36:58 +000037 : Context(C), Out(os), Ctor(0), CtorType(Ctor_Complete) { }
Douglas Gregor5f2bfd42009-02-13 00:10:09 +000038
39 bool mangle(const NamedDecl *D);
Anders Carlsson41aa8c12009-04-13 18:02:10 +000040 void mangleGuardVariable(const VarDecl *D);
Anders Carlsson3ac86b52009-04-15 05:36:58 +000041 void mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type);
42
Anders Carlsson43f17402009-04-02 15:51:53 +000043 private:
44 bool mangleFunctionDecl(const FunctionDecl *FD);
45
Douglas Gregor5f2bfd42009-02-13 00:10:09 +000046 void mangleFunctionEncoding(const FunctionDecl *FD);
47 void mangleName(const NamedDecl *ND);
48 void mangleUnqualifiedName(const NamedDecl *ND);
49 void mangleSourceName(const IdentifierInfo *II);
Anders Carlsson1b42c792009-04-02 16:24:45 +000050 void mangleLocalName(const NamedDecl *ND);
Douglas Gregor5f2bfd42009-02-13 00:10:09 +000051 void mangleNestedName(const NamedDecl *ND);
52 void manglePrefix(const DeclContext *DC);
53 void mangleOperatorName(OverloadedOperatorKind OO, unsigned Arity);
54 void mangleCVQualifiers(unsigned Quals);
55 void mangleType(QualType T);
56 void mangleType(const BuiltinType *T);
57 void mangleType(const FunctionType *T);
58 void mangleBareFunctionType(const FunctionType *T, bool MangleReturnType);
59 void mangleType(const TagType *T);
60 void mangleType(const ArrayType *T);
61 void mangleType(const MemberPointerType *T);
62 void mangleType(const TemplateTypeParmType *T);
Anders Carlssona40c5e42009-03-07 22:03:21 +000063 void mangleType(const ObjCInterfaceType *T);
Douglas Gregor5f2bfd42009-02-13 00:10:09 +000064 void mangleExpression(Expr *E);
Anders Carlsson3ac86b52009-04-15 05:36:58 +000065 void mangleCXXCtorType(CXXCtorType T);
Douglas Gregor5f2bfd42009-02-13 00:10:09 +000066 };
67}
68
Anders Carlsson43f17402009-04-02 15:51:53 +000069static bool isInCLinkageSpecification(const Decl *D) {
70 for (const DeclContext *DC = D->getDeclContext();
71 !DC->isTranslationUnit(); DC = DC->getParent()) {
72 if (const LinkageSpecDecl *Linkage = dyn_cast<LinkageSpecDecl>(DC))
73 return Linkage->getLanguage() == LinkageSpecDecl::lang_c;
74 }
75
76 return false;
77}
78
79bool CXXNameMangler::mangleFunctionDecl(const FunctionDecl *FD) {
80 // Clang's "overloadable" attribute extension to C/C++ implies
81 // name mangling (always).
Daniel Dunbarb11fa0d2009-04-13 21:08:27 +000082 if (FD->hasAttr<OverloadableAttr>()) {
Anders Carlsson43f17402009-04-02 15:51:53 +000083 ; // fall into mangling code unconditionally.
84 } else if (// C functions are not mangled
85 !Context.getLangOptions().CPlusPlus ||
86 // "main" is not mangled in C++
87 FD->isMain() ||
88 // No mangling in an "implicit extern C" header.
89 Context.getSourceManager().getFileCharacteristic(FD->getLocation())
90 == SrcMgr::C_ExternCSystem ||
91 // No name mangling in a C linkage specification.
92 isInCLinkageSpecification(FD))
93 return false;
94
95 // If we get here, mangle the decl name!
96 Out << "_Z";
97 mangleFunctionEncoding(FD);
98 return true;
99}
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000100
101bool CXXNameMangler::mangle(const NamedDecl *D) {
Chris Lattnerca3f25c2009-03-21 08:24:40 +0000102 // Any decl can be declared with __asm("foo") on it, and this takes
103 // precedence over all other naming in the .o file.
104 if (const AsmLabelAttr *ALA = D->getAttr<AsmLabelAttr>()) {
105 // If we have an asm name, then we use it as the mangling.
106 Out << '\01'; // LLVM IR Marker for __asm("foo")
107 Out << ALA->getLabel();
108 return true;
109 }
110
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000111 // <mangled-name> ::= _Z <encoding>
112 // ::= <data name>
113 // ::= <special-name>
114
115 // FIXME: Actually use a visitor to decode these?
Anders Carlsson43f17402009-04-02 15:51:53 +0000116 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
117 return mangleFunctionDecl(FD);
Chris Lattnerbc7a0292009-03-21 06:19:20 +0000118
Anders Carlsson329749c2009-04-02 16:05:20 +0000119 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
120 if (!Context.getLangOptions().CPlusPlus ||
Anders Carlsson9ccb0652009-04-11 01:19:45 +0000121 isInCLinkageSpecification(D) ||
122 D->getDeclContext()->isTranslationUnit())
Anders Carlsson329749c2009-04-02 16:05:20 +0000123 return false;
124
125 Out << "_Z";
126 mangleName(VD);
127 return true;
128 }
129
Anders Carlsson43f17402009-04-02 15:51:53 +0000130 return false;
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000131}
132
Anders Carlsson3ac86b52009-04-15 05:36:58 +0000133void CXXNameMangler::mangleCXXCtor(const CXXConstructorDecl *D,
134 CXXCtorType Type) {
135 assert(!Ctor && "Ctor already set!");
136 Ctor = D;
137 CtorType = Type;
138
139 mangle(D);
140}
141
Anders Carlsson41aa8c12009-04-13 18:02:10 +0000142void CXXNameMangler::mangleGuardVariable(const VarDecl *D)
143{
144 // <special-name> ::= GV <object name> # Guard variable for one-time
145 // # initialization
146
147 Out << "_ZGV";
148 mangleName(D);
149}
150
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000151void CXXNameMangler::mangleFunctionEncoding(const FunctionDecl *FD) {
152 // <encoding> ::= <function name> <bare-function-type>
153 mangleName(FD);
154 mangleBareFunctionType(FD->getType()->getAsFunctionType(), false);
155}
156
157static bool isStdNamespace(const DeclContext *DC) {
158 if (!DC->isNamespace() || !DC->getParent()->isTranslationUnit())
159 return false;
160
161 const NamespaceDecl *NS = cast<NamespaceDecl>(DC);
Douglas Gregor6ec36682009-02-18 23:53:56 +0000162 return NS->getOriginalNamespace()->getIdentifier()->isStr("std");
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000163}
164
165void CXXNameMangler::mangleName(const NamedDecl *ND) {
166 // <name> ::= <nested-name>
167 // ::= <unscoped-name>
168 // ::= <unscoped-template-name> <template-args>
169 // ::= <local-name> # See Scope Encoding below
170 //
171 // <unscoped-name> ::= <unqualified-name>
172 // ::= St <unqualified-name> # ::std::
173 if (ND->getDeclContext()->isTranslationUnit())
174 mangleUnqualifiedName(ND);
175 else if (isStdNamespace(ND->getDeclContext())) {
176 Out << "St";
177 mangleUnqualifiedName(ND);
Anders Carlsson1b42c792009-04-02 16:24:45 +0000178 } else if (isa<FunctionDecl>(ND->getDeclContext()))
179 mangleLocalName(ND);
180 else
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000181 mangleNestedName(ND);
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000182}
183
184void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND) {
185 // <unqualified-name> ::= <operator-name>
186 // ::= <ctor-dtor-name>
187 // ::= <source-name>
188 DeclarationName Name = ND->getDeclName();
189 switch (Name.getNameKind()) {
190 case DeclarationName::Identifier:
191 mangleSourceName(Name.getAsIdentifierInfo());
192 break;
193
194 case DeclarationName::ObjCZeroArgSelector:
195 case DeclarationName::ObjCOneArgSelector:
196 case DeclarationName::ObjCMultiArgSelector:
197 assert(false && "Can't mangle Objective-C selector names here!");
198 break;
199
200 case DeclarationName::CXXConstructorName:
Anders Carlsson3ac86b52009-04-15 05:36:58 +0000201 if (ND == Ctor)
202 // If the named decl is the C++ constructor we're mangling, use the
203 // type we were given.
204 mangleCXXCtorType(CtorType);
205 else
206 // Otherwise, use the complete constructor name. This is relevant if a
207 // class with a constructor is declared within a constructor.
208 mangleCXXCtorType(Ctor_Complete);
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000209 break;
210
211 case DeclarationName::CXXDestructorName:
212 // <ctor-dtor-name> ::= D0 # deleting destructor
213 // ::= D1 # complete object destructor
214 // ::= D2 # base object destructor
215 //
216 // FIXME: We don't even have all of these destructors in the AST
217 // yet.
218 Out << "D0";
219 break;
220
221 case DeclarationName::CXXConversionFunctionName:
Douglas Gregor219cc612009-02-13 01:28:03 +0000222 // <operator-name> ::= cv <type> # (cast)
223 Out << "cv";
224 mangleType(Context.getCanonicalType(Name.getCXXNameType()));
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000225 break;
226
227 case DeclarationName::CXXOperatorName:
228 mangleOperatorName(Name.getCXXOverloadedOperator(),
229 cast<FunctionDecl>(ND)->getNumParams());
230 break;
231
232 case DeclarationName::CXXUsingDirective:
233 assert(false && "Can't mangle a using directive name!");
Douglas Gregor219cc612009-02-13 01:28:03 +0000234 break;
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000235 }
236}
237
238void CXXNameMangler::mangleSourceName(const IdentifierInfo *II) {
239 // <source-name> ::= <positive length number> <identifier>
240 // <number> ::= [n] <non-negative decimal integer>
241 // <identifier> ::= <unqualified source code identifier>
242 Out << II->getLength() << II->getName();
243}
244
245void CXXNameMangler::mangleNestedName(const NamedDecl *ND) {
246 // <nested-name> ::= N [<CV-qualifiers>] <prefix> <unqualified-name> E
247 // ::= N [<CV-qualifiers>] <template-prefix> <template-args> E
248 // FIXME: no template support
249 Out << 'N';
250 if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(ND))
251 mangleCVQualifiers(Method->getTypeQualifiers());
252 manglePrefix(ND->getDeclContext());
253 mangleUnqualifiedName(ND);
254 Out << 'E';
255}
256
Anders Carlsson1b42c792009-04-02 16:24:45 +0000257void CXXNameMangler::mangleLocalName(const NamedDecl *ND) {
258 // <local-name> := Z <function encoding> E <entity name> [<discriminator>]
259 // := Z <function encoding> E s [<discriminator>]
260 // <discriminator> := _ <non-negative number>
261 Out << 'Z';
262 mangleFunctionEncoding(cast<FunctionDecl>(ND->getDeclContext()));
263 Out << 'E';
264 mangleSourceName(ND->getIdentifier());
265}
266
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000267void CXXNameMangler::manglePrefix(const DeclContext *DC) {
268 // <prefix> ::= <prefix> <unqualified-name>
269 // ::= <template-prefix> <template-args>
270 // ::= <template-param>
271 // ::= # empty
272 // ::= <substitution>
273 // FIXME: We only handle mangling of namespaces and classes at the moment.
Anders Carlssonc8dee9c2009-04-01 00:42:16 +0000274 if (!DC->getParent()->isTranslationUnit())
275 manglePrefix(DC->getParent());
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000276
277 if (const NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(DC))
278 mangleSourceName(Namespace->getIdentifier());
279 else if (const RecordDecl *Record = dyn_cast<RecordDecl>(DC))
280 mangleSourceName(Record->getIdentifier());
281}
282
283void
284CXXNameMangler::mangleOperatorName(OverloadedOperatorKind OO, unsigned Arity) {
285 switch (OO) {
286 // <operator-name> ::= nw # new
287 case OO_New: Out << "nw"; break;
288 // ::= na # new[]
289 case OO_Array_New: Out << "na"; break;
290 // ::= dl # delete
291 case OO_Delete: Out << "dl"; break;
292 // ::= da # delete[]
293 case OO_Array_Delete: Out << "da"; break;
294 // ::= ps # + (unary)
295 // ::= pl # +
296 case OO_Plus: Out << (Arity == 1? "ps" : "pl"); break;
297 // ::= ng # - (unary)
298 // ::= mi # -
299 case OO_Minus: Out << (Arity == 1? "ng" : "mi"); break;
300 // ::= ad # & (unary)
301 // ::= an # &
302 case OO_Amp: Out << (Arity == 1? "ad" : "an"); break;
303 // ::= de # * (unary)
304 // ::= ml # *
305 case OO_Star: Out << (Arity == 1? "de" : "ml"); break;
306 // ::= co # ~
307 case OO_Tilde: Out << "co"; break;
308 // ::= dv # /
309 case OO_Slash: Out << "dv"; break;
310 // ::= rm # %
311 case OO_Percent: Out << "rm"; break;
312 // ::= or # |
313 case OO_Pipe: Out << "or"; break;
314 // ::= eo # ^
315 case OO_Caret: Out << "eo"; break;
316 // ::= aS # =
317 case OO_Equal: Out << "aS"; break;
318 // ::= pL # +=
319 case OO_PlusEqual: Out << "pL"; break;
320 // ::= mI # -=
321 case OO_MinusEqual: Out << "mI"; break;
322 // ::= mL # *=
323 case OO_StarEqual: Out << "mL"; break;
324 // ::= dV # /=
325 case OO_SlashEqual: Out << "dV"; break;
326 // ::= rM # %=
327 case OO_PercentEqual: Out << "rM"; break;
328 // ::= aN # &=
329 case OO_AmpEqual: Out << "aN"; break;
330 // ::= oR # |=
331 case OO_PipeEqual: Out << "oR"; break;
332 // ::= eO # ^=
333 case OO_CaretEqual: Out << "eO"; break;
334 // ::= ls # <<
335 case OO_LessLess: Out << "ls"; break;
336 // ::= rs # >>
337 case OO_GreaterGreater: Out << "rs"; break;
338 // ::= lS # <<=
339 case OO_LessLessEqual: Out << "lS"; break;
340 // ::= rS # >>=
341 case OO_GreaterGreaterEqual: Out << "rS"; break;
342 // ::= eq # ==
343 case OO_EqualEqual: Out << "eq"; break;
344 // ::= ne # !=
345 case OO_ExclaimEqual: Out << "ne"; break;
346 // ::= lt # <
347 case OO_Less: Out << "lt"; break;
348 // ::= gt # >
349 case OO_Greater: Out << "gt"; break;
350 // ::= le # <=
351 case OO_LessEqual: Out << "le"; break;
352 // ::= ge # >=
353 case OO_GreaterEqual: Out << "ge"; break;
354 // ::= nt # !
355 case OO_Exclaim: Out << "nt"; break;
356 // ::= aa # &&
357 case OO_AmpAmp: Out << "aa"; break;
358 // ::= oo # ||
359 case OO_PipePipe: Out << "oo"; break;
360 // ::= pp # ++
361 case OO_PlusPlus: Out << "pp"; break;
362 // ::= mm # --
363 case OO_MinusMinus: Out << "mm"; break;
364 // ::= cm # ,
365 case OO_Comma: Out << "cm"; break;
366 // ::= pm # ->*
367 case OO_ArrowStar: Out << "pm"; break;
368 // ::= pt # ->
369 case OO_Arrow: Out << "pt"; break;
370 // ::= cl # ()
371 case OO_Call: Out << "cl"; break;
372 // ::= ix # []
373 case OO_Subscript: Out << "ix"; break;
374 // UNSUPPORTED: ::= qu # ?
375
376 case OO_None:
377 case NUM_OVERLOADED_OPERATORS:
Douglas Gregor6ec36682009-02-18 23:53:56 +0000378 assert(false && "Not an overloaded operator");
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000379 break;
380 }
381}
382
383void CXXNameMangler::mangleCVQualifiers(unsigned Quals) {
384 // <CV-qualifiers> ::= [r] [V] [K] # restrict (C99), volatile, const
385 if (Quals & QualType::Restrict)
386 Out << 'r';
387 if (Quals & QualType::Volatile)
388 Out << 'V';
389 if (Quals & QualType::Const)
390 Out << 'K';
391}
392
393void CXXNameMangler::mangleType(QualType T) {
Anders Carlsson4843e582009-03-10 17:07:44 +0000394 // Only operate on the canonical type!
395 T = Context.getCanonicalType(T);
396
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000397 // FIXME: Should we have a TypeNodes.def to make this easier? (YES!)
398
399 // <type> ::= <CV-qualifiers> <type>
400 mangleCVQualifiers(T.getCVRQualifiers());
401
402 // ::= <builtin-type>
Anders Carlsson4843e582009-03-10 17:07:44 +0000403 if (const BuiltinType *BT = dyn_cast<BuiltinType>(T.getTypePtr()))
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000404 mangleType(BT);
405 // ::= <function-type>
406 else if (const FunctionType *FT = dyn_cast<FunctionType>(T.getTypePtr()))
407 mangleType(FT);
408 // ::= <class-enum-type>
409 else if (const TagType *TT = dyn_cast<TagType>(T.getTypePtr()))
410 mangleType(TT);
411 // ::= <array-type>
412 else if (const ArrayType *AT = dyn_cast<ArrayType>(T.getTypePtr()))
413 mangleType(AT);
414 // ::= <pointer-to-member-type>
415 else if (const MemberPointerType *MPT
416 = dyn_cast<MemberPointerType>(T.getTypePtr()))
417 mangleType(MPT);
418 // ::= <template-param>
419 else if (const TemplateTypeParmType *TypeParm
420 = dyn_cast<TemplateTypeParmType>(T.getTypePtr()))
421 mangleType(TypeParm);
422 // FIXME: ::= <template-template-param> <template-args>
423 // FIXME: ::= <substitution> # See Compression below
424 // ::= P <type> # pointer-to
425 else if (const PointerType *PT = dyn_cast<PointerType>(T.getTypePtr())) {
426 Out << 'P';
427 mangleType(PT->getPointeeType());
428 }
429 // ::= R <type> # reference-to
Sebastian Redl7c80bd62009-03-16 23:22:08 +0000430 else if (const LValueReferenceType *RT =
431 dyn_cast<LValueReferenceType>(T.getTypePtr())) {
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000432 Out << 'R';
433 mangleType(RT->getPointeeType());
434 }
Sebastian Redl7c80bd62009-03-16 23:22:08 +0000435 // ::= O <type> # rvalue reference-to (C++0x)
436 else if (const RValueReferenceType *RT =
437 dyn_cast<RValueReferenceType>(T.getTypePtr())) {
438 Out << 'O';
439 mangleType(RT->getPointeeType());
440 }
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000441 // ::= C <type> # complex pair (C 2000)
442 else if (const ComplexType *CT = dyn_cast<ComplexType>(T.getTypePtr())) {
443 Out << 'C';
444 mangleType(CT->getElementType());
445 } else if (const VectorType *VT = dyn_cast<VectorType>(T.getTypePtr())) {
446 // GNU extension: vector types
447 Out << "U8__vector";
448 mangleType(VT->getElementType());
Anders Carlssona40c5e42009-03-07 22:03:21 +0000449 } else if (const ObjCInterfaceType *IT =
450 dyn_cast<ObjCInterfaceType>(T.getTypePtr())) {
451 mangleType(IT);
Anders Carlsson4843e582009-03-10 17:07:44 +0000452 }
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000453 // FIXME: ::= G <type> # imaginary (C 2000)
454 // FIXME: ::= U <source-name> <type> # vendor extended type qualifier
455 else
456 assert(false && "Cannot mangle unknown type");
457}
458
459void CXXNameMangler::mangleType(const BuiltinType *T) {
460 // <builtin-type> ::= v # void
461 // ::= w # wchar_t
462 // ::= b # bool
463 // ::= c # char
464 // ::= a # signed char
465 // ::= h # unsigned char
466 // ::= s # short
467 // ::= t # unsigned short
468 // ::= i # int
469 // ::= j # unsigned int
470 // ::= l # long
471 // ::= m # unsigned long
472 // ::= x # long long, __int64
473 // ::= y # unsigned long long, __int64
474 // ::= n # __int128
475 // UNSUPPORTED: ::= o # unsigned __int128
476 // ::= f # float
477 // ::= d # double
478 // ::= e # long double, __float80
479 // UNSUPPORTED: ::= g # __float128
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000480 // UNSUPPORTED: ::= Dd # IEEE 754r decimal floating point (64 bits)
481 // UNSUPPORTED: ::= De # IEEE 754r decimal floating point (128 bits)
482 // UNSUPPORTED: ::= Df # IEEE 754r decimal floating point (32 bits)
483 // UNSUPPORTED: ::= Dh # IEEE 754r half-precision floating point (16 bits)
484 // UNSUPPORTED: ::= Di # char32_t
485 // UNSUPPORTED: ::= Ds # char16_t
486 // ::= u <source-name> # vendor extended type
487 switch (T->getKind()) {
488 case BuiltinType::Void: Out << 'v'; break;
489 case BuiltinType::Bool: Out << 'b'; break;
490 case BuiltinType::Char_U: case BuiltinType::Char_S: Out << 'c'; break;
491 case BuiltinType::UChar: Out << 'h'; break;
492 case BuiltinType::UShort: Out << 't'; break;
493 case BuiltinType::UInt: Out << 'j'; break;
494 case BuiltinType::ULong: Out << 'm'; break;
495 case BuiltinType::ULongLong: Out << 'y'; break;
496 case BuiltinType::SChar: Out << 'a'; break;
497 case BuiltinType::WChar: Out << 'w'; break;
498 case BuiltinType::Short: Out << 's'; break;
499 case BuiltinType::Int: Out << 'i'; break;
500 case BuiltinType::Long: Out << 'l'; break;
501 case BuiltinType::LongLong: Out << 'x'; break;
502 case BuiltinType::Float: Out << 'f'; break;
503 case BuiltinType::Double: Out << 'd'; break;
504 case BuiltinType::LongDouble: Out << 'e'; break;
505
506 case BuiltinType::Overload:
507 case BuiltinType::Dependent:
508 assert(false &&
509 "Overloaded and dependent types shouldn't get to name mangling");
510 break;
511 }
512}
513
514void CXXNameMangler::mangleType(const FunctionType *T) {
515 // <function-type> ::= F [Y] <bare-function-type> E
516 Out << 'F';
517 // FIXME: We don't have enough information in the AST to produce the
518 // 'Y' encoding for extern "C" function types.
519 mangleBareFunctionType(T, /*MangleReturnType=*/true);
520 Out << 'E';
521}
522
523void CXXNameMangler::mangleBareFunctionType(const FunctionType *T,
524 bool MangleReturnType) {
525 // <bare-function-type> ::= <signature type>+
526 if (MangleReturnType)
527 mangleType(T->getResultType());
528
Douglas Gregor72564e72009-02-26 23:50:07 +0000529 const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(T);
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000530 assert(Proto && "Can't mangle K&R function prototypes");
531
Anders Carlssonc6c91bc2009-04-01 00:15:23 +0000532 if (Proto->getNumArgs() == 0) {
533 Out << 'v';
534 return;
535 }
536
Douglas Gregor72564e72009-02-26 23:50:07 +0000537 for (FunctionProtoType::arg_type_iterator Arg = Proto->arg_type_begin(),
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000538 ArgEnd = Proto->arg_type_end();
539 Arg != ArgEnd; ++Arg)
540 mangleType(*Arg);
Douglas Gregor219cc612009-02-13 01:28:03 +0000541
542 // <builtin-type> ::= z # ellipsis
543 if (Proto->isVariadic())
544 Out << 'z';
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000545}
546
547void CXXNameMangler::mangleType(const TagType *T) {
548 // <class-enum-type> ::= <name>
Anders Carlsson4843e582009-03-10 17:07:44 +0000549
550 if (!T->getDecl()->getIdentifier())
551 mangleName(T->getDecl()->getTypedefForAnonDecl());
552 else
553 mangleName(T->getDecl());
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000554}
555
556void CXXNameMangler::mangleType(const ArrayType *T) {
557 // <array-type> ::= A <positive dimension number> _ <element type>
558 // ::= A [<dimension expression>] _ <element type>
559 Out << 'A';
560 if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(T))
561 Out << CAT->getSize();
562 else if (const VariableArrayType *VAT = dyn_cast<VariableArrayType>(T))
563 mangleExpression(VAT->getSizeExpr());
564 else if (const DependentSizedArrayType *DSAT
565 = dyn_cast<DependentSizedArrayType>(T))
566 mangleExpression(DSAT->getSizeExpr());
567
568 Out << '_';
569 mangleType(T->getElementType());
570}
571
572void CXXNameMangler::mangleType(const MemberPointerType *T) {
573 // <pointer-to-member-type> ::= M <class type> <member type>
574 Out << 'M';
575 mangleType(QualType(T->getClass(), 0));
576 mangleType(T->getPointeeType());
577}
578
579void CXXNameMangler::mangleType(const TemplateTypeParmType *T) {
580 // <template-param> ::= T_ # first template parameter
581 // ::= T <parameter-2 non-negative number> _
582 if (T->getIndex() == 0)
583 Out << "T_";
584 else
585 Out << 'T' << (T->getIndex() - 1) << '_';
586}
587
Anders Carlssona40c5e42009-03-07 22:03:21 +0000588void CXXNameMangler::mangleType(const ObjCInterfaceType *T) {
589 mangleSourceName(T->getDecl()->getIdentifier());
590}
591
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000592void CXXNameMangler::mangleExpression(Expr *E) {
593 assert(false && "Cannot mangle expressions yet");
594}
595
Anders Carlsson3ac86b52009-04-15 05:36:58 +0000596void CXXNameMangler::mangleCXXCtorType(CXXCtorType T) {
597 // <ctor-dtor-name> ::= C1 # complete object constructor
598 // ::= C2 # base object constructor
599 // ::= C3 # complete object allocating constructor
600 //
601 switch (T) {
602 case Ctor_Complete:
603 Out << "C1";
604 break;
605 case Ctor_Base:
606 Out << "C2";
607 break;
608 case Ctor_CompleteAllocating:
609 Out << "C3";
610 break;
611 }
612}
613
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000614namespace clang {
615 /// \brief Mangles the name of the declaration D and emits that name
616 /// to the given output stream.
617 ///
618 /// If the declaration D requires a mangled name, this routine will
619 /// emit that mangled name to \p os and return true. Otherwise, \p
620 /// os will be unchanged and this routine will return false. In this
621 /// case, the caller should just emit the identifier of the declaration
622 /// (\c D->getIdentifier()) as its name.
623 bool mangleName(const NamedDecl *D, ASTContext &Context,
624 llvm::raw_ostream &os) {
625 CXXNameMangler Mangler(Context, os);
Douglas Gregor6ec36682009-02-18 23:53:56 +0000626 if (!Mangler.mangle(D))
627 return false;
628
629 os.flush();
630 return true;
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000631 }
Anders Carlsson41aa8c12009-04-13 18:02:10 +0000632
Anders Carlsson3ac86b52009-04-15 05:36:58 +0000633 /// mangleGuardVariable - Returns the mangled name for a guard variable
634 /// for the passed in VarDecl.
Anders Carlsson41aa8c12009-04-13 18:02:10 +0000635 void mangleGuardVariable(const VarDecl *D, ASTContext &Context,
636 llvm::raw_ostream &os) {
637 CXXNameMangler Mangler(Context, os);
638 Mangler.mangleGuardVariable(D);
639
640 os.flush();
641 }
Anders Carlsson3ac86b52009-04-15 05:36:58 +0000642
643 void mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type,
644 ASTContext &Context, llvm::raw_ostream &os) {
645 CXXNameMangler Mangler(Context, os);
646 Mangler.mangleCXXCtor(D, Type);
647
648 os.flush();
649 }
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000650}
651