]>
git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/d/dmd/cppmangle.c
2 /* Compiler implementation of the D programming language
3 * Copyright (C) 1999-2021 by The D Language Foundation, All Rights Reserved
4 * written by Walter Bright
5 * http://www.digitalmars.com
6 * Distributed under the Boost Software License, Version 1.0.
7 * http://www.boost.org/LICENSE_1_0.txt
8 * https://github.com/D-Programming-Language/dmd/blob/master/src/cppmangle.c
12 * Do mangling for C++ linkage.
15 * Follows Itanium C++ ABI 1.86 section 5.1
16 * http://refspecs.linux-foundation.org/cxxabi-1.86.html#mangling
17 * which is where the grammar comments come from.
20 * https://issues.dlang.org/query.cgi
21 * enter `C++, mangling` as the keywords.
24 #include "root/dsystem.h"
31 #include "expression.h"
33 #include "declaration.h"
38 #include "aggregate.h"
41 typedef int (*ForeachDg
)(void *ctx
, size_t paramidx
, Parameter
*param
);
42 int Parameter_foreach(Parameters
*parameters
, ForeachDg dg
, void *ctx
, size_t *pn
= NULL
);
44 class CppMangleVisitor
: public Visitor
46 Objects components
; // array of components available for substitution
47 OutBuffer
*buf
; // append the mangling to buf[]
49 Loc loc
; // location for use in error messages
51 // Write <seq-id> to buf
52 void write_seq_id(size_t i
)
59 i
+= (i
< 10) ? '0' : 'A' - 10;
60 buf
->writeByte((char)i
);
63 bool substitute(RootObject
*p
)
65 //printf("substitute %s\n", p ? p->toChars() : NULL);
69 //printf("\tmatch\n");
70 /* Sequence is S_, S0_, .., S9_, SA_, ..., SZ_, S10_, ...
84 * See if `p` exists in components[]
86 * index if found, -1 if not
88 int find(RootObject
*p
)
90 //printf("find %p %d %s\n", p, p.dyncast(), p ? p.toChars() : NULL);
91 for (size_t i
= 0; i
< components
.length
; i
++)
93 if (p
== components
[i
])
99 /*********************
100 * Append p to components[]
102 void append(RootObject
*p
)
104 //printf("append %p %d %s\n", p, p.dyncast(), p ? p.toChars() : "null");
108 /************************
109 * Determine if symbol is indeed the global ::std namespace.
111 * s = symbol to check
113 * true if it is ::std
115 static bool isStd(Dsymbol
*s
)
118 s
->ident
== Id::std
&& // the right name
119 s
->isNspace() && // g++ disallows global "std" for other than a namespace
120 !getQualifier(s
)); // at global level
123 /************************
124 * Determine if type is a C++ fundamental type.
128 * true if it is a fundamental type
130 static bool isFundamentalType(Type
*t
)
132 // First check the target whether some specific ABI is being followed.
134 if (target
.cpp
.fundamentalType(t
, isFundamental
))
135 return isFundamental
;
138 // Peel off enum type from special types.
139 TypeEnum
*te
= (TypeEnum
*)t
;
140 if (te
->sym
->isSpecial())
141 t
= te
->sym
->getMemtype(Loc());
144 // Fundamental arithmetic types:
145 // 1. integral types: bool, char, int, ...
146 // 2. floating point types: float, double, real
148 // 4. null pointer: std::nullptr_t (since C++11)
149 if (t
->ty
== Tvoid
|| t
->ty
== Tbool
)
151 else if (t
->ty
== Tnull
&& global
.params
.cplusplus
>= CppStdRevisionCpp11
)
154 return t
->isTypeBasic() && (t
->isintegral() || t
->isreal());
157 /******************************
158 * Write the mangled representation of the template arguments.
160 * ti = the template instance
162 void template_args(TemplateInstance
*ti
)
164 /* <template-args> ::= I <template-arg>+ E
166 if (!ti
) // could happen if std::basic_string is not a template
169 for (size_t i
= 0; i
< ti
->tiargs
->length
; i
++)
171 RootObject
*o
= (*ti
->tiargs
)[i
];
172 TemplateDeclaration
*td
= ti
->tempdecl
->isTemplateDeclaration();
174 TemplateParameter
*tp
= (*td
->parameters
)[i
];
177 * <template-arg> ::= <type> # type or template
178 * ::= X <expression> E # expression
179 * ::= <expr-primary> # simple expressions
180 * ::= I <template-arg>* E # argument pack
182 if (tp
->isTemplateTupleParameter())
184 buf
->writeByte('I'); // argument pack
186 // mangle the rest of the arguments as types
187 for (size_t j
= i
; j
< ti
->tiargs
->length
; j
++)
189 Type
*t
= isType((*ti
->tiargs
)[j
]);
197 if (tp
->isTemplateTypeParameter())
203 else if (TemplateValueParameter
*tv
= tp
->isTemplateValueParameter())
205 // <expr-primary> ::= L <type> <value number> E # integer literal
206 if (tv
->valType
->isintegral())
208 Expression
*e
= isExpression(o
);
211 tv
->valType
->accept(this);
212 uinteger_t val
= e
->toUInteger();
213 if (!tv
->valType
->isunsigned() && (sinteger_t
)val
< 0)
218 buf
->printf("%llu", val
);
223 ti
->error("Internal Compiler Error: C++ `%s` template value parameter is not supported", tv
->valType
->toChars());
227 else if (tp
->isTemplateAliasParameter())
229 Dsymbol
*d
= isDsymbol(o
);
230 Expression
*e
= isExpression(o
);
231 if (d
&& d
->isFuncDeclaration())
233 bool is_nested
= d
->toParent3() &&
234 !d
->toParent3()->isModule() &&
235 ((TypeFunction
*)d
->isFuncDeclaration()->type
)->linkage
== LINKcpp
;
239 mangle_function(d
->isFuncDeclaration());
244 else if (e
&& e
->op
== TOKvar
&& ((VarExp
*)e
)->var
->isVarDeclaration())
246 VarDeclaration
*vd
= ((VarExp
*)e
)->var
->isVarDeclaration();
248 mangle_variable(vd
, true);
251 else if (d
&& d
->isTemplateDeclaration() && d
->isTemplateDeclaration()->onemember
)
255 cpp_mangle_name(d
, false);
260 ti
->error("Internal Compiler Error: `%s` is unsupported parameter for C++ template", o
->toChars());
264 else if (tp
->isTemplateThisParameter())
266 ti
->error("Internal Compiler Error: C++ `%s` template this parameter is not supported", o
->toChars());
277 void source_name(Dsymbol
*s
)
279 //printf("source_name(%s)\n", s->toChars());
280 if (TemplateInstance
*ti
= s
->isTemplateInstance())
282 if (!substitute(ti
->tempdecl
))
284 append(ti
->tempdecl
);
285 const char *name
= ti
->tempdecl
->toAlias()->ident
->toChars();
286 buf
->printf("%d", strlen(name
));
287 buf
->writestring(name
);
293 const char *name
= s
->ident
->toChars();
294 buf
->printf("%d", strlen(name
));
295 buf
->writestring(name
);
300 * See if s is actually an instance of a template
304 * if s is instance of a template, return the instance, otherwise return s
306 Dsymbol
*getInstance(Dsymbol
*s
)
308 Dsymbol
*p
= s
->toParent3();
311 if (TemplateInstance
*ti
= p
->isTemplateInstance())
318 * Get qualifier for `s`, meaning the symbol
319 * that s is in the symbol table of.
320 * The module does not count as a qualifier, because C++
321 * does not have modules.
323 * s = symbol that may have a qualifier
325 * qualifier, NULL if none
327 static Dsymbol
*getQualifier(Dsymbol
*s
)
329 Dsymbol
*p
= s
->toParent3();
330 return (p
&& !p
->isModule()) ? p
: NULL
;
334 static bool isChar(RootObject
*o
)
337 return (t
&& t
->equals(Type::tchar
));
340 // Detect type ::std::char_traits<char>
341 static bool isChar_traits_char(RootObject
*o
)
343 return isIdent_char(Id::char_traits
, o
);
346 // Detect type ::std::allocator<char>
347 static bool isAllocator_char(RootObject
*o
)
349 return isIdent_char(Id::allocator
, o
);
352 // Detect type ::std::ident<char>
353 static bool isIdent_char(Identifier
*ident
, RootObject
*o
)
356 if (!t
|| t
->ty
!= Tstruct
)
358 Dsymbol
*s
= ((TypeStruct
*)t
)->toDsymbol(NULL
);
359 if (s
->ident
!= ident
)
361 Dsymbol
*p
= s
->toParent3();
364 TemplateInstance
*ti
= p
->isTemplateInstance();
367 Dsymbol
*q
= getQualifier(ti
);
368 return isStd(q
) && ti
->tiargs
->length
== 1 && isChar((*ti
->tiargs
)[0]);
372 * Detect template args <char, ::std::char_traits<char>>
373 * and write st if found.
377 bool char_std_char_traits_char(TemplateInstance
*ti
, const char *st
)
379 if (ti
->tiargs
->length
== 2 &&
380 isChar((*ti
->tiargs
)[0]) &&
381 isChar_traits_char((*ti
->tiargs
)[1]))
383 buf
->writestring(st
);
390 void prefix_name(Dsymbol
*s
)
392 //printf("prefix_name(%s)\n", s->toChars());
395 Dsymbol
*si
= getInstance(s
);
396 Dsymbol
*p
= getQualifier(si
);
401 TemplateInstance
*ti
= si
->isTemplateInstance();
404 if (s
->ident
== Id::allocator
)
406 buf
->writestring("Sa");
411 if (s
->ident
== Id::basic_string
)
413 // ::std::basic_string<char, ::std::char_traits<char>, ::std::allocator<char>>
414 if (ti
->tiargs
->length
== 3 &&
415 isChar((*ti
->tiargs
)[0]) &&
416 isChar_traits_char((*ti
->tiargs
)[1]) &&
417 isAllocator_char((*ti
->tiargs
)[2]))
420 buf
->writestring("Ss");
423 buf
->writestring("Sb"); // ::std::basic_string
429 // ::std::basic_istream<char, ::std::char_traits<char>>
430 if (s
->ident
== Id::basic_istream
&&
431 char_std_char_traits_char(ti
, "Si"))
434 // ::std::basic_ostream<char, ::std::char_traits<char>>
435 if (s
->ident
== Id::basic_ostream
&&
436 char_std_char_traits_char(ti
, "So"))
439 // ::std::basic_iostream<char, ::std::char_traits<char>>
440 if (s
->ident
== Id::basic_iostream
&&
441 char_std_char_traits_char(ti
, "Sd"))
444 buf
->writestring("St");
452 /* Do this after the source_name() call to keep components[]
453 * in the right order.
454 * https://issues.dlang.org/show_bug.cgi?id=17947
461 void cpp_mangle_name(Dsymbol
*s
, bool qualified
)
463 //printf("cpp_mangle_name(%s, %d)\n", s->toChars(), qualified);
464 Dsymbol
*p
= s
->toParent3();
466 bool write_prefix
= true;
467 if (p
&& p
->isTemplateInstance())
470 if (find(p
->isTemplateInstance()->tempdecl
) >= 0)
471 write_prefix
= false;
475 if (p
&& !p
->isModule())
477 /* The N..E is not required if:
478 * 1. the parent is 'std'
479 * 2. 'std' is the initial qualifier
480 * 3. there is no CV-qualifier or a ref-qualifier for a member function
483 if (isStd(p
) && !qualified
)
485 TemplateInstance
*ti
= se
->isTemplateInstance();
486 if (s
->ident
== Id::allocator
)
488 buf
->writestring("Sa"); // "Sa" is short for ::std::allocator
491 else if (s
->ident
== Id::basic_string
)
493 // ::std::basic_string<char, ::std::char_traits<char>, ::std::allocator<char>>
494 if (ti
->tiargs
->length
== 3 &&
495 isChar((*ti
->tiargs
)[0]) &&
496 isChar_traits_char((*ti
->tiargs
)[1]) &&
497 isAllocator_char((*ti
->tiargs
)[2]))
500 buf
->writestring("Ss");
503 buf
->writestring("Sb"); // ::std::basic_string
508 // ::std::basic_istream<char, ::std::char_traits<char>>
509 if (s
->ident
== Id::basic_istream
)
511 if (char_std_char_traits_char(ti
, "Si"))
514 else if (s
->ident
== Id::basic_ostream
)
516 if (char_std_char_traits_char(ti
, "So"))
519 else if (s
->ident
== Id::basic_iostream
)
521 if (char_std_char_traits_char(ti
, "Sd"))
524 buf
->writestring("St");
542 void CV_qualifiers(Type
*t
)
544 // CV-qualifiers are 'r': restrict, 'V': volatile, 'K': const
549 void mangle_variable(VarDeclaration
*d
, bool is_temp_arg_ref
)
551 // fake mangling for fields to fix https://issues.dlang.org/show_bug.cgi?id=16525
552 if (!(d
->storage_class
& (STCextern
| STCfield
| STCgshared
)))
554 d
->error("Internal Compiler Error: C++ static non-`__gshared` non-`extern` variables not supported");
558 Dsymbol
*p
= d
->toParent3();
559 if (p
&& !p
->isModule()) //for example: char Namespace1::beta[6] should be mangled as "_ZN10Namespace14betaE"
561 buf
->writestring("_ZN");
566 else //char beta[6] should mangle as "beta"
568 if (!is_temp_arg_ref
)
570 buf
->writestring(d
->ident
->toChars());
574 buf
->writestring("_Z");
580 void mangle_function(FuncDeclaration
*d
)
582 //printf("mangle_function(%s)\n", d->toChars());
584 * <mangled-name> ::= _Z <encoding>
586 buf
->writestring("_Z");
587 this->mangle_function_encoding(d
);
590 void mangle_function_encoding(FuncDeclaration
*d
)
592 //printf("mangle_function_encoding(%s)\n", d->toChars());
594 * <encoding> ::= <function name> <bare-function-type>
598 TypeFunction
*tf
= (TypeFunction
*)d
->type
;
600 if (getFuncTemplateDecl(d
))
602 /* It's an instance of a function template
604 TemplateInstance
*ti
= d
->parent
->isTemplateInstance();
606 Dsymbol
*p
= ti
->toParent3();
607 if (p
&& !p
->isModule() && tf
->linkage
== LINKcpp
)
610 CV_qualifiers(d
->type
);
612 if (d
->isCtorDeclaration())
613 buf
->writestring("C1");
614 else if (d
->isDtorDeclaration())
615 buf
->writestring("D1");
622 headOfType(tf
->nextOf()); // mangle return type
626 Dsymbol
*p
= d
->toParent3();
627 if (p
&& !p
->isModule() && tf
->linkage
== LINKcpp
)
629 /* <nested-name> ::= N [<CV-qualifiers>] <prefix> <unqualified-name> E
630 * ::= N [<CV-qualifiers>] <template-prefix> <template-args> E
633 CV_qualifiers(d
->type
);
635 /* <prefix> ::= <prefix> <unqualified-name>
636 * ::= <template-prefix> <template-args>
637 * ::= <template-param>
640 * ::= <prefix> <data-member-prefix>
643 //printf("p: %s\n", buf.peekChars());
645 if (d
->isCtorDeclaration())
647 buf
->writestring("C1");
649 else if (d
->isDtorDeclaration())
651 buf
->writestring("D1");
665 if (tf
->linkage
== LINKcpp
) //Template args accept extern "C" symbols with special mangling
667 assert(tf
->ty
== Tfunction
);
668 mangleFunctionParameters(tf
->parameterList
.parameters
,
669 tf
->parameterList
.varargs
);
673 void mangleFunctionParameters(Parameters
*parameters
, int varargs
)
675 struct ParamsCppMangle
678 CppMangleVisitor
*mangler
;
680 static int dg(void *ctx
, size_t, Parameter
*fparam
)
682 ParamsCppMangle
*p
= (ParamsCppMangle
*)ctx
;
683 CppMangleVisitor
*mangler
= p
->mangler
;
684 Type
*t
= target
.cpp
.parameterType(fparam
);
685 if (t
->ty
== Tsarray
)
687 // Static arrays in D are passed by value; no counterpart in C++
688 t
->error(mangler
->loc
, "Internal Compiler Error: unable to pass static array `%s` to extern(C++) function, use pointer instead",
692 mangler
->headOfType(t
);
703 Parameter_foreach(parameters
, &ParamsCppMangle::dg
, (void*)&p
);
707 else if (!p
.numparams
)
708 buf
->writeByte('v'); // encode (void) parameters
712 CppMangleVisitor(OutBuffer
*buf
, Loc loc
)
713 : components(), buf(buf
), loc(loc
)
718 * Entry point. Append mangling to buf[]
720 * s = symbol to mangle
722 void mangleOf(Dsymbol
*s
)
724 if (VarDeclaration
*vd
= s
->isVarDeclaration())
726 mangle_variable(vd
, false);
728 else if (FuncDeclaration
*fd
= s
->isFuncDeclaration())
738 /****** The rest is type mangling ************/
743 if (t
->isImmutable())
745 else if (t
->isShared())
749 t
->error(loc
, "Internal Compiler Error: %stype `%s` can not be mapped to C++", p
, t
->toChars());
750 fatal(); //Fatal, because this error should be handled in frontend
753 /****************************
755 * treating it as a Head followed by a Tail.
759 void headOfType(Type
*t
)
763 mangleTypeClass((TypeClass
*)t
, true);
767 // For value types, strip const/immutable/shared from the head of the type
768 t
->mutableOf()->unSharedOf()->accept(this);
778 * Write out 1 or 2 character basic type mangling.
779 * Handle const and substitutions.
782 * p = if not 0, then character prefix
783 * c = mangling character
785 void writeBasicType(Type
*t
, char p
, char c
)
787 // Only do substitutions for non-fundamental types.
788 if (!isFundamentalType(t
) || t
->isConst())
801 void visit(TypeNull
*t
)
803 if (t
->isImmutable() || t
->isShared())
806 writeBasicType(t
, 'D', 'n');
809 void visit(TypeNoreturn
*t
)
811 if (t
->isImmutable() || t
->isShared())
814 writeBasicType(t
, 0, 'v'); // mangle like `void`
817 void visit(TypeBasic
*t
)
819 if (t
->isImmutable() || t
->isShared())
822 // Handle any target-specific basic types.
823 if (const char *tm
= target
.cpp
.typeMangle(t
))
825 // Only do substitutions for non-fundamental types.
826 if (!isFundamentalType(t
) || t
->isConst())
834 buf
->writestring(tm
);
851 * x long long, __int64
852 * y unsigned long long, __int64
854 * o unsigned __int128
857 * e long double, __float80
860 * Dd 64 bit IEEE 754r decimal floating point
861 * De 128 bit IEEE 754r decimal floating point
862 * Df 32 bit IEEE 754r decimal floating point
863 * Dh 16 bit IEEE 754r half-precision floating point
866 * u <source-name> # vendor extended type
873 case Tvoid
: c
= 'v'; break;
874 case Tint8
: c
= 'a'; break;
875 case Tuns8
: c
= 'h'; break;
876 case Tint16
: c
= 's'; break;
877 case Tuns16
: c
= 't'; break;
878 case Tint32
: c
= 'i'; break;
879 case Tuns32
: c
= 'j'; break;
880 case Tfloat32
: c
= 'f'; break;
882 c
= (target
.c
.longsize
== 8 ? 'l' : 'x');
885 c
= (target
.c
.longsize
== 8 ? 'm' : 'y');
887 case Tint128
: c
= 'n'; break;
888 case Tuns128
: c
= 'o'; break;
889 case Tfloat64
: c
= 'd'; break;
890 case Tfloat80
: c
= 'e'; break;
891 case Tbool
: c
= 'b'; break;
892 case Tchar
: c
= 'c'; break;
893 case Twchar
: c
= 't'; break; // unsigned short (perhaps use 'Ds' ?
894 case Tdchar
: c
= 'w'; break; // wchar_t (UTF-32) (perhaps use 'Di' ?
895 case Timaginary32
: p
= 'G'; c
= 'f'; break; // 'G' means imaginary
896 case Timaginary64
: p
= 'G'; c
= 'd'; break;
897 case Timaginary80
: p
= 'G'; c
= 'e'; break;
898 case Tcomplex32
: p
= 'C'; c
= 'f'; break; // 'C' means complex
899 case Tcomplex64
: p
= 'C'; c
= 'd'; break;
900 case Tcomplex80
: p
= 'C'; c
= 'e'; break;
905 writeBasicType(t
, p
, c
);
908 void visit(TypeVector
*t
)
910 if (t
->isImmutable() || t
->isShared())
918 // Handle any target-specific vector types.
919 if (const char *tm
= target
.cpp
.typeMangle(t
))
921 buf
->writestring(tm
);
925 assert(t
->basetype
&& t
->basetype
->ty
== Tsarray
);
926 assert(((TypeSArray
*)t
->basetype
)->dim
);
927 buf
->writestring("U8__vector"); //-- Gnu ABI v.3
928 t
->basetype
->nextOf()->accept(this);
932 void visit(TypeSArray
*t
)
934 if (t
->isImmutable() || t
->isShared())
941 buf
->printf("%llu", t
->dim
? t
->dim
->toInteger() : 0);
943 t
->next
->accept(this);
946 void visit(TypePointer
*t
)
948 if (t
->isImmutable() || t
->isShared())
955 t
->next
->accept(this);
959 void visit(TypeReference
*t
)
961 //printf("TypeReference %s\n", t->toChars());
965 t
->next
->accept(this);
969 void visit(TypeFunction
*t
)
972 * <function-type> ::= F [Y] <bare-function-type> E
973 * <bare-function-type> ::= <signature type>+
974 * # types are possible return type, then parameter types
978 "The type of a non-static member function is considered to be different,
979 for the purposes of substitution, from the type of a namespace-scope or
980 static member function whose type appears similar. The types of two
981 non-static member functions are considered to be different, for the
982 purposes of substitution, if the functions are members of different
983 classes. In other words, for the purposes of substitution, the class of
984 which the function is a member is considered part of the type of
987 BUG: Right now, types of functions are never merged, so our simplistic
988 component matcher always finds them to be different.
989 We should use Type::equals on these, and use different
990 TypeFunctions for non-static member functions, and non-static
991 member functions of different classes.
996 if (t
->linkage
== LINKc
)
1000 tn
= tn
->referenceTo();
1002 mangleFunctionParameters(t
->parameterList
.parameters
,
1003 t
->parameterList
.varargs
);
1004 buf
->writeByte('E');
1008 void visit(TypeStruct
*t
)
1010 if (t
->isImmutable() || t
->isShared())
1013 //printf("TypeStruct %s\n", t->toChars());
1018 void visit(TypeEnum
*t
)
1020 if (t
->isImmutable() || t
->isShared())
1023 /* __c_(u)long(long) and others get special mangling
1025 Identifier
*id
= t
->sym
->ident
;
1026 //printf("enum id = '%s'\n", id->toChars());
1027 if (id
== Id::__c_long
)
1028 return writeBasicType(t
, 0, 'l');
1029 else if (id
== Id::__c_ulong
)
1030 return writeBasicType(t
, 0, 'm');
1031 else if (id
== Id::__c_wchar_t
)
1032 return writeBasicType(t
, 0, 'w');
1033 else if (id
== Id::__c_longlong
)
1034 return writeBasicType(t
, 0, 'x');
1035 else if (id
== Id::__c_ulonglong
)
1036 return writeBasicType(t
, 0, 'y');
1037 else if (id
== Id::__c_complex_float
)
1038 return writeBasicType(t
, 'C', 'f');
1039 else if (id
== Id::__c_complex_double
)
1040 return writeBasicType(t
, 'C', 'd');
1041 else if (id
== Id::__c_complex_real
)
1042 return writeBasicType(t
, 'C', 'e');
1048 * Write structs and enums.
1050 * t = TypeStruct or TypeEnum
1052 void doSymbol(Type
*t
)
1058 // Handle any target-specific struct types.
1059 if (const char *tm
= target
.cpp
.typeMangle(t
))
1061 buf
->writestring(tm
);
1065 Dsymbol
*s
= t
->toDsymbol(NULL
);
1066 Dsymbol
*p
= s
->toParent3();
1067 if (p
&& p
->isTemplateInstance())
1069 /* https://issues.dlang.org/show_bug.cgi?id=17947
1070 * Substitute the template instance symbol, not the struct/enum symbol
1077 cpp_mangle_name(s
, t
->isConst());
1084 void visit(TypeClass
*t
)
1086 mangleTypeClass(t
, false);
1089 /************************
1090 * Mangle a class type.
1091 * If it's the head, treat the initial pointer as a value type.
1094 * head = true for head of a type
1096 void mangleTypeClass(TypeClass
*t
, bool head
)
1098 if (t
->isImmutable() || t
->isShared())
1101 /* Mangle as a <pointer to><struct>
1107 buf
->writeByte('P');
1112 Dsymbol
*s
= t
->toDsymbol(NULL
);
1113 Dsymbol
*p
= s
->toParent3();
1114 if (p
&& p
->isTemplateInstance())
1116 /* https://issues.dlang.org/show_bug.cgi?id=17947
1117 * Substitute the template instance symbol, not the class symbol
1124 if (!substitute(t
->sym
))
1126 cpp_mangle_name(t
->sym
, t
->isConst());
1129 append(NULL
); // C++ would have an extra type here
1133 const char *mangle_typeinfo(Dsymbol
*s
)
1135 buf
->writestring("_ZTI");
1136 cpp_mangle_name(s
, false);
1137 return buf
->extractChars();
1141 const char *toCppMangleItanium(Dsymbol
*s
)
1143 //printf("toCppMangleItanium(%s)\n", s->toChars());
1145 CppMangleVisitor
v(&buf
, s
->loc
);
1147 return buf
.extractChars();
1150 const char *cppTypeInfoMangleItanium(Dsymbol
*s
)
1152 //printf("cppTypeInfoMangleItanium(%s)\n", s->toChars());
1154 buf
.writestring("_ZTI"); // "TI" means typeinfo structure
1155 CppMangleVisitor
v(&buf
, s
->loc
);
1156 v
.cpp_mangle_name(s
, false);
1157 return buf
.extractChars();
1160 const char *cppThunkMangleItanium(FuncDeclaration
*fd
, int offset
)
1162 //printf("cppThunkMangleItanium(%s)\n", fd.toChars());
1164 buf
.printf("_ZThn%u_", offset
); // "Th" means thunk, "n%u" is the call offset
1165 CppMangleVisitor
v(&buf
, fd
->loc
);
1166 v
.mangle_function_encoding(fd
);
1167 return buf
.extractChars();