aboutsummaryrefslogtreecommitdiff
path: root/gcc/d/dmd/cppmangle.c
diff options
context:
space:
mode:
authorIain Buclaw <ibuclaw@gdcproject.org>2019-06-18 20:42:10 +0200
committerIain Buclaw <ibuclaw@gdcproject.org>2021-11-30 16:53:28 +0100
commit5fee5ec362f7a243f459e6378fd49dfc89dc9fb5 (patch)
tree61d1bdbca854a903c0860406f457f06b2040be7a /gcc/d/dmd/cppmangle.c
parentb3f60112edcb85b459e60f66c44a55138b1cef49 (diff)
downloadgcc-5fee5ec362f7a243f459e6378fd49dfc89dc9fb5.zip
gcc-5fee5ec362f7a243f459e6378fd49dfc89dc9fb5.tar.gz
gcc-5fee5ec362f7a243f459e6378fd49dfc89dc9fb5.tar.bz2
d: Import dmd b8384668f, druntime e6caaab9, phobos 5ab9ad256 (v2.098.0-beta.1)
The D front-end is now itself written in D, in order to build GDC, you will need a working GDC compiler (GCC version 9.1 or later). GCC changes: - Add support for bootstrapping the D front-end. These add the required components in order to have a D front-end written in D itself. Because the compiler front-end only depends on the core runtime modules, only libdruntime is built for the bootstrap stages. D front-end changes: - Import dmd v2.098.0-beta.1. Druntime changes: - Import druntime v2.098.0-beta.1. Phobos changes: - Import phobos v2.098.0-beta.1. The jump from v2.076.1 to v2.098.0 covers nearly 4 years worth of development on the D programming language and run-time libraries. ChangeLog: * Makefile.def: Add bootstrap to libbacktrace, libphobos, zlib, and libatomic. * Makefile.in: Regenerate. * Makefile.tpl (POSTSTAGE1_HOST_EXPORTS): Fix command for GDC. (STAGE1_CONFIGURE_FLAGS): Add --with-libphobos-druntime-only if target-libphobos-bootstrap. (STAGE2_CONFIGURE_FLAGS): Likewise. * configure: Regenerate. * configure.ac: Add support for bootstrapping D front-end. config/ChangeLog: * acx.m4 (ACX_PROG_GDC): New m4 function. gcc/ChangeLog: * Makefile.in (GDC): New variable. (GDCFLAGS): New variable. * configure: Regenerate. * configure.ac: Add call to ACX_PROG_GDC. Substitute GDCFLAGS. gcc/d/ChangeLog: * dmd/MERGE: Merge upstream dmd b8384668f. * Make-lang.in (d-warn): Use strict warnings. (DMD_WARN_CXXFLAGS): Remove. (DMD_COMPILE): Remove. (CHECKING_DFLAGS): Define. (WARN_DFLAGS): Define. (ALL_DFLAGS): Define. (DCOMPILE.base): Define. (DCOMPILE): Define. (DPOSTCOMPILE): Define. (DLINKER): Define. (DLLINKER): Define. (D_FRONTEND_OBJS): Add new dmd front-end objects. (D_GENERATED_SRCS): Remove. (D_GENERATED_OBJS): Remove. (D_ALL_OBJS): Remove D_GENERATED_OBJS. (d21$(exeext)): Build using DLLINKER and -static-libphobos. (d.tags): Remove dmd/*.c and dmd/root/*.c. (d.mostlyclean): Remove D_GENERATED_SRCS, d/idgen$(build_exeext), d/impcnvgen$(build_exeext). (D_INCLUDES): Include $(srcdir)/d/dmd/res. (CFLAGS-d/id.o): Remove. (CFLAGS-d/impcnvtab.o): Remove. (d/%.o): Build using DCOMPILE and DPOSTCOMPILE. Update dependencies from d/dmd/%.c to d/dmd/%.d. (d/idgen$(build_exeext)): Remove. (d/impcnvgen$(build_exeext)): Remove. (d/id.c): Remove. (d/id.h): Remove. (d/impcnvtab.c): Remove. (d/%.dmdgen.o): Remove. (D_SYSTEM_H): Remove. (d/idgen.dmdgen.o): Remove. (d/impcnvgen.dmdgen.o): Remove. * config-lang.in (boot_language): New variable. * d-attribs.cc: Include dmd/expression.h. * d-builtins.cc: Include d-frontend.h. (build_frontend_type): Update for new front-end interface. (d_eval_constant_expression): Likewise. (d_build_builtins_module): Likewise. (maybe_set_builtin_1): Likewise. (d_build_d_type_nodes): Likewise. * d-codegen.cc (d_decl_context): Likewise. (declaration_reference_p): Likewise. (declaration_type): Likewise. (parameter_reference_p): Likewise. (parameter_type): Likewise. (get_array_length): Likewise. (build_delegate_cst): Likewise. (build_typeof_null_value): Likewise. (identity_compare_p): Likewise. (lower_struct_comparison): Likewise. (build_filename_from_loc): Likewise. (build_assert_call): Remove LIBCALL_SWITCH_ERROR. (build_bounds_index_condition): Call LIBCALL_ARRAYBOUNDS_INDEXP on bounds error. (build_bounds_slice_condition): Call LIBCALL_ARRAYBOUNDS_SLICEP on bounds error. (array_bounds_check): Update for new front-end interface. (checkaction_trap_p): Handle CHECKACTION_context. (get_function_type): Update for new front-end interface. (d_build_call): Likewise. * d-compiler.cc: Remove include of dmd/scope.h. (Compiler::genCmain): Remove. (Compiler::paintAsType): Update for new front-end interface. (Compiler::onParseModule): Likewise. * d-convert.cc (convert_expr): Remove call to LIBCALL_ARRAYCAST. (convert_for_rvalue): Update for new front-end interface. (convert_for_assignment): Likewise. (convert_for_condition): Likewise. (d_array_convert): Likewise. * d-diagnostic.cc (error): Remove. (errorSupplemental): Remove. (warning): Remove. (warningSupplemental): Remove. (deprecation): Remove. (deprecationSupplemental): Remove. (message): Remove. (vtip): New. * d-frontend.cc (global): Remove. (Global::_init): Remove. (Global::startGagging): Remove. (Global::endGagging): Remove. (Global::increaseErrorCount): Remove. (Loc::Loc): Remove. (Loc::toChars): Remove. (Loc::equals): Remove. (isBuiltin): Update for new front-end interface. (eval_builtin): Likewise. (getTypeInfoType): Likewise. (inlineCopy): Remove. * d-incpath.cc: Include d-frontend.h. (add_globalpaths): Call d_gc_malloc to allocate Strings. (add_filepaths): Likewise. * d-lang.cc: Include dmd/id.h, dmd/root/file.h, d-frontend.h. Remove include of dmd/mars.h, id.h. (entrypoint_module): Remove. (entrypoint_root_module): Remove. (deps_write_string): Update for new front-end interface. (deps_write): Likewise. (d_init_options): Call rt_init. Remove setting global params that are default initialized by the front-end. (d_handle_option): Handle OPT_fcheckaction_, OPT_fdump_c___spec_, OPT_fdump_c___spec_verbose, OPT_fextern_std_, OPT_fpreview, OPT_revert, OPT_fsave_mixins_, and OPT_ftransition. (d_post_options): Propagate dip1021 and dip1000 preview flags to dip25, and flag_diagnostics_show_caret to printErrorContext. (d_add_entrypoint_module): Remove. (d_parse_file): Update for new front-end interface. (d_type_promotes_to): Likewise. (d_types_compatible_p): Likewise. * d-longdouble.cc (CTFloat::zero): Remove. (CTFloat::one): Remove. (CTFloat::minusone): Remove. (CTFloat::half): Remove. * d-system.h (POSIX): Remove. (realpath): Remove. (isalpha): Remove. (isalnum): Remove. (isdigit): Remove. (islower): Remove. (isprint): Remove. (isspace): Remove. (isupper): Remove. (isxdigit): Remove. (tolower): Remove. (_mkdir): Remove. (INT32_MAX): Remove. (INT32_MIN): Remove. (INT64_MIN): Remove. (UINT32_MAX): Remove. (UINT64_MAX): Remove. * d-target.cc: Include calls.h. (target): Remove. (define_float_constants): Remove initialization of snan. (Target::_init): Update for new front-end interface. (Target::isVectorTypeSupported): Likewise. (Target::isVectorOpSupported): Remove cases for unordered operators. (TargetCPP::typeMangle): Update for new front-end interface. (TargetCPP::parameterType): Likewise. (Target::systemLinkage): Likewise. (Target::isReturnOnStack): Likewise. (Target::isCalleeDestroyingArgs): Define. (Target::preferPassByRef): Define. * d-tree.h (d_add_entrypoint_module): Remove. * decl.cc (gcc_attribute_p): Update for new front-end interface. (apply_pragma_crt): Define. (DeclVisitor::visit(PragmaDeclaration *)): Handle pragmas crt_constructor and crt_destructor. (DeclVisitor::visit(TemplateDeclaration *)): Update for new front-end interface. (DeclVisitor::visit): Likewise. (DeclVisitor::finish_vtable): Likewise. (get_symbol_decl): Error if template has more than one nesting context. Update for new front-end interface. (make_thunk): Update for new front-end interface. (get_vtable_decl): Likewise. * expr.cc (ExprVisitor::visit): Likewise. (build_return_dtor): Likewise. * imports.cc (ImportVisitor::visit): Likewise. * intrinsics.cc: Include dmd/expression.h. Remove include of dmd/mangle.h. (maybe_set_intrinsic): Update for new front-end interface. * intrinsics.def (INTRINSIC_ROL): Update intrinsic signature. (INTRINSIC_ROR): Likewise. (INTRINSIC_ROR_TIARG): Likewise. (INTRINSIC_TOPREC): Likewise. (INTRINSIC_TOPRECL): Likewise. (INTRINSIC_TAN): Update intrinsic module and signature. (INTRINSIC_ISNAN): Likewise. (INTRINSIC_ISFINITE): Likewise. (INTRINSIC_COPYSIGN): Define intrinsic. (INTRINSIC_COPYSIGNI): Define intrinsic. (INTRINSIC_EXP): Update intrinsic module. (INTRINSIC_EXPM1): Likewise. (INTRINSIC_EXP2): Likewise. (INTRINSIC_LOG): Likewise. (INTRINSIC_LOG2): Likewise. (INTRINSIC_LOG10): Likewise. (INTRINSIC_POW): Likewise. (INTRINSIC_ROUND): Likewise. (INTRINSIC_FLOORF): Likewise. (INTRINSIC_FLOOR): Likewise. (INTRINSIC_FLOORL): Likewise. (INTRINSIC_CEILF): Likewise. (INTRINSIC_CEIL): Likewise. (INTRINSIC_CEILL): Likewise. (INTRINSIC_TRUNC): Likewise. (INTRINSIC_FMIN): Likewise. (INTRINSIC_FMAX): Likewise. (INTRINSIC_FMA): Likewise. (INTRINSIC_VA_ARG): Update intrinsic signature. (INTRINSIC_VASTART): Likewise. * lang.opt (fcheck=): Add alternate aliases for contract switches. (fcheckaction=): New option. (check_action): New Enum and EnumValue entries. (fdump-c++-spec-verbose): New option. (fdump-c++-spec=): New option. (fextern-std=): New option. (extern_stdcpp): New Enum and EnumValue entries (fpreview=): New options. (frevert=): New options. (fsave-mixins): New option. (ftransition=): Update options. * modules.cc (get_internal_fn): Replace Prot with Visibility. (build_internal_fn): Likewise. (build_dso_cdtor_fn): Likewise. (build_module_tree): Remove check for __entrypoint module. * runtime.def (P5): Define. (ARRAYBOUNDS_SLICEP): Define. (ARRAYBOUNDS_INDEXP): Define. (NEWTHROW): Define. (ADCMP2): Remove. (ARRAYCAST): Remove. (SWITCH_STRING): Remove. (SWITCH_USTRING): Remove. (SWITCH_DSTRING): Remove. (SWITCH_ERROR): Remove. * toir.cc (IRVisitor::visit): Update for new front-end interface. (IRVisitor::check_previous_goto): Remove checks for case and default statements. (IRVisitor::visit(SwitchStatement *)): Remove handling of string switch conditions. * typeinfo.cc: Include d-frontend.h. (get_typeinfo_kind): Update for new front-end interface. (make_frontend_typeinfo): Likewise. (TypeInfoVisitor::visit): Likewise. (builtin_typeinfo_p): Likewise. (get_typeinfo_decl): Likewise. (build_typeinfo): Likewise. * types.cc (valist_array_p): Likewise. (make_array_type): Likewise. (merge_aggregate_types): Likewise. (TypeVisitor::visit(TypeBasic *)): Likewise. (TypeVisitor::visit(TypeFunction *)): Likewise. (TypeVisitor::visit(TypeStruct *)): Update comment. * verstr.h: Removed. * d-frontend.h: New file. gcc/po/ChangeLog: * EXCLUDES: Remove d/dmd sources from list. gcc/testsuite/ChangeLog: * gdc.dg/Wcastresult2.d: Update test. * gdc.dg/asm1.d: Likewise. * gdc.dg/asm2.d: Likewise. * gdc.dg/asm3.d: Likewise. * gdc.dg/gdc282.d: Likewise. * gdc.dg/imports/gdc170.d: Likewise. * gdc.dg/intrinsics.d: Likewise. * gdc.dg/pr101672.d: Likewise. * gdc.dg/pr90650a.d: Likewise. * gdc.dg/pr90650b.d: Likewise. * gdc.dg/pr94777a.d: Likewise. * gdc.dg/pr95250.d: Likewise. * gdc.dg/pr96869.d: Likewise. * gdc.dg/pr98277.d: Likewise. * gdc.dg/pr98457.d: Likewise. * gdc.dg/simd1.d: Likewise. * gdc.dg/simd2a.d: Likewise. * gdc.dg/simd2b.d: Likewise. * gdc.dg/simd2c.d: Likewise. * gdc.dg/simd2d.d: Likewise. * gdc.dg/simd2e.d: Likewise. * gdc.dg/simd2f.d: Likewise. * gdc.dg/simd2g.d: Likewise. * gdc.dg/simd2h.d: Likewise. * gdc.dg/simd2i.d: Likewise. * gdc.dg/simd2j.d: Likewise. * gdc.dg/simd7951.d: Likewise. * gdc.dg/torture/gdc309.d: Likewise. * gdc.dg/torture/pr94424.d: Likewise. * gdc.dg/torture/pr94777b.d: Likewise. * lib/gdc-utils.exp (gdc-convert-args): Handle new compiler options. (gdc-convert-test): Handle CXXFLAGS, EXTRA_OBJC_SOURCES, and ARG_SETS test directives. (gdc-do-test): Only import modules in the test run directory. * gdc.dg/pr94777c.d: New test. * gdc.dg/pr96156b.d: New test. * gdc.dg/pr96157c.d: New test. * gdc.dg/simd_ctfe.d: New test. * gdc.dg/torture/simd17344.d: New test. * gdc.dg/torture/simd20052.d: New test. * gdc.dg/torture/simd6.d: New test. * gdc.dg/torture/simd7.d: New test. libphobos/ChangeLog: * libdruntime/MERGE: Merge upstream druntime e6caaab9. * libdruntime/Makefile.am (D_EXTRA_FLAGS): Build libdruntime with -fpreview=dip1000, -fpreview=fieldwise, and -fpreview=dtorfields. (ALL_DRUNTIME_SOURCES): Add DRUNTIME_DSOURCES_STDCXX. (DRUNTIME_DSOURCES): Update list of C binding modules. (DRUNTIME_DSOURCES_STDCXX): Likewise. (DRUNTIME_DSOURCES_LINUX): Likewise. (DRUNTIME_DSOURCES_OPENBSD): Likewise. (DRUNTIME_DISOURCES): Remove __entrypoint.di. * libdruntime/Makefile.in: Regenerated. * libdruntime/__entrypoint.di: Removed. * libdruntime/gcc/deh.d (_d_isbaseof): Update signature. (_d_createTrace): Likewise. (__gdc_begin_catch): Remove reference to the exception. (_d_throw): Increment reference count of thrown object before unwind. (__gdc_personality): Chain exceptions with Throwable.chainTogether. * libdruntime/gcc/emutls.d: Update imports. * libdruntime/gcc/sections/elf.d: Update imports. (DSO.moduleGroup): Update signature. * libdruntime/gcc/sections/macho.d: Update imports. (DSO.moduleGroup): Update signature. * libdruntime/gcc/sections/pecoff.d: Update imports. (DSO.moduleGroup): Update signature. * src/MERGE: Merge upstream phobos 5ab9ad256. * src/Makefile.am (D_EXTRA_DFLAGS): Add -fpreview=dip1000 and -fpreview=dtorfields flags. (PHOBOS_DSOURCES): Update list of std modules. * src/Makefile.in: Regenerate. * testsuite/lib/libphobos.exp (libphobos-dg-test): Handle assembly compile types. (dg-test): Override. (additional_prunes): Define. (libphobos-dg-prune): Filter any additional_prunes set by tests. * testsuite/libphobos.aa/test_aa.d: Update test. * testsuite/libphobos.druntime/druntime.exp (version_flags): Add -fversion=CoreUnittest. * testsuite/libphobos.druntime_shared/druntime_shared.exp (version_flags): Add -fversion=CoreUnittest -fversion=Shared. * testsuite/libphobos.exceptions/unknown_gc.d: Update test. * testsuite/libphobos.hash/test_hash.d: Update test. * testsuite/libphobos.phobos/phobos.exp (version_flags): Add -fversion=StdUnittest * testsuite/libphobos.phobos_shared/phobos_shared.exp (version_flags): Likewise. * testsuite/libphobos.shared/host.c: Update test. * testsuite/libphobos.shared/load.d: Update test. * testsuite/libphobos.shared/load_13414.d: Update test. * testsuite/libphobos.thread/fiber_guard_page.d: Update test. * testsuite/libphobos.thread/tlsgc_sections.d: Update test. * testsuite/testsuite_flags.in: Add -fpreview=dip1000 to --gdcflags. * testsuite/libphobos.shared/link_mod_collision.d: Removed. * testsuite/libphobos.shared/load_mod_collision.d: Removed. * testsuite/libphobos.betterc/betterc.exp: New test. * testsuite/libphobos.config/config.exp: New test. * testsuite/libphobos.gc/gc.exp: New test. * testsuite/libphobos.imports/imports.exp: New test. * testsuite/libphobos.lifetime/lifetime.exp: New test. * testsuite/libphobos.unittest/unittest.exp: New test.
Diffstat (limited to 'gcc/d/dmd/cppmangle.c')
-rw-r--r--gcc/d/dmd/cppmangle.c1168
1 files changed, 0 insertions, 1168 deletions
diff --git a/gcc/d/dmd/cppmangle.c b/gcc/d/dmd/cppmangle.c
deleted file mode 100644
index baf64c5..0000000
--- a/gcc/d/dmd/cppmangle.c
+++ /dev/null
@@ -1,1168 +0,0 @@
-
-/* Compiler implementation of the D programming language
- * Copyright (C) 1999-2021 by The D Language Foundation, All Rights Reserved
- * written by Walter Bright
- * http://www.digitalmars.com
- * Distributed under the Boost Software License, Version 1.0.
- * http://www.boost.org/LICENSE_1_0.txt
- * https://github.com/D-Programming-Language/dmd/blob/master/src/cppmangle.c
- */
-
-/**
- * Do mangling for C++ linkage.
- *
- * References:
- * Follows Itanium C++ ABI 1.86 section 5.1
- * http://refspecs.linux-foundation.org/cxxabi-1.86.html#mangling
- * which is where the grammar comments come from.
- *
- * Bugs:
- * https://issues.dlang.org/query.cgi
- * enter `C++, mangling` as the keywords.
- */
-
-#include "root/dsystem.h"
-
-#include "mars.h"
-#include "dsymbol.h"
-#include "mtype.h"
-#include "scope.h"
-#include "init.h"
-#include "expression.h"
-#include "attrib.h"
-#include "declaration.h"
-#include "template.h"
-#include "id.h"
-#include "enum.h"
-#include "import.h"
-#include "aggregate.h"
-#include "target.h"
-
-typedef int (*ForeachDg)(void *ctx, size_t paramidx, Parameter *param);
-int Parameter_foreach(Parameters *parameters, ForeachDg dg, void *ctx, size_t *pn = NULL);
-
-class CppMangleVisitor : public Visitor
-{
- Objects components; // array of components available for substitution
- OutBuffer *buf; // append the mangling to buf[]
- public:
- Loc loc; // location for use in error messages
-
- // Write <seq-id> to buf
- void write_seq_id(size_t i)
- {
- if (i >= 36)
- {
- write_seq_id(i / 36);
- i %= 36;
- }
- i += (i < 10) ? '0' : 'A' - 10;
- buf->writeByte((char)i);
- }
-
- bool substitute(RootObject *p)
- {
- //printf("substitute %s\n", p ? p->toChars() : NULL);
- int i = find(p);
- if (i >= 0)
- {
- //printf("\tmatch\n");
- /* Sequence is S_, S0_, .., S9_, SA_, ..., SZ_, S10_, ...
- */
- buf->writeByte('S');
- if (i)
- {
- write_seq_id(i - 1);
- }
- buf->writeByte('_');
- return true;
- }
- return false;
- }
-
- /******
- * See if `p` exists in components[]
- * Returns:
- * index if found, -1 if not
- */
- int find(RootObject *p)
- {
- //printf("find %p %d %s\n", p, p.dyncast(), p ? p.toChars() : NULL);
- for (size_t i = 0; i < components.length; i++)
- {
- if (p == components[i])
- return (int)i;
- }
- return -1;
- }
-
- /*********************
- * Append p to components[]
- */
- void append(RootObject *p)
- {
- //printf("append %p %d %s\n", p, p.dyncast(), p ? p.toChars() : "null");
- components.push(p);
- }
-
- /************************
- * Determine if symbol is indeed the global ::std namespace.
- * Params:
- * s = symbol to check
- * Returns:
- * true if it is ::std
- */
- static bool isStd(Dsymbol *s)
- {
- return (s &&
- s->ident == Id::std && // the right name
- s->isNspace() && // g++ disallows global "std" for other than a namespace
- !getQualifier(s)); // at global level
- }
-
- /************************
- * Determine if type is a C++ fundamental type.
- * Params:
- * t = type to check
- * Returns:
- * true if it is a fundamental type
- */
- static bool isFundamentalType(Type *t)
- {
- // First check the target whether some specific ABI is being followed.
- bool isFundamental;
- if (target.cpp.fundamentalType(t, isFundamental))
- return isFundamental;
- if (t->ty == Tenum)
- {
- // Peel off enum type from special types.
- TypeEnum *te = (TypeEnum *)t;
- if (te->sym->isSpecial())
- t = te->sym->getMemtype(Loc());
- }
-
- // Fundamental arithmetic types:
- // 1. integral types: bool, char, int, ...
- // 2. floating point types: float, double, real
- // 3. void
- // 4. null pointer: std::nullptr_t (since C++11)
- if (t->ty == Tvoid || t->ty == Tbool)
- return true;
- else if (t->ty == Tnull && global.params.cplusplus >= CppStdRevisionCpp11)
- return true;
- else
- return t->isTypeBasic() && (t->isintegral() || t->isreal());
- }
-
- /******************************
- * Write the mangled representation of the template arguments.
- * Params:
- * ti = the template instance
- */
- void template_args(TemplateInstance *ti)
- {
- /* <template-args> ::= I <template-arg>+ E
- */
- if (!ti) // could happen if std::basic_string is not a template
- return;
- buf->writeByte('I');
- for (size_t i = 0; i < ti->tiargs->length; i++)
- {
- RootObject *o = (*ti->tiargs)[i];
- TemplateDeclaration *td = ti->tempdecl->isTemplateDeclaration();
- assert(td);
- TemplateParameter *tp = (*td->parameters)[i];
-
- /*
- * <template-arg> ::= <type> # type or template
- * ::= X <expression> E # expression
- * ::= <expr-primary> # simple expressions
- * ::= I <template-arg>* E # argument pack
- */
- if (tp->isTemplateTupleParameter())
- {
- buf->writeByte('I'); // argument pack
-
- // mangle the rest of the arguments as types
- for (size_t j = i; j < ti->tiargs->length; j++)
- {
- Type *t = isType((*ti->tiargs)[j]);
- assert(t);
- t->accept(this);
- }
-
- buf->writeByte('E');
- break;
- }
- if (tp->isTemplateTypeParameter())
- {
- Type *t = isType(o);
- assert(t);
- t->accept(this);
- }
- else if (TemplateValueParameter *tv = tp->isTemplateValueParameter())
- {
- // <expr-primary> ::= L <type> <value number> E # integer literal
- if (tv->valType->isintegral())
- {
- Expression *e = isExpression(o);
- assert(e);
- buf->writeByte('L');
- tv->valType->accept(this);
- uinteger_t val = e->toUInteger();
- if (!tv->valType->isunsigned() && (sinteger_t)val < 0)
- {
- val = -val;
- buf->writeByte('n');
- }
- buf->printf("%llu", val);
- buf->writeByte('E');
- }
- else
- {
- ti->error("Internal Compiler Error: C++ `%s` template value parameter is not supported", tv->valType->toChars());
- fatal();
- }
- }
- else if (tp->isTemplateAliasParameter())
- {
- Dsymbol *d = isDsymbol(o);
- Expression *e = isExpression(o);
- if (d && d->isFuncDeclaration())
- {
- bool is_nested = d->toParent3() &&
- !d->toParent3()->isModule() &&
- ((TypeFunction*)d->isFuncDeclaration()->type)->linkage == LINKcpp;
- if (is_nested)
- buf->writeByte('X');
- buf->writeByte('L');
- mangle_function(d->isFuncDeclaration());
- buf->writeByte('E');
- if (is_nested)
- buf->writeByte('E');
- }
- else if (e && e->op == TOKvar && ((VarExp*)e)->var->isVarDeclaration())
- {
- VarDeclaration *vd = ((VarExp*)e)->var->isVarDeclaration();
- buf->writeByte('L');
- mangle_variable(vd, true);
- buf->writeByte('E');
- }
- else if (d && d->isTemplateDeclaration() && d->isTemplateDeclaration()->onemember)
- {
- if (!substitute(d))
- {
- cpp_mangle_name(d, false);
- }
- }
- else
- {
- ti->error("Internal Compiler Error: `%s` is unsupported parameter for C++ template", o->toChars());
- fatal();
- }
- }
- else if (tp->isTemplateThisParameter())
- {
- ti->error("Internal Compiler Error: C++ `%s` template this parameter is not supported", o->toChars());
- fatal();
- }
- else
- {
- assert(0);
- }
- }
- buf->writeByte('E');
- }
-
- void source_name(Dsymbol *s)
- {
- //printf("source_name(%s)\n", s->toChars());
- if (TemplateInstance *ti = s->isTemplateInstance())
- {
- if (!substitute(ti->tempdecl))
- {
- append(ti->tempdecl);
- const char *name = ti->tempdecl->toAlias()->ident->toChars();
- buf->printf("%d", strlen(name));
- buf->writestring(name);
- }
- template_args(ti);
- }
- else
- {
- const char *name = s->ident->toChars();
- buf->printf("%d", strlen(name));
- buf->writestring(name);
- }
- }
-
- /********
- * See if s is actually an instance of a template
- * Params:
- * s = symbol
- * Returns:
- * if s is instance of a template, return the instance, otherwise return s
- */
- Dsymbol *getInstance(Dsymbol *s)
- {
- Dsymbol *p = s->toParent3();
- if (p)
- {
- if (TemplateInstance *ti = p->isTemplateInstance())
- return ti;
- }
- return s;
- }
-
- /********
- * Get qualifier for `s`, meaning the symbol
- * that s is in the symbol table of.
- * The module does not count as a qualifier, because C++
- * does not have modules.
- * Params:
- * s = symbol that may have a qualifier
- * Returns:
- * qualifier, NULL if none
- */
- static Dsymbol *getQualifier(Dsymbol *s)
- {
- Dsymbol *p = s->toParent3();
- return (p && !p->isModule()) ? p : NULL;
- }
-
- // Detect type char
- static bool isChar(RootObject *o)
- {
- Type *t = isType(o);
- return (t && t->equals(Type::tchar));
- }
-
- // Detect type ::std::char_traits<char>
- static bool isChar_traits_char(RootObject *o)
- {
- return isIdent_char(Id::char_traits, o);
- }
-
- // Detect type ::std::allocator<char>
- static bool isAllocator_char(RootObject *o)
- {
- return isIdent_char(Id::allocator, o);
- }
-
- // Detect type ::std::ident<char>
- static bool isIdent_char(Identifier *ident, RootObject *o)
- {
- Type *t = isType(o);
- if (!t || t->ty != Tstruct)
- return false;
- Dsymbol *s = ((TypeStruct*)t)->toDsymbol(NULL);
- if (s->ident != ident)
- return false;
- Dsymbol *p = s->toParent3();
- if (!p)
- return false;
- TemplateInstance *ti = p->isTemplateInstance();
- if (!ti)
- return false;
- Dsymbol *q = getQualifier(ti);
- return isStd(q) && ti->tiargs->length == 1 && isChar((*ti->tiargs)[0]);
- }
-
- /***
- * Detect template args <char, ::std::char_traits<char>>
- * and write st if found.
- * Returns:
- * true if found
- */
- bool char_std_char_traits_char(TemplateInstance *ti, const char *st)
- {
- if (ti->tiargs->length == 2 &&
- isChar((*ti->tiargs)[0]) &&
- isChar_traits_char((*ti->tiargs)[1]))
- {
- buf->writestring(st);
- return true;
- }
- return false;
- }
-
-
- void prefix_name(Dsymbol *s)
- {
- //printf("prefix_name(%s)\n", s->toChars());
- if (!substitute(s))
- {
- Dsymbol *si = getInstance(s);
- Dsymbol *p = getQualifier(si);
- if (p)
- {
- if (isStd(p))
- {
- TemplateInstance *ti = si->isTemplateInstance();
- if (ti)
- {
- if (s->ident == Id::allocator)
- {
- buf->writestring("Sa");
- template_args(ti);
- append(ti);
- return;
- }
- if (s->ident == Id::basic_string)
- {
- // ::std::basic_string<char, ::std::char_traits<char>, ::std::allocator<char>>
- if (ti->tiargs->length == 3 &&
- isChar((*ti->tiargs)[0]) &&
- isChar_traits_char((*ti->tiargs)[1]) &&
- isAllocator_char((*ti->tiargs)[2]))
-
- {
- buf->writestring("Ss");
- return;
- }
- buf->writestring("Sb"); // ::std::basic_string
- template_args(ti);
- append(ti);
- return;
- }
-
- // ::std::basic_istream<char, ::std::char_traits<char>>
- if (s->ident == Id::basic_istream &&
- char_std_char_traits_char(ti, "Si"))
- return;
-
- // ::std::basic_ostream<char, ::std::char_traits<char>>
- if (s->ident == Id::basic_ostream &&
- char_std_char_traits_char(ti, "So"))
- return;
-
- // ::std::basic_iostream<char, ::std::char_traits<char>>
- if (s->ident == Id::basic_iostream &&
- char_std_char_traits_char(ti, "Sd"))
- return;
- }
- buf->writestring("St");
- }
- else
- prefix_name(p);
- }
- source_name(si);
- if (!isStd(si))
- {
- /* Do this after the source_name() call to keep components[]
- * in the right order.
- * https://issues.dlang.org/show_bug.cgi?id=17947
- */
- append(si);
- }
- }
- }
-
- void cpp_mangle_name(Dsymbol *s, bool qualified)
- {
- //printf("cpp_mangle_name(%s, %d)\n", s->toChars(), qualified);
- Dsymbol *p = s->toParent3();
- Dsymbol *se = s;
- bool write_prefix = true;
- if (p && p->isTemplateInstance())
- {
- se = p;
- if (find(p->isTemplateInstance()->tempdecl) >= 0)
- write_prefix = false;
- p = p->toParent3();
- }
-
- if (p && !p->isModule())
- {
- /* The N..E is not required if:
- * 1. the parent is 'std'
- * 2. 'std' is the initial qualifier
- * 3. there is no CV-qualifier or a ref-qualifier for a member function
- * ABI 5.1.8
- */
- if (isStd(p) && !qualified)
- {
- TemplateInstance *ti = se->isTemplateInstance();
- if (s->ident == Id::allocator)
- {
- buf->writestring("Sa"); // "Sa" is short for ::std::allocator
- template_args(ti);
- }
- else if (s->ident == Id::basic_string)
- {
- // ::std::basic_string<char, ::std::char_traits<char>, ::std::allocator<char>>
- if (ti->tiargs->length == 3 &&
- isChar((*ti->tiargs)[0]) &&
- isChar_traits_char((*ti->tiargs)[1]) &&
- isAllocator_char((*ti->tiargs)[2]))
-
- {
- buf->writestring("Ss");
- return;
- }
- buf->writestring("Sb"); // ::std::basic_string
- template_args(ti);
- }
- else
- {
- // ::std::basic_istream<char, ::std::char_traits<char>>
- if (s->ident == Id::basic_istream)
- {
- if (char_std_char_traits_char(ti, "Si"))
- return;
- }
- else if (s->ident == Id::basic_ostream)
- {
- if (char_std_char_traits_char(ti, "So"))
- return;
- }
- else if (s->ident == Id::basic_iostream)
- {
- if (char_std_char_traits_char(ti, "Sd"))
- return;
- }
- buf->writestring("St");
- source_name(se);
- }
- }
- else
- {
- buf->writeByte('N');
- if (write_prefix)
- prefix_name(p);
- source_name(se);
- buf->writeByte('E');
- }
- }
- else
- source_name(se);
- append(s);
- }
-
- void CV_qualifiers(Type *t)
- {
- // CV-qualifiers are 'r': restrict, 'V': volatile, 'K': const
- if (t->isConst())
- buf->writeByte('K');
- }
-
- void mangle_variable(VarDeclaration *d, bool is_temp_arg_ref)
- {
- // fake mangling for fields to fix https://issues.dlang.org/show_bug.cgi?id=16525
- if (!(d->storage_class & (STCextern | STCfield | STCgshared)))
- {
- d->error("Internal Compiler Error: C++ static non-`__gshared` non-`extern` variables not supported");
- fatal();
- }
-
- Dsymbol *p = d->toParent3();
- if (p && !p->isModule()) //for example: char Namespace1::beta[6] should be mangled as "_ZN10Namespace14betaE"
- {
- buf->writestring("_ZN");
- prefix_name(p);
- source_name(d);
- buf->writeByte('E');
- }
- else //char beta[6] should mangle as "beta"
- {
- if (!is_temp_arg_ref)
- {
- buf->writestring(d->ident->toChars());
- }
- else
- {
- buf->writestring("_Z");
- source_name(d);
- }
- }
- }
-
- void mangle_function(FuncDeclaration *d)
- {
- //printf("mangle_function(%s)\n", d->toChars());
- /*
- * <mangled-name> ::= _Z <encoding>
- */
- buf->writestring("_Z");
- this->mangle_function_encoding(d);
- }
-
- void mangle_function_encoding(FuncDeclaration *d)
- {
- //printf("mangle_function_encoding(%s)\n", d->toChars());
- /*
- * <encoding> ::= <function name> <bare-function-type>
- * ::= <data name>
- * ::= <special-name>
- */
- TypeFunction *tf = (TypeFunction *)d->type;
-
- if (getFuncTemplateDecl(d))
- {
- /* It's an instance of a function template
- */
- TemplateInstance *ti = d->parent->isTemplateInstance();
- assert(ti);
- Dsymbol *p = ti->toParent3();
- if (p && !p->isModule() && tf->linkage == LINKcpp)
- {
- buf->writeByte('N');
- CV_qualifiers(d->type);
- prefix_name(p);
- if (d->isCtorDeclaration())
- buf->writestring("C1");
- else if (d->isDtorDeclaration())
- buf->writestring("D1");
- else
- source_name(ti);
- buf->writeByte('E');
- }
- else
- source_name(ti);
- headOfType(tf->nextOf()); // mangle return type
- }
- else
- {
- Dsymbol *p = d->toParent3();
- if (p && !p->isModule() && tf->linkage == LINKcpp)
- {
- /* <nested-name> ::= N [<CV-qualifiers>] <prefix> <unqualified-name> E
- * ::= N [<CV-qualifiers>] <template-prefix> <template-args> E
- */
- buf->writeByte('N');
- CV_qualifiers(d->type);
-
- /* <prefix> ::= <prefix> <unqualified-name>
- * ::= <template-prefix> <template-args>
- * ::= <template-param>
- * ::= # empty
- * ::= <substitution>
- * ::= <prefix> <data-member-prefix>
- */
- prefix_name(p);
- //printf("p: %s\n", buf.peekChars());
-
- if (d->isCtorDeclaration())
- {
- buf->writestring("C1");
- }
- else if (d->isDtorDeclaration())
- {
- buf->writestring("D1");
- }
- else
- {
- source_name(d);
- }
- buf->writeByte('E');
- }
- else
- {
- source_name(d);
- }
- }
-
- if (tf->linkage == LINKcpp) //Template args accept extern "C" symbols with special mangling
- {
- assert(tf->ty == Tfunction);
- mangleFunctionParameters(tf->parameterList.parameters,
- tf->parameterList.varargs);
- }
- }
-
- void mangleFunctionParameters(Parameters *parameters, int varargs)
- {
- struct ParamsCppMangle
- {
- int numparams;
- CppMangleVisitor *mangler;
-
- static int dg(void *ctx, size_t, Parameter *fparam)
- {
- ParamsCppMangle *p = (ParamsCppMangle *)ctx;
- CppMangleVisitor *mangler = p->mangler;
- Type *t = target.cpp.parameterType(fparam);
- if (t->ty == Tsarray)
- {
- // Static arrays in D are passed by value; no counterpart in C++
- t->error(mangler->loc, "Internal Compiler Error: unable to pass static array `%s` to extern(C++) function, use pointer instead",
- t->toChars());
- fatal();
- }
- mangler->headOfType(t);
- p->numparams++;
- return 0;
- }
- };
-
- ParamsCppMangle p;
- p.numparams = 0;
- p.mangler = this;
-
- if (parameters)
- Parameter_foreach(parameters, &ParamsCppMangle::dg, (void*)&p);
-
- if (varargs)
- buf->writeByte('z');
- else if (!p.numparams)
- buf->writeByte('v'); // encode (void) parameters
- }
-
-public:
- CppMangleVisitor(OutBuffer *buf, Loc loc)
- : components(), buf(buf), loc(loc)
- {
- }
-
- /*****
- * Entry point. Append mangling to buf[]
- * Params:
- * s = symbol to mangle
- */
- void mangleOf(Dsymbol *s)
- {
- if (VarDeclaration *vd = s->isVarDeclaration())
- {
- mangle_variable(vd, false);
- }
- else if (FuncDeclaration *fd = s->isFuncDeclaration())
- {
- mangle_function(fd);
- }
- else
- {
- assert(0);
- }
- }
-
- /****** The rest is type mangling ************/
-
- void error(Type *t)
- {
- const char *p;
- if (t->isImmutable())
- p = "`immutable` ";
- else if (t->isShared())
- p = "`shared` ";
- else
- p = "";
- t->error(loc, "Internal Compiler Error: %stype `%s` can not be mapped to C++", p, t->toChars());
- fatal(); //Fatal, because this error should be handled in frontend
- }
-
- /****************************
- * Mangle a type,
- * treating it as a Head followed by a Tail.
- * Params:
- * t = Head of a type
- */
- void headOfType(Type *t)
- {
- if (t->ty == Tclass)
- {
- mangleTypeClass((TypeClass*)t, true);
- }
- else
- {
- // For value types, strip const/immutable/shared from the head of the type
- t->mutableOf()->unSharedOf()->accept(this);
- }
- }
-
- void visit(Type *t)
- {
- error(t);
- }
-
- /******
- * Write out 1 or 2 character basic type mangling.
- * Handle const and substitutions.
- * Params:
- * t = type to mangle
- * p = if not 0, then character prefix
- * c = mangling character
- */
- void writeBasicType(Type *t, char p, char c)
- {
- // Only do substitutions for non-fundamental types.
- if (!isFundamentalType(t) || t->isConst())
- {
- if (substitute(t))
- return;
- else
- append(t);
- }
- CV_qualifiers(t);
- if (p)
- buf->writeByte(p);
- buf->writeByte(c);
- }
-
- void visit(TypeNull *t)
- {
- if (t->isImmutable() || t->isShared())
- return error(t);
-
- writeBasicType(t, 'D', 'n');
- }
-
- void visit(TypeNoreturn *t)
- {
- if (t->isImmutable() || t->isShared())
- return error(t);
-
- writeBasicType(t, 0, 'v'); // mangle like `void`
- }
-
- void visit(TypeBasic *t)
- {
- if (t->isImmutable() || t->isShared())
- return error(t);
-
- // Handle any target-specific basic types.
- if (const char *tm = target.cpp.typeMangle(t))
- {
- // Only do substitutions for non-fundamental types.
- if (!isFundamentalType(t) || t->isConst())
- {
- if (substitute(t))
- return;
- else
- append(t);
- }
- CV_qualifiers(t);
- buf->writestring(tm);
- return;
- }
-
- /* <builtin-type>:
- * v void
- * w wchar_t
- * b bool
- * c char
- * a signed char
- * h unsigned char
- * s short
- * t unsigned short
- * i int
- * j unsigned int
- * l long
- * m unsigned long
- * x long long, __int64
- * y unsigned long long, __int64
- * n __int128
- * o unsigned __int128
- * f float
- * d double
- * e long double, __float80
- * g __float128
- * z ellipsis
- * Dd 64 bit IEEE 754r decimal floating point
- * De 128 bit IEEE 754r decimal floating point
- * Df 32 bit IEEE 754r decimal floating point
- * Dh 16 bit IEEE 754r half-precision floating point
- * Di char32_t
- * Ds char16_t
- * u <source-name> # vendor extended type
- */
-
- char c;
- char p = 0;
- switch (t->ty)
- {
- case Tvoid: c = 'v'; break;
- case Tint8: c = 'a'; break;
- case Tuns8: c = 'h'; break;
- case Tint16: c = 's'; break;
- case Tuns16: c = 't'; break;
- case Tint32: c = 'i'; break;
- case Tuns32: c = 'j'; break;
- case Tfloat32: c = 'f'; break;
- case Tint64:
- c = (target.c.longsize == 8 ? 'l' : 'x');
- break;
- case Tuns64:
- c = (target.c.longsize == 8 ? 'm' : 'y');
- break;
- case Tint128: c = 'n'; break;
- case Tuns128: c = 'o'; break;
- case Tfloat64: c = 'd'; break;
- case Tfloat80: c = 'e'; break;
- case Tbool: c = 'b'; break;
- case Tchar: c = 'c'; break;
- case Twchar: c = 't'; break; // unsigned short (perhaps use 'Ds' ?
- case Tdchar: c = 'w'; break; // wchar_t (UTF-32) (perhaps use 'Di' ?
- case Timaginary32: p = 'G'; c = 'f'; break; // 'G' means imaginary
- case Timaginary64: p = 'G'; c = 'd'; break;
- case Timaginary80: p = 'G'; c = 'e'; break;
- case Tcomplex32: p = 'C'; c = 'f'; break; // 'C' means complex
- case Tcomplex64: p = 'C'; c = 'd'; break;
- case Tcomplex80: p = 'C'; c = 'e'; break;
-
- default:
- return error(t);
- }
- writeBasicType(t, p, c);
- }
-
- void visit(TypeVector *t)
- {
- if (t->isImmutable() || t->isShared())
- return error(t);
-
- if (substitute(t))
- return;
- append(t);
- CV_qualifiers(t);
-
- // Handle any target-specific vector types.
- if (const char *tm = target.cpp.typeMangle(t))
- {
- buf->writestring(tm);
- }
- else
- {
- assert(t->basetype && t->basetype->ty == Tsarray);
- assert(((TypeSArray *)t->basetype)->dim);
- buf->writestring("U8__vector"); //-- Gnu ABI v.3
- t->basetype->nextOf()->accept(this);
- }
- }
-
- void visit(TypeSArray *t)
- {
- if (t->isImmutable() || t->isShared())
- return error(t);
-
- if (!substitute(t))
- append(t);
- CV_qualifiers(t);
- buf->writeByte('A');
- buf->printf("%llu", t->dim ? t->dim->toInteger() : 0);
- buf->writeByte('_');
- t->next->accept(this);
- }
-
- void visit(TypePointer *t)
- {
- if (t->isImmutable() || t->isShared())
- return error(t);
-
- if (substitute(t))
- return;
- CV_qualifiers(t);
- buf->writeByte('P');
- t->next->accept(this);
- append(t);
- }
-
- void visit(TypeReference *t)
- {
- //printf("TypeReference %s\n", t->toChars());
- if (substitute(t))
- return;
- buf->writeByte('R');
- t->next->accept(this);
- append(t);
- }
-
- void visit(TypeFunction *t)
- {
- /*
- * <function-type> ::= F [Y] <bare-function-type> E
- * <bare-function-type> ::= <signature type>+
- * # types are possible return type, then parameter types
- */
-
- /* ABI says:
- "The type of a non-static member function is considered to be different,
- for the purposes of substitution, from the type of a namespace-scope or
- static member function whose type appears similar. The types of two
- non-static member functions are considered to be different, for the
- purposes of substitution, if the functions are members of different
- classes. In other words, for the purposes of substitution, the class of
- which the function is a member is considered part of the type of
- function."
-
- BUG: Right now, types of functions are never merged, so our simplistic
- component matcher always finds them to be different.
- We should use Type::equals on these, and use different
- TypeFunctions for non-static member functions, and non-static
- member functions of different classes.
- */
- if (substitute(t))
- return;
- buf->writeByte('F');
- if (t->linkage == LINKc)
- buf->writeByte('Y');
- Type *tn = t->next;
- if (t->isref)
- tn = tn->referenceTo();
- tn->accept(this);
- mangleFunctionParameters(t->parameterList.parameters,
- t->parameterList.varargs);
- buf->writeByte('E');
- append(t);
- }
-
- void visit(TypeStruct *t)
- {
- if (t->isImmutable() || t->isShared())
- return error(t);
-
- //printf("TypeStruct %s\n", t->toChars());
- doSymbol(t);
- }
-
-
- void visit(TypeEnum *t)
- {
- if (t->isImmutable() || t->isShared())
- return error(t);
-
- /* __c_(u)long(long) and others get special mangling
- */
- Identifier *id = t->sym->ident;
- //printf("enum id = '%s'\n", id->toChars());
- if (id == Id::__c_long)
- return writeBasicType(t, 0, 'l');
- else if (id == Id::__c_ulong)
- return writeBasicType(t, 0, 'm');
- else if (id == Id::__c_wchar_t)
- return writeBasicType(t, 0, 'w');
- else if (id == Id::__c_longlong)
- return writeBasicType(t, 0, 'x');
- else if (id == Id::__c_ulonglong)
- return writeBasicType(t, 0, 'y');
- else if (id == Id::__c_complex_float)
- return writeBasicType(t, 'C', 'f');
- else if (id == Id::__c_complex_double)
- return writeBasicType(t, 'C', 'd');
- else if (id == Id::__c_complex_real)
- return writeBasicType(t, 'C', 'e');
-
- doSymbol(t);
- }
-
- /****************
- * Write structs and enums.
- * Params:
- * t = TypeStruct or TypeEnum
- */
- void doSymbol(Type *t)
- {
- if (substitute(t))
- return;
- CV_qualifiers(t);
-
- // Handle any target-specific struct types.
- if (const char *tm = target.cpp.typeMangle(t))
- {
- buf->writestring(tm);
- }
- else
- {
- Dsymbol *s = t->toDsymbol(NULL);
- Dsymbol *p = s->toParent3();
- if (p && p->isTemplateInstance())
- {
- /* https://issues.dlang.org/show_bug.cgi?id=17947
- * Substitute the template instance symbol, not the struct/enum symbol
- */
- if (substitute(p))
- return;
- }
- if (!substitute(s))
- {
- cpp_mangle_name(s, t->isConst());
- }
- }
- if (t->isConst())
- append(t);
- }
-
- void visit(TypeClass *t)
- {
- mangleTypeClass(t, false);
- }
-
- /************************
- * Mangle a class type.
- * If it's the head, treat the initial pointer as a value type.
- * Params:
- * t = class type
- * head = true for head of a type
- */
- void mangleTypeClass(TypeClass *t, bool head)
- {
- if (t->isImmutable() || t->isShared())
- return error(t);
-
- /* Mangle as a <pointer to><struct>
- */
- if (substitute(t))
- return;
- if (!head)
- CV_qualifiers(t);
- buf->writeByte('P');
-
- CV_qualifiers(t);
-
- {
- Dsymbol *s = t->toDsymbol(NULL);
- Dsymbol *p = s->toParent3();
- if (p && p->isTemplateInstance())
- {
- /* https://issues.dlang.org/show_bug.cgi?id=17947
- * Substitute the template instance symbol, not the class symbol
- */
- if (substitute(p))
- return;
- }
- }
-
- if (!substitute(t->sym))
- {
- cpp_mangle_name(t->sym, t->isConst());
- }
- if (t->isConst())
- append(NULL); // C++ would have an extra type here
- append(t);
- }
-
- const char *mangle_typeinfo(Dsymbol *s)
- {
- buf->writestring("_ZTI");
- cpp_mangle_name(s, false);
- return buf->extractChars();
- }
-};
-
-const char *toCppMangleItanium(Dsymbol *s)
-{
- //printf("toCppMangleItanium(%s)\n", s->toChars());
- OutBuffer buf;
- CppMangleVisitor v(&buf, s->loc);
- v.mangleOf(s);
- return buf.extractChars();
-}
-
-const char *cppTypeInfoMangleItanium(Dsymbol *s)
-{
- //printf("cppTypeInfoMangleItanium(%s)\n", s->toChars());
- OutBuffer buf;
- buf.writestring("_ZTI"); // "TI" means typeinfo structure
- CppMangleVisitor v(&buf, s->loc);
- v.cpp_mangle_name(s, false);
- return buf.extractChars();
-}
-
-const char *cppThunkMangleItanium(FuncDeclaration *fd, int offset)
-{
- //printf("cppThunkMangleItanium(%s)\n", fd.toChars());
- OutBuffer buf;
- buf.printf("_ZThn%u_", offset); // "Th" means thunk, "n%u" is the call offset
- CppMangleVisitor v(&buf, fd->loc);
- v.mangle_function_encoding(fd);
- return buf.extractChars();
-}