本文整理汇总了C++中Dsymbol::isTemplateDeclaration方法的典型用法代码示例。如果您正苦于以下问题:C++ Dsymbol::isTemplateDeclaration方法的具体用法?C++ Dsymbol::isTemplateDeclaration怎么用?C++ Dsymbol::isTemplateDeclaration使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Dsymbol
的用法示例。
在下文中一共展示了Dsymbol::isTemplateDeclaration方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: toAlias
Dsymbol *Dsymbol::searchX(Loc loc, Scope *sc, RootObject *id)
{
//printf("Dsymbol::searchX(this=%p,%s, ident='%s')\n", this, toChars(), ident->toChars());
Dsymbol *s = toAlias();
Dsymbol *sm;
if (Declaration *d = s->isDeclaration())
{
if (d->inuse)
{
::error(loc, "circular reference to '%s'", d->toPrettyChars());
return NULL;
}
}
switch (id->dyncast())
{
case DYNCAST_IDENTIFIER:
sm = s->search(loc, (Identifier *)id);
break;
case DYNCAST_DSYMBOL:
{
// It's a template instance
//printf("\ttemplate instance id\n");
Dsymbol *st = (Dsymbol *)id;
TemplateInstance *ti = st->isTemplateInstance();
sm = s->search(loc, ti->name);
if (!sm)
{
sm = s->search_correct(ti->name);
if (sm)
error("template identifier '%s' is not a member of '%s %s', did you mean '%s %s'?",
ti->name->toChars(), s->kind(), s->toChars(), sm->kind(), sm->toChars());
else
error("template identifier '%s' is not a member of '%s %s'",
ti->name->toChars(), s->kind(), s->toChars());
return NULL;
}
sm = sm->toAlias();
TemplateDeclaration *td = sm->isTemplateDeclaration();
if (!td)
{
error("%s is not a template, it is a %s", ti->name->toChars(), sm->kind());
return NULL;
}
ti->tempdecl = td;
if (!ti->semanticRun)
ti->semantic(sc);
sm = ti->toAlias();
break;
}
default:
assert(0);
}
return sm;
}
示例2: search
/*******************************************
* Look for constructor declaration.
*/
Dsymbol *AggregateDeclaration::searchCtor()
{
Dsymbol *s = search(Loc(), Id::ctor);
if (s)
{
if (!(s->isCtorDeclaration() ||
s->isTemplateDeclaration() ||
s->isOverloadSet()))
{
error("%s %s is not a constructor; identifiers starting with __ are reserved for the implementation", s->kind(), s->toChars());
errors = true;
s = NULL;
}
}
return s;
}
示例3: fp
static int fp(void *param, Dsymbol *s)
{
if (!isCPP(s))
return 0;
auto fd = s->isFuncDeclaration();
auto td = static_cast<cpp::TemplateDeclaration*>(
s->isTemplateDeclaration());
DEquals *p = (DEquals *)param;
decltype(D) s_D = fd ? getFD(fd) : td->TempOrSpec;
if (p->D == getCanonicalDecl(s_D))
{
p->s = s;
return 1;
}
return 0;
}
示例4: toAlias
Dsymbol *Dsymbol::searchX(Loc loc, Scope *sc, Identifier *id)
{
//printf("Dsymbol::searchX(this=%p,%s, ident='%s')\n", this, toChars(), ident->toChars());
Dsymbol *s = toAlias();
Dsymbol *sm;
switch (id->dyncast())
{
case DYNCAST_IDENTIFIER:
sm = s->search(loc, id, 0);
break;
case DYNCAST_DSYMBOL:
{ // It's a template instance
//printf("\ttemplate instance id\n");
Dsymbol *st = (Dsymbol *)id;
TemplateInstance *ti = st->isTemplateInstance();
id = ti->name;
sm = s->search(loc, id, 0);
if (!sm)
{ error("template identifier %s is not a member of %s %s",
id->toChars(), s->kind(), s->toChars());
return NULL;
}
sm = sm->toAlias();
TemplateDeclaration *td = sm->isTemplateDeclaration();
if (!td)
{
error("%s is not a template, it is a %s", id->toChars(), sm->kind());
return NULL;
}
ti->tempdecl = td;
if (!ti->semanticRun)
ti->semantic(sc);
sm = ti->toAlias();
break;
}
default:
assert(0);
}
return sm;
}
示例5: if
//.........这里部分代码省略.........
if (ad1 && id)
{
s = search_function(ad1, id);
}
#endif
Objects *targsi = NULL;
#if DMDV2
if (!s)
{ /* Try the new D2 scheme, opOpAssign
*/
if (ad1)
s = search_function(ad1, Id::opOpAssign);
// Set targsi, the template argument list, which will be the operator string
if (s)
{
id = Id::opOpAssign;
targsi = opToArg(sc, op);
}
}
#endif
if (s)
{
/* Try:
* a.opOpAssign(b)
*/
args2.setDim(1);
args2.tdata()[0] = e2;
Match m;
memset(&m, 0, sizeof(m));
m.last = MATCHnomatch;
if (s)
{
FuncDeclaration *fd = s->isFuncDeclaration();
if (fd)
{
overloadResolveX(&m, fd, NULL, &args2, sc->module);
}
else
{ TemplateDeclaration *td = s->isTemplateDeclaration();
templateResolve(&m, td, sc, loc, targsi, e1, &args2);
}
}
if (m.count > 1)
{
// Error, ambiguous
error("overloads %s and %s both match argument list for %s",
m.lastf->type->toChars(),
m.nextf->type->toChars(),
m.lastf->toChars());
}
else if (m.last == MATCHnomatch)
{
m.lastf = m.anyf;
if (targsi)
goto L1;
}
// Rewrite (e1 op e2) as e1.opOpAssign(e2)
return build_overload(loc, sc, e1, e2, m.lastf ? m.lastf : s);
}
L1:
#if DMDV2
// Try alias this on first operand
if (ad1 && ad1->aliasthis)
{
/* Rewrite (e1 op e2) as:
* (e1.aliasthis op e2)
*/
Expression *e1 = new DotIdExp(loc, this->e1, ad1->aliasthis->ident);
Expression *e = copy();
((BinExp *)e)->e1 = e1;
e = e->trySemantic(sc);
return e;
}
// Try alias this on second operand
AggregateDeclaration *ad2 = isAggregate(e2->type);
if (ad2 && ad2->aliasthis)
{
/* Rewrite (e1 op e2) as:
* (e1 op e2.aliasthis)
*/
Expression *e2 = new DotIdExp(loc, this->e2, ad2->aliasthis->ident);
Expression *e = copy();
((BinExp *)e)->e2 = e2;
e = e->trySemantic(sc);
return e;
}
#endif
return NULL;
}
示例6: inferApplyArgTypes
void inferApplyArgTypes(enum TOK op, Parameters *arguments, Expression *aggr, Module* from)
{
if (!arguments || !arguments->dim)
return;
/* Return if no arguments need types.
*/
for (size_t u = 0; 1; u++)
{ if (u == arguments->dim)
return;
Parameter *arg = arguments->tdata()[u];
if (!arg->type)
break;
}
Dsymbol *s;
AggregateDeclaration *ad;
Parameter *arg = arguments->tdata()[0];
Type *taggr = aggr->type;
if (!taggr)
return;
Type *tab = taggr->toBasetype();
switch (tab->ty)
{
case Tarray:
case Tsarray:
case Ttuple:
if (arguments->dim == 2)
{
if (!arg->type)
arg->type = Type::tsize_t; // key type
arg = arguments->tdata()[1];
}
if (!arg->type && tab->ty != Ttuple)
arg->type = tab->nextOf(); // value type
break;
case Taarray:
{ TypeAArray *taa = (TypeAArray *)tab;
if (arguments->dim == 2)
{
if (!arg->type)
arg->type = taa->index; // key type
arg = arguments->tdata()[1];
}
if (!arg->type)
arg->type = taa->next; // value type
break;
}
case Tclass:
ad = ((TypeClass *)tab)->sym;
goto Laggr;
case Tstruct:
ad = ((TypeStruct *)tab)->sym;
goto Laggr;
Laggr:
s = search_function(ad,
(op == TOKforeach_reverse) ? Id::applyReverse
: Id::apply);
if (s)
goto Lapply; // prefer opApply
if (arguments->dim == 1)
{
if (!arg->type)
{
/* Look for a head() or rear() overload
*/
Identifier *id = (op == TOKforeach) ? Id::Fhead : Id::Ftoe;
Dsymbol *s = search_function(ad, id);
FuncDeclaration *fd = s ? s->isFuncDeclaration() : NULL;
if (!fd)
{ if (s && s->isTemplateDeclaration())
break;
goto Lapply;
}
arg->type = fd->type->nextOf();
}
break;
}
Lapply:
{ /* Look for an
* int opApply(int delegate(ref Type [, ...]) dg);
* overload
*/
if (s)
{
FuncDeclaration *fd = s->isFuncDeclaration();
if (fd)
{ inferApplyArgTypesX(from, fd, arguments);
break;
}
#if 0
TemplateDeclaration *td = s->isTemplateDeclaration();
//.........这里部分代码省略.........
示例7: if
//.........这里部分代码省略.........
*/
if (!*pvar) // if not already initialized
{ /* Create variable v and set it to the value of $
*/
VarDeclaration *v;
Type *t;
if (ce->op == TOKtuple)
{ /* It is for an expression tuple, so the
* length will be a const.
*/
Expression *e = new IntegerExp(Loc(), ((TupleExp *)ce)->exps->dim, Type::tsize_t);
v = new VarDeclaration(loc, Type::tsize_t, Id::dollar, new ExpInitializer(Loc(), e));
v->storage_class |= STCstatic | STCconst;
}
else if (ce->type && (t = ce->type->toBasetype()) != NULL &&
(t->ty == Tstruct || t->ty == Tclass))
{ // Look for opDollar
assert(exp->op == TOKarray || exp->op == TOKslice);
AggregateDeclaration *ad = NULL;
if (t->ty == Tclass)
{
ad = ((TypeClass *)t)->sym;
}
else if (t->ty == Tstruct)
{
ad = ((TypeStruct *)t)->sym;
}
assert(ad);
Dsymbol *s = ad->search(loc, Id::opDollar, 0);
if (!s) // no dollar exists -- search in higher scope
return NULL;
s = s->toAlias();
Expression *e = NULL;
// Check for multi-dimensional opDollar(dim) template.
if (TemplateDeclaration *td = s->isTemplateDeclaration())
{
dinteger_t dim;
if (exp->op == TOKarray)
{
dim = ((ArrayExp *)exp)->currentDimension;
}
else if (exp->op == TOKslice)
{
dim = 0; // slices are currently always one-dimensional
}
Objects *tdargs = new Objects();
Expression *edim = new IntegerExp(Loc(), dim, Type::tsize_t);
edim = edim->semantic(sc);
tdargs->push(edim);
//TemplateInstance *ti = new TemplateInstance(loc, td, tdargs);
//ti->semantic(sc);
e = new DotTemplateInstanceExp(loc, ce, td->ident, tdargs);
}
else
{ /* opDollar exists, but it's not a template.
* This is acceptable ONLY for single-dimension indexing.
* Note that it's impossible to have both template & function opDollar,
* because both take no arguments.
*/
if (exp->op == TOKarray && ((ArrayExp *)exp)->arguments->dim != 1)
{
exp->error("%s only defines opDollar for one dimension", ad->toChars());
return NULL;
}
Declaration *d = s->isDeclaration();
assert(d);
e = new DotVarExp(loc, ce, d);
}
e = e->semantic(sc);
if (!e->type)
exp->error("%s has no value", e->toChars());
t = e->type->toBasetype();
if (t && t->ty == Tfunction)
e = new CallExp(e->loc, e);
v = new VarDeclaration(loc, NULL, Id::dollar, new ExpInitializer(Loc(), e));
}
else
{ /* For arrays, $ will either be a compile-time constant
* (in which case its value in set during constant-folding),
* or a variable (in which case an expression is created in
* toir.c).
*/
VoidInitializer *e = new VoidInitializer(Loc());
e->type = Type::tsize_t;
v = new VarDeclaration(loc, Type::tsize_t, Id::dollar, e);
v->storage_class |= STCctfe; // it's never a true static variable
}
*pvar = v;
}
(*pvar)->semantic(sc);
return (*pvar);
}
return NULL;
}
示例8: if
//.........这里部分代码省略.........
#endif
BinExp::semantic(sc);
e1 = resolveProperties(sc, e1);
e2 = resolveProperties(sc, e2);
// Don't attempt 'alias this' if an error occured
if (e1->type->ty == Terror || e2->type->ty == Terror)
return new ErrorExp();
Identifier *id = opId();
Expressions args2;
AggregateDeclaration *ad1 = isAggregate(e1->type);
Dsymbol *s = NULL;
#if 1 // the old D1 scheme
if (ad1 && id)
{
s = search_function(ad1, id);
}
#endif
Objects *tiargs = NULL;
#if DMDV2
if (!s)
{ /* Try the new D2 scheme, opOpAssign
*/
if (ad1)
{
s = search_function(ad1, Id::opOpAssign);
if (s && !s->isTemplateDeclaration())
{ error("%s.opOpAssign isn't a template", e1->toChars());
return new ErrorExp();
}
}
// Set tiargs, the template argument list, which will be the operator string
if (s)
{
id = Id::opOpAssign;
tiargs = opToArg(sc, op);
}
}
#endif
if (s)
{
/* Try:
* a.opOpAssign(b)
*/
args2.setDim(1);
args2[0] = e2;
Match m;
memset(&m, 0, sizeof(m));
m.last = MATCHnomatch;
if (s)
{
FuncDeclaration *fd = s->isFuncDeclaration();
if (fd)
{
示例9: if
//.........这里部分代码省略.........
{
/* After following aliases, we found the same
* symbol, so it's not an ambiguity. But if one
* alias is deprecated or less accessible, prefer
* the other.
*/
if (s->isDeprecated() ||
s2->prot() > s->prot() && s2->prot() != PROTnone)
s = s2;
}
else
{
/* Two imports of the same module should be regarded as
* the same.
*/
Import *i1 = s->isImport();
Import *i2 = s2->isImport();
if (!(i1 && i2 &&
(i1->mod == i2->mod ||
(!i1->parent->isImport() && !i2->parent->isImport() &&
i1->ident->equals(i2->ident))
)
)
)
{
/* Bugzilla 8668:
* Public selective import adds AliasDeclaration in module.
* To make an overload set, resolve aliases in here and
* get actual overload roots which accessible via s and s2.
*/
s = s->toAlias();
s2 = s2->toAlias();
/* If both s2 and s are overloadable (though we only
* need to check s once)
*/
if (s2->isOverloadable() && (a || s->isOverloadable()))
{ if (!a)
a = new OverloadSet(s->ident);
/* Don't add to a[] if s2 is alias of previous sym
*/
for (size_t j = 0; j < a->a.dim; j++)
{ Dsymbol *s3 = a->a[j];
if (s2->toAlias() == s3->toAlias())
{
if (s3->isDeprecated() ||
s2->prot() > s3->prot() && s2->prot() != PROTnone)
a->a[j] = s2;
goto Lcontinue;
}
}
a->push(s2);
Lcontinue:
continue;
}
if (flags & 4) // if return NULL on ambiguity
return NULL;
if (!(flags & 2))
ScopeDsymbol::multiplyDefined(loc, s, s2);
break;
}
}
}
}
/* Build special symbol if we had multiple finds
*/
if (a)
{ assert(s);
a->push(s);
s = a;
}
if (s)
{
if (!(flags & 2))
{ Declaration *d = s->isDeclaration();
if (d && d->protection == PROTprivate &&
!d->parent->isTemplateMixin())
error(loc, "%s is private", d->toPrettyChars());
AggregateDeclaration *ad = s->isAggregateDeclaration();
if (ad && ad->protection == PROTprivate &&
!ad->parent->isTemplateMixin())
error(loc, "%s is private", ad->toPrettyChars());
EnumDeclaration *ed = s->isEnumDeclaration();
if (ed && ed->protection == PROTprivate &&
!ed->parent->isTemplateMixin())
error(loc, "%s is private", ed->toPrettyChars());
TemplateDeclaration *td = s->isTemplateDeclaration();
if (td && td->protection == PROTprivate &&
!td->parent->isTemplateMixin())
error(loc, "%s is private", td->toPrettyChars());
}
}
}
return s;
}
示例10: source_name
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);
//.........这里部分代码省略.........
示例11: semantic
//.........这里部分代码省略.........
}
}
else
error("unrecognized pragma(%s)", ident->toChars());
if (decl)
{
for (unsigned i = 0; i < decl->dim; i++)
{
Dsymbol *s = (Dsymbol *)decl->data[i];
s->semantic(sc);
// LDC
#if IN_LLVM
if (llvm_internal)
{
if (s->llvmInternal)
{
error("multiple LDC specific pragmas not allowed not affect the same declaration ('%s' at '%s')", s->toChars(), s->loc.toChars());
fatal();
}
switch(llvm_internal)
{
case LLVMintrinsic:
if (FuncDeclaration* fd = s->isFuncDeclaration())
{
fd->llvmInternal = llvm_internal;
fd->intrinsicName = arg1str;
fd->linkage = LINKintrinsic;
((TypeFunction*)fd->type)->linkage = LINKintrinsic;
}
else if (TemplateDeclaration* td = s->isTemplateDeclaration())
{
td->llvmInternal = llvm_internal;
td->intrinsicName = arg1str;
}
else
{
error("only allowed on function declarations");
fatal();
}
break;
case LLVMatomic_rmw:
if (TemplateDeclaration* td = s->isTemplateDeclaration())
{
td->llvmInternal = llvm_internal;
td->intrinsicName = arg1str;
}
else
{
error("the '%s' pragma is only allowed on template declarations", ident->toChars());
fatal();
}
break;
case LLVMva_start:
case LLVMva_arg:
case LLVMatomic_load:
case LLVMatomic_store:
case LLVMatomic_cmp_xchg:
if (TemplateDeclaration* td = s->isTemplateDeclaration())
{
if (td->parameters->dim != 1)
示例12: if
//.........这里部分代码省略.........
if (dtor)
{
tmp = new VarDeclaration(loc, type, idtmp, new VoidInitializer(loc));
tmp->noscope = 1;
tmp->storage_class |= STCctfe;
e = new DeclarationExp(loc, tmp);
ec = new AssignExp(loc,
new VarExp(loc, tmp),
new ThisExp(loc)
);
ec->op = TOKblit;
e = Expression::combine(e, ec);
}
ec = new AssignExp(loc,
new ThisExp(loc),
new IdentifierExp(loc, Id::p));
ec->op = TOKblit;
e = Expression::combine(e, ec);
if (dtor)
{
/* Instead of running the destructor on s, run it
* on tmp. This avoids needing to copy tmp back in to s.
*/
Expression *ec2 = new DotVarExp(loc, new VarExp(loc, tmp), dtor, 0);
ec2 = new CallExp(loc, ec2);
e = Expression::combine(e, ec2);
}
}
else
{
/* Do memberwise copy
*/
//printf("\tmemberwise copy\n");
for (size_t i = 0; i < fields.dim; i++)
{
Dsymbol *s = fields[i];
VarDeclaration *v = s->isVarDeclaration();
assert(v && v->isField());
// this.v = s.v;
AssignExp *ec = new AssignExp(loc,
new DotVarExp(loc, new ThisExp(loc), v, 0),
new DotVarExp(loc, new IdentifierExp(loc, Id::p), v, 0));
e = Expression::combine(e, ec);
}
}
if (e)
{
Statement *s1 = new ExpStatement(loc, e);
/* Add:
* return this;
*/
e = new ThisExp(loc);
Statement *s2 = new ReturnStatement(loc, e);
fop->fbody = new CompoundStatement(loc, s1, s2);
}
Dsymbol *s = fop;
#if 1 // workaround until fixing issue 1528
Dsymbol *assign = search_function(this, Id::assign);
if (assign && assign->isTemplateDeclaration())
{
// Wrap a template around the function declaration
TemplateParameters *tpl = new TemplateParameters();
Dsymbols *decldefs = new Dsymbols();
decldefs->push(s);
TemplateDeclaration *tempdecl =
new TemplateDeclaration(assign->loc, fop->ident, tpl, NULL, decldefs, 0);
s = tempdecl;
}
#endif
members->push(s);
s->addMember(sc, this, 1);
this->hasIdentityAssign = 1; // temporary mark identity assignable
unsigned errors = global.startGagging(); // Do not report errors, even if the
unsigned oldspec = global.speculativeGag; // template opAssign fbody makes it.
global.speculativeGag = global.gag;
Scope *sc2 = sc->push();
sc2->stc = 0;
sc2->linkage = LINKd;
sc2->speculative = true;
s->semantic(sc2);
s->semantic2(sc2);
s->semantic3(sc2);
sc2->pop();
global.speculativeGag = oldspec;
if (global.endGagging(errors)) // if errors happened
{ // Disable generated opAssign, because some members forbid identity assignment.
fop->storage_class |= STCdisable;
fop->fbody = NULL; // remove fbody which contains the error
}
//printf("-StructDeclaration::buildOpAssign() %s %s, errors = %d\n", toChars(), s->kind(), (fop->storage_class & STCdisable) != 0);
return fop;
}
示例13: DotVarExp
FuncDeclaration *StructDeclaration::buildOpEquals(Scope *sc)
{
Dsymbol *eq = search_function(this, Id::eq);
if (eq)
{
for (size_t i = 0; i <= 1; i++)
{
Expression *e =
i == 0 ? new NullExp(loc, type->constOf()) // dummy rvalue
: type->constOf()->defaultInit(); // dummy lvalue
Expressions *arguments = new Expressions();
arguments->push(e);
// check identity opEquals exists
FuncDeclaration *fd = eq->isFuncDeclaration();
if (fd)
{ fd = fd->overloadResolve(loc, e, arguments, 1);
if (fd && !(fd->storage_class & STCdisable))
return fd;
}
TemplateDeclaration *td = eq->isTemplateDeclaration();
if (td)
{ fd = td->deduceFunctionTemplate(sc, loc, NULL, e, arguments, 1);
if (fd && !(fd->storage_class & STCdisable))
return fd;
}
}
return NULL;
}
if (!needOpEquals())
return NULL;
//printf("StructDeclaration::buildOpEquals() %s\n", toChars());
Parameters *parameters = new Parameters;
parameters->push(new Parameter(STCin, type, Id::p, NULL));
TypeFunction *tf = new TypeFunction(parameters, Type::tbool, 0, LINKd);
tf->mod = MODconst;
tf = (TypeFunction *)tf->semantic(loc, sc);
FuncDeclaration *fop = new FuncDeclaration(loc, 0, Id::eq, STCundefined, tf);
Expression *e = NULL;
/* Do memberwise compare
*/
//printf("\tmemberwise compare\n");
for (size_t i = 0; i < fields.dim; i++)
{
Dsymbol *s = fields[i];
VarDeclaration *v = s->isVarDeclaration();
assert(v && v->storage_class & STCfield);
if (v->storage_class & STCref)
assert(0); // what should we do with this?
// this.v == s.v;
EqualExp *ec = new EqualExp(TOKequal, loc,
new DotVarExp(loc, new ThisExp(loc), v, 0),
new DotVarExp(loc, new IdentifierExp(loc, Id::p), v, 0));
if (e)
e = new AndAndExp(loc, e, ec);
else
e = ec;
}
if (!e)
e = new IntegerExp(loc, 1, Type::tbool);
fop->fbody = new ReturnStatement(loc, e);
members->push(fop);
fop->addMember(sc, this, 1);
sc = sc->push();
sc->stc = 0;
sc->linkage = LINKd;
fop->semantic(sc);
sc->pop();
//printf("-StructDeclaration::buildOpEquals() %s\n", toChars());
return fop;
}
示例14: inferApplyArgTypes
int ForeachStatement::inferApplyArgTypes(Scope *sc, Dsymbol *&sapply)
{
if (!arguments || !arguments->dim)
return 0;
if (sapply) // prefer opApply
{
for (size_t u = 0; u < arguments->dim; u++)
{ Parameter *arg = (*arguments)[u];
if (arg->type)
{
arg->type = arg->type->semantic(loc, sc);
arg->type = arg->type->addStorageClass(arg->storageClass);
}
}
Expression *ethis;
Type *tab = aggr->type->toBasetype();
if (tab->ty == Tclass || tab->ty == Tstruct)
ethis = aggr;
else
{ assert(tab->ty == Tdelegate && aggr->op == TOKdelegate);
ethis = ((DelegateExp *)aggr)->e1;
}
/* Look for like an
* int opApply(int delegate(ref Type [, ...]) dg);
* overload
*/
FuncDeclaration *fd = sapply->isFuncDeclaration();
if (fd)
{ sapply = inferApplyArgTypesX(ethis, fd, arguments);
}
#if 0
TemplateDeclaration *td = sapply->isTemplateDeclaration();
if (td)
{ inferApplyArgTypesZ(td, arguments);
}
#endif
return sapply ? 1 : 0;
}
/* Return if no arguments need types.
*/
for (size_t u = 0; u < arguments->dim; u++)
{ Parameter *arg = (*arguments)[u];
if (!arg->type)
break;
}
AggregateDeclaration *ad;
Parameter *arg = (*arguments)[0];
Type *taggr = aggr->type;
assert(taggr);
Type *tab = taggr->toBasetype();
switch (tab->ty)
{
case Tarray:
case Tsarray:
case Ttuple:
if (arguments->dim == 2)
{
if (!arg->type)
{
arg->type = Type::tsize_t; // key type
arg->type = arg->type->addStorageClass(arg->storageClass);
}
arg = (*arguments)[1];
}
if (!arg->type && tab->ty != Ttuple)
{
arg->type = tab->nextOf(); // value type
arg->type = arg->type->addStorageClass(arg->storageClass);
}
break;
case Taarray:
{ TypeAArray *taa = (TypeAArray *)tab;
if (arguments->dim == 2)
{
if (!arg->type)
{
arg->type = taa->index; // key type
arg->type = arg->type->addStorageClass(arg->storageClass);
}
arg = (*arguments)[1];
}
if (!arg->type)
{
arg->type = taa->next; // value type
arg->type = arg->type->addStorageClass(arg->storageClass);
}
break;
}
case Tclass:
ad = ((TypeClass *)tab)->sym;
goto Laggr;
//.........这里部分代码省略.........
示例15: VarExp
FuncDeclaration *StructDeclaration::buildOpAssign(Scope *sc)
{
Dsymbol *assign = search_function(this, Id::assign);
if (assign)
{
if (FuncDeclaration *f = hasIdentityOpAssign(sc, assign))
return f;
// Even if non-identity opAssign is defined, built-in identity opAssign
// will be defined. (Is this an exception of operator overloading rule?)
}
if (!needOpAssign())
return NULL;
//printf("StructDeclaration::buildOpAssign() %s\n", toChars());
Parameters *fparams = new Parameters;
fparams->push(new Parameter(STCnodtor, type, Id::p, NULL));
Type *ftype = new TypeFunction(fparams, handle, FALSE, LINKd);
((TypeFunction *)ftype)->isref = 1;
FuncDeclaration *fop = new FuncDeclaration(loc, 0, Id::assign, STCundefined, ftype);
Expression *e = NULL;
if (postblit)
{ /* Swap:
* tmp = *this; *this = s; tmp.dtor();
*/
//printf("\tswap copy\n");
Identifier *idtmp = Lexer::uniqueId("__tmp");
VarDeclaration *tmp;
AssignExp *ec = NULL;
if (dtor)
{
tmp = new VarDeclaration(0, type, idtmp, new VoidInitializer(0));
tmp->noscope = 1;
tmp->storage_class |= STCctfe;
e = new DeclarationExp(0, tmp);
ec = new AssignExp(0,
new VarExp(0, tmp),
new ThisExp(0)
);
ec->op = TOKblit;
e = Expression::combine(e, ec);
}
ec = new AssignExp(0,
new ThisExp(0),
new IdentifierExp(0, Id::p));
ec->op = TOKblit;
e = Expression::combine(e, ec);
if (dtor)
{
/* Instead of running the destructor on s, run it
* on tmp. This avoids needing to copy tmp back in to s.
*/
Expression *ec2 = new DotVarExp(0, new VarExp(0, tmp), dtor, 0);
ec2 = new CallExp(0, ec2);
e = Expression::combine(e, ec2);
}
}
else
{ /* Do memberwise copy
*/
//printf("\tmemberwise copy\n");
for (size_t i = 0; i < fields.dim; i++)
{
Dsymbol *s = fields[i];
VarDeclaration *v = s->isVarDeclaration();
assert(v && v->isField());
// this.v = s.v;
AssignExp *ec = new AssignExp(0,
new DotVarExp(0, new ThisExp(0), v, 0),
new DotVarExp(0, new IdentifierExp(0, Id::p), v, 0));
e = Expression::combine(e, ec);
}
}
Statement *s1 = new ExpStatement(0, e);
/* Add:
* return this;
*/
e = new ThisExp(0);
Statement *s2 = new ReturnStatement(0, e);
fop->fbody = new CompoundStatement(0, s1, s2);
Dsymbol *s = fop;
if (assign && assign->isTemplateDeclaration())
{
// Wrap a template around the function declaration
TemplateParameters *tpl = new TemplateParameters();
Dsymbols *decldefs = new Dsymbols();
decldefs->push(s);
TemplateDeclaration *tempdecl =
new TemplateDeclaration(assign->loc, fop->ident, tpl, NULL, decldefs, 0);
s = tempdecl;
}
members->push(s);
s->addMember(sc, this, 1);
this->hasIdentityAssign = 1; // temporary mark identity assignable
//.........这里部分代码省略.........