void inferApplyArgTypesZ(TemplateDeclaration *tstart, Parameters *arguments) { for (TemplateDeclaration *td = tstart; td; td = td->overnext) { if (!td->scope) { error("forward reference to template %s", td->toChars()); return; } if (!td->onemember || !td->onemember->toAlias()->isFuncDeclaration()) { error("is not a function template"); return; } if (!td->parameters || td->parameters->dim != 1) continue; TemplateParameter *tp = td->parameters->tdata()[0]; TemplateAliasParameter *tap = tp->isTemplateAliasParameter(); if (!tap || !tap->specType || tap->specType->ty != Tfunction) continue; TypeFunction *tf = (TypeFunction *)tap->specType; if (inferApplyArgTypesY(tf, arguments) == 0) // found it return; } }
Type * TypeCheck::visit(TemplateParameterList *ast) { FUNCLOG; List<TemplateParameter*>::iterator it = ast->params.begin(); while (it != ast->params.end()) { TemplateParameter *param = *it; param->accept(this); ++it; } return NULL; }
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); } }
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(); }