
/* 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();
}
