Beispiel #1
0
    void source_name(Dsymbol *s)
    {
        char *name = s->ident->toChars();
        TemplateInstance *ti = s->isTemplateInstance();
        if (ti)
        {
            if (!substitute(ti->tempdecl))
            {
                store(ti->tempdecl);
                name = ti->name->toChars();
                buf.printf("%d%s", strlen(name), name);
            }
            buf.writeByte('I');
            bool is_var_arg = false;
            for (size_t i = 0; i < ti->tiargs->dim; i++)
            {
                RootObject *o = (RootObject *)(*ti->tiargs)[i];

                TemplateParameter *tp = NULL;
                TemplateValueParameter *tv = NULL;
                TemplateTupleParameter *tt = NULL;
                if (!is_var_arg)
                {
                    TemplateDeclaration *td = ti->tempdecl->isTemplateDeclaration();
                    tp = (*td->parameters)[i];
                    tv = tp->isTemplateValueParameter();
                    tt = tp->isTemplateTupleParameter();
                }
                /*
                 *           <template-arg> ::= <type>            # type or template
                 *                          ::= <expr-primary>   # simple expressions
                 */

                if (tt)
                {
                    buf.writeByte('I');
                    is_var_arg = true;
                    tp = NULL;
                }

                if (tv)
                {
                    // <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);
                        if (tv->valType->isunsigned())
                        {
                            buf.printf("%llu", e->toUInteger());
                        }
                        else
                        {
                            dinteger_t val = e->toInteger();
                            if (val < 0)
                            {
                                val = -val;
                                buf.writeByte('n');
                            }
                            buf.printf("%lld", val);
                        }
                        buf.writeByte('E');
                    }
                    else
                    {
                        s->error("ICE: C++ %s template value parameter is not supported", tv->valType->toChars());
                        assert(0);
                    }
                }
                else if (!tp || tp->isTemplateTypeParameter())
                {
                    Type *t = isType(o);
                    assert(t);
                    t->accept(this);
                }
                else if (tp->isTemplateAliasParameter())
                {
                    Dsymbol* d = isDsymbol(o);
                    Expression* e = isExpression(o);
                    if (!d && !e)
                    {
                        s->error("ICE: %s is unsupported parameter for C++ template: (%s)", o->toChars());
                        assert(0);
                    }
                    if (d && d->isFuncDeclaration())
                    {
                        bool is_nested = d->toParent() && !d->toParent()->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);
                            store(d);
                        }
                    }
                    else
                    {
                        s->error("ICE: %s is unsupported parameter for C++ template", o->toChars());
                        assert(0);
                    }

                }
                else
                {
                    s->error("ICE: C++ templates support only integral value , type parameters, alias templates and alias function parameters");
                    assert(0);
                }
            }
            if (is_var_arg)
            {
                buf.writeByte('E');
            }
            buf.writeByte('E');
            return;
        }
        else
        {
            buf.printf("%d%s", strlen(name), name);
        }
    }
Beispiel #2
0
void TemplateDeclaration::toJson(JsonOut *json)
{
    json->objectStart();

    // TemplateDeclaration::kind returns the kind of its Aggregate onemember, if it is one
    json->property("kind", "template");

    jsonProperties(json);

    json->propertyStart("parameters");
    json->arrayStart();
    for (size_t i = 0; i < parameters->dim; i++)
    {   TemplateParameter *s = (*parameters)[i];
        json->objectStart();

        json->property("name", s->ident->toChars());

        TemplateTypeParameter *type = s->isTemplateTypeParameter();
        if (type)
        {
#if DMDV2
            if (s->isTemplateThisParameter())
                json->property("kind", "this");
            else
                json->property("kind", "type");
#else
            json->property("kind", "type");
#endif
            json->property("type", "deco", type->specType);

            json->property("default", "defaultDeco", type->defaultType);
        }

        TemplateValueParameter *value = s->isTemplateValueParameter();
        if (value)
        {
            json->property("kind", "value");

            json->property("type", "deco", value->valType);

            if (value->specValue)
                json->property("specValue", value->specValue->toChars());

            if (value->defaultValue)
                json->property("defaultValue", value->defaultValue->toChars());
        }

        TemplateAliasParameter *alias = s->isTemplateAliasParameter();
        if (alias)
        {
            json->property("kind", "alias");

            json->property("type", "deco", alias->specType);

            if (alias->specAlias)
                json->property("specAlias", alias->specAlias->toChars());

            if (alias->defaultAlias)
                json->property("defaultAlias", alias->defaultAlias->toChars());
        }

        TemplateTupleParameter *tuple = s->isTemplateTupleParameter();
        if (tuple)
        {
            json->property("kind", "tuple");
        }

        json->objectEnd();
    }
    json->arrayEnd();

    json->propertyStart("members");
    json->arrayStart();
    for (size_t i = 0; i < members->dim; i++)
    {   Dsymbol *s = (*members)[i];
        s->toJson(json);
    }
    json->arrayEnd();

    json->objectEnd();
}