]>
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-2020 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
.dim
; 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::cppFundamentalType(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
->dim
; 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
->dim
; 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
->dim
== 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
->dim
== 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
->dim
== 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
->dim
== 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>
585 * <encoding> ::= <function name> <bare-function-type>
589 TypeFunction
*tf
= (TypeFunction
*)d
->type
;
591 buf
->writestring("_Z");
592 if (getFuncTemplateDecl(d
))
594 /* It's an instance of a function template
596 TemplateInstance
*ti
= d
->parent
->isTemplateInstance();
598 Dsymbol
*p
= ti
->toParent3();
599 if (p
&& !p
->isModule() && tf
->linkage
== LINKcpp
)
602 CV_qualifiers(d
->type
);
604 if (d
->isCtorDeclaration())
605 buf
->writestring("C1");
606 else if (d
->isDtorDeclaration())
607 buf
->writestring("D1");
614 headOfType(tf
->nextOf()); // mangle return type
618 Dsymbol
*p
= d
->toParent3();
619 if (p
&& !p
->isModule() && tf
->linkage
== LINKcpp
)
621 /* <nested-name> ::= N [<CV-qualifiers>] <prefix> <unqualified-name> E
622 * ::= N [<CV-qualifiers>] <template-prefix> <template-args> E
625 CV_qualifiers(d
->type
);
627 /* <prefix> ::= <prefix> <unqualified-name>
628 * ::= <template-prefix> <template-args>
629 * ::= <template-param>
632 * ::= <prefix> <data-member-prefix>
635 //printf("p: %s\n", buf.peekString());
637 if (d
->isCtorDeclaration())
639 buf
->writestring("C1");
641 else if (d
->isDtorDeclaration())
643 buf
->writestring("D1");
657 if (tf
->linkage
== LINKcpp
) //Template args accept extern "C" symbols with special mangling
659 assert(tf
->ty
== Tfunction
);
660 mangleFunctionParameters(tf
->parameters
, tf
->varargs
);
664 void mangleFunctionParameters(Parameters
*parameters
, int varargs
)
666 struct ParamsCppMangle
669 CppMangleVisitor
*mangler
;
671 static int dg(void *ctx
, size_t, Parameter
*fparam
)
673 ParamsCppMangle
*p
= (ParamsCppMangle
*)ctx
;
674 CppMangleVisitor
*mangler
= p
->mangler
;
675 Type
*t
= Target::cppParameterType(fparam
);
676 if (t
->ty
== Tsarray
)
678 // Static arrays in D are passed by value; no counterpart in C++
679 t
->error(mangler
->loc
, "Internal Compiler Error: unable to pass static array `%s` to extern(C++) function, use pointer instead",
683 mangler
->headOfType(t
);
694 Parameter_foreach(parameters
, &ParamsCppMangle::dg
, (void*)&p
);
698 else if (!p
.numparams
)
699 buf
->writeByte('v'); // encode (void) parameters
703 CppMangleVisitor(OutBuffer
*buf
, Loc loc
)
704 : components(), buf(buf
), loc(loc
)
709 * Entry point. Append mangling to buf[]
711 * s = symbol to mangle
713 void mangleOf(Dsymbol
*s
)
715 if (VarDeclaration
*vd
= s
->isVarDeclaration())
717 mangle_variable(vd
, false);
719 else if (FuncDeclaration
*fd
= s
->isFuncDeclaration())
729 /****** The rest is type mangling ************/
734 if (t
->isImmutable())
736 else if (t
->isShared())
740 t
->error(loc
, "Internal Compiler Error: %stype `%s` can not be mapped to C++", p
, t
->toChars());
741 fatal(); //Fatal, because this error should be handled in frontend
744 /****************************
746 * treating it as a Head followed by a Tail.
750 void headOfType(Type
*t
)
754 mangleTypeClass((TypeClass
*)t
, true);
758 // For value types, strip const/immutable/shared from the head of the type
759 t
->mutableOf()->unSharedOf()->accept(this);
769 * Write out 1 or 2 character basic type mangling.
770 * Handle const and substitutions.
773 * p = if not 0, then character prefix
774 * c = mangling character
776 void writeBasicType(Type
*t
, char p
, char c
)
778 // Only do substitutions for non-fundamental types.
779 if (!isFundamentalType(t
) || t
->isConst())
792 void visit(TypeNull
*t
)
794 if (t
->isImmutable() || t
->isShared())
797 writeBasicType(t
, 'D', 'n');
800 void visit(TypeBasic
*t
)
802 if (t
->isImmutable() || t
->isShared())
805 // Handle any target-specific basic types.
806 if (const char *tm
= Target::cppTypeMangle(t
))
808 // Only do substitutions for non-fundamental types.
809 if (!isFundamentalType(t
) || t
->isConst())
817 buf
->writestring(tm
);
834 * x long long, __int64
835 * y unsigned long long, __int64
837 * o unsigned __int128
840 * e long double, __float80
843 * Dd 64 bit IEEE 754r decimal floating point
844 * De 128 bit IEEE 754r decimal floating point
845 * Df 32 bit IEEE 754r decimal floating point
846 * Dh 16 bit IEEE 754r half-precision floating point
849 * u <source-name> # vendor extended type
856 case Tvoid
: c
= 'v'; break;
857 case Tint8
: c
= 'a'; break;
858 case Tuns8
: c
= 'h'; break;
859 case Tint16
: c
= 's'; break;
860 case Tuns16
: c
= 't'; break;
861 case Tint32
: c
= 'i'; break;
862 case Tuns32
: c
= 'j'; break;
863 case Tfloat32
: c
= 'f'; break;
865 c
= (Target::c_longsize
== 8 ? 'l' : 'x');
868 c
= (Target::c_longsize
== 8 ? 'm' : 'y');
870 case Tint128
: c
= 'n'; break;
871 case Tuns128
: c
= 'o'; break;
872 case Tfloat64
: c
= 'd'; break;
873 case Tfloat80
: c
= 'e'; break;
874 case Tbool
: c
= 'b'; break;
875 case Tchar
: c
= 'c'; break;
876 case Twchar
: c
= 't'; break; // unsigned short (perhaps use 'Ds' ?
877 case Tdchar
: c
= 'w'; break; // wchar_t (UTF-32) (perhaps use 'Di' ?
878 case Timaginary32
: p
= 'G'; c
= 'f'; break; // 'G' means imaginary
879 case Timaginary64
: p
= 'G'; c
= 'd'; break;
880 case Timaginary80
: p
= 'G'; c
= 'e'; break;
881 case Tcomplex32
: p
= 'C'; c
= 'f'; break; // 'C' means complex
882 case Tcomplex64
: p
= 'C'; c
= 'd'; break;
883 case Tcomplex80
: p
= 'C'; c
= 'e'; break;
888 writeBasicType(t
, p
, c
);
891 void visit(TypeVector
*t
)
893 if (t
->isImmutable() || t
->isShared())
901 // Handle any target-specific vector types.
902 if (const char *tm
= Target::cppTypeMangle(t
))
904 buf
->writestring(tm
);
908 assert(t
->basetype
&& t
->basetype
->ty
== Tsarray
);
909 assert(((TypeSArray
*)t
->basetype
)->dim
);
910 buf
->writestring("U8__vector"); //-- Gnu ABI v.3
911 t
->basetype
->nextOf()->accept(this);
915 void visit(TypeSArray
*t
)
917 if (t
->isImmutable() || t
->isShared())
924 buf
->printf("%llu", t
->dim
? t
->dim
->toInteger() : 0);
926 t
->next
->accept(this);
929 void visit(TypePointer
*t
)
931 if (t
->isImmutable() || t
->isShared())
938 t
->next
->accept(this);
942 void visit(TypeReference
*t
)
944 //printf("TypeReference %s\n", t->toChars());
948 t
->next
->accept(this);
952 void visit(TypeFunction
*t
)
955 * <function-type> ::= F [Y] <bare-function-type> E
956 * <bare-function-type> ::= <signature type>+
957 * # types are possible return type, then parameter types
961 "The type of a non-static member function is considered to be different,
962 for the purposes of substitution, from the type of a namespace-scope or
963 static member function whose type appears similar. The types of two
964 non-static member functions are considered to be different, for the
965 purposes of substitution, if the functions are members of different
966 classes. In other words, for the purposes of substitution, the class of
967 which the function is a member is considered part of the type of
970 BUG: Right now, types of functions are never merged, so our simplistic
971 component matcher always finds them to be different.
972 We should use Type::equals on these, and use different
973 TypeFunctions for non-static member functions, and non-static
974 member functions of different classes.
979 if (t
->linkage
== LINKc
)
983 tn
= tn
->referenceTo();
985 mangleFunctionParameters(t
->parameters
, t
->varargs
);
990 void visit(TypeStruct
*t
)
992 if (t
->isImmutable() || t
->isShared())
995 //printf("TypeStruct %s\n", t->toChars());
1000 void visit(TypeEnum
*t
)
1002 if (t
->isImmutable() || t
->isShared())
1005 /* __c_(u)long(long) get special mangling
1007 Identifier
*id
= t
->sym
->ident
;
1008 //printf("enum id = '%s'\n", id->toChars());
1009 if (id
== Id::__c_long
)
1010 return writeBasicType(t
, 0, 'l');
1011 else if (id
== Id::__c_ulong
)
1012 return writeBasicType(t
, 0, 'm');
1013 else if (id
== Id::__c_longlong
)
1014 return writeBasicType(t
, 0, 'x');
1015 else if (id
== Id::__c_ulonglong
)
1016 return writeBasicType(t
, 0, 'y');
1022 * Write structs and enums.
1024 * t = TypeStruct or TypeEnum
1026 void doSymbol(Type
*t
)
1032 // Handle any target-specific struct types.
1033 if (const char *tm
= Target::cppTypeMangle(t
))
1035 buf
->writestring(tm
);
1039 Dsymbol
*s
= t
->toDsymbol(NULL
);
1040 Dsymbol
*p
= s
->toParent3();
1041 if (p
&& p
->isTemplateInstance())
1043 /* https://issues.dlang.org/show_bug.cgi?id=17947
1044 * Substitute the template instance symbol, not the struct/enum symbol
1051 cpp_mangle_name(s
, t
->isConst());
1058 void visit(TypeClass
*t
)
1060 mangleTypeClass(t
, false);
1063 /************************
1064 * Mangle a class type.
1065 * If it's the head, treat the initial pointer as a value type.
1068 * head = true for head of a type
1070 void mangleTypeClass(TypeClass
*t
, bool head
)
1072 if (t
->isImmutable() || t
->isShared())
1075 /* Mangle as a <pointer to><struct>
1081 buf
->writeByte('P');
1086 Dsymbol
*s
= t
->toDsymbol(NULL
);
1087 Dsymbol
*p
= s
->toParent3();
1088 if (p
&& p
->isTemplateInstance())
1090 /* https://issues.dlang.org/show_bug.cgi?id=17947
1091 * Substitute the template instance symbol, not the class symbol
1098 if (!substitute(t
->sym
))
1100 cpp_mangle_name(t
->sym
, t
->isConst());
1103 append(NULL
); // C++ would have an extra type here
1107 const char *mangle_typeinfo(Dsymbol
*s
)
1109 buf
->writestring("_ZTI");
1110 cpp_mangle_name(s
, false);
1111 return buf
->extractString();
1115 const char *toCppMangleItanium(Dsymbol
*s
)
1117 //printf("toCppMangleItanium(%s)\n", s->toChars());
1119 CppMangleVisitor
v(&buf
, s
->loc
);
1121 return buf
.extractString();
1124 const char *cppTypeInfoMangleItanium(Dsymbol
*s
)
1126 //printf("cppTypeInfoMangleItanium(%s)\n", s->toChars());
1128 buf
.writestring("_ZTI"); // "TI" means typeinfo structure
1129 CppMangleVisitor
v(&buf
, s
->loc
);
1130 v
.cpp_mangle_name(s
, false);
1131 return buf
.extractString();