本文整理汇总了C++中TypeFunction类的典型用法代码示例。如果您正苦于以下问题:C++ TypeFunction类的具体用法?C++ TypeFunction怎么用?C++ TypeFunction使用的例子?那么恭喜您, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了TypeFunction类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: Parameter
FuncDeclaration *StructDeclaration::buildOpEquals(Scope *sc)
{
if (!needOpEquals())
return NULL;
//printf("StructDeclaration::buildOpEquals() %s\n", toChars());
Loc loc = this->loc;
Parameters *parameters = new Parameters;
#if STRUCTTHISREF
// bool opEquals(ref const T) const;
Parameter *param = new Parameter(STCref, type->constOf(), Id::p, NULL);
#else
// bool opEquals(const T*) const;
Parameter *param = new Parameter(STCin, type->pointerTo(), Id::p, NULL);
#endif
parameters->push(param);
TypeFunction *ftype = new TypeFunction(parameters, Type::tbool, 0, LINKd);
ftype->mod = MODconst;
ftype = (TypeFunction *)ftype->semantic(loc, sc);
FuncDeclaration *fop = new FuncDeclaration(loc, 0, Id::eq, STCundefined, ftype);
Expression *e = NULL;
/* Do memberwise compare
*/
//printf("\tmemberwise compare\n");
for (size_t i = 0; i < fields.dim; i++)
{
Dsymbol *s = (Dsymbol *)fields.data[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;
}
示例2: assert
//.........这里部分代码省略.........
{
Dsymbol *s = fields[i];
VarDeclaration *vd = s->isVarDeclaration();
if (vd && !vd->isDataseg())
{
if (vd->init)
{
// Should examine init to see if it is really all 0's
zeroInit = 0;
break;
}
else
{
if (!vd->type->isZeroInit(loc))
{
zeroInit = 0;
break;
}
}
}
}
#if DMDV1
/* This doesn't work for DMDV2 because (ref S) and (S) parameter
* lists will overload the same.
*/
/* The TypeInfo_Struct is expecting an opEquals and opCmp with
* a parameter that is a pointer to the struct. But if there
* isn't one, but is an opEquals or opCmp with a value, write
* another that is a shell around the value:
* int opCmp(struct *p) { return opCmp(*p); }
*/
TypeFunction *tfeqptr;
{
Parameters *arguments = new Parameters;
Parameter *arg = new Parameter(STCin, handle, Id::p, NULL);
arguments->push(arg);
tfeqptr = new TypeFunction(arguments, Type::tint32, 0, LINKd);
tfeqptr = (TypeFunction *)tfeqptr->semantic(Loc(), sc);
}
TypeFunction *tfeq;
{
Parameters *arguments = new Parameters;
Parameter *arg = new Parameter(STCin, type, NULL, NULL);
arguments->push(arg);
tfeq = new TypeFunction(arguments, Type::tint32, 0, LINKd);
tfeq = (TypeFunction *)tfeq->semantic(Loc(), sc);
}
Identifier *id = Id::eq;
for (int i = 0; i < 2; i++)
{
Dsymbol *s = search_function(this, id);
FuncDeclaration *fdx = s ? s->isFuncDeclaration() : NULL;
if (fdx)
{ FuncDeclaration *fd = fdx->overloadExactMatch(tfeqptr);
if (!fd)
{ fd = fdx->overloadExactMatch(tfeq);
if (fd)
{ // Create the thunk, fdptr
FuncDeclaration *fdptr = new FuncDeclaration(loc, loc, fdx->ident, STCundefined, tfeqptr);
Expression *e = new IdentifierExp(loc, Id::p);
示例3: visit
void visit(TypeInfoStructDeclaration *d)
{
//printf("TypeInfoStructDeclaration::toDt() '%s'\n", toChars());
if (global.params.is64bit)
verifyStructSize(Type::typeinfostruct, 17 * Target::ptrsize);
else
verifyStructSize(Type::typeinfostruct, 15 * Target::ptrsize);
dtxoff(pdt, Type::typeinfostruct->toVtblSymbol(), 0); // vtbl for TypeInfo_Struct
dtsize_t(pdt, 0); // monitor
assert(d->tinfo->ty == Tstruct);
TypeStruct *tc = (TypeStruct *)d->tinfo;
StructDeclaration *sd = tc->sym;
if (!sd->members)
return;
/* Put out:
* char[] name;
* void[] init;
* hash_t function(in void*) xtoHash;
* bool function(in void*, in void*) xopEquals;
* int function(in void*, in void*) xopCmp;
* string function(const(void)*) xtoString;
* StructFlags m_flags;
* //xgetMembers;
* xdtor;
* xpostblit;
* uint m_align;
* version (X86_64)
* TypeInfo m_arg1;
* TypeInfo m_arg2;
* xgetRTInfo
*/
const char *name = sd->toPrettyChars();
size_t namelen = strlen(name);
dtsize_t(pdt, namelen);
dtabytes(pdt, 0, namelen + 1, name);
// void[] init;
dtsize_t(pdt, sd->structsize); // init.length
if (sd->zeroInit)
dtsize_t(pdt, 0); // NULL for 0 initialization
else
dtxoff(pdt, sd->toInitializer(), 0); // init.ptr
if (FuncDeclaration *fd = search_toHash(sd))
{
dtxoff(pdt, fd->toSymbol(), 0);
TypeFunction *tf = (TypeFunction *)fd->type;
assert(tf->ty == Tfunction);
/* I'm a little unsure this is the right way to do it. Perhaps a better
* way would to automatically add these attributes to any struct member
* function with the name "toHash".
* So I'm leaving this here as an experiment for the moment.
*/
if (!tf->isnothrow || tf->trust == TRUSTsystem /*|| tf->purity == PUREimpure*/)
warning(fd->loc, "toHash() must be declared as extern (D) size_t toHash() const nothrow @safe, not %s", tf->toChars());
}
else
dtsize_t(pdt, 0);
if (sd->xeq)
dtxoff(pdt, sd->xeq->toSymbol(), 0);
else
dtsize_t(pdt, 0);
if (sd->xcmp)
dtxoff(pdt, sd->xcmp->toSymbol(), 0);
else
dtsize_t(pdt, 0);
if (FuncDeclaration *fd = search_toString(sd))
{
dtxoff(pdt, fd->toSymbol(), 0);
}
else
dtsize_t(pdt, 0);
// StructFlags m_flags;
StructFlags::Type m_flags = 0;
if (tc->hasPointers()) m_flags |= StructFlags::hasPointers;
dtsize_t(pdt, m_flags);
#if 0
// xgetMembers
FuncDeclaration *sgetmembers = sd->findGetMembers();
if (sgetmembers)
dtxoff(pdt, sgetmembers->toSymbol(), 0);
else
dtsize_t(pdt, 0); // xgetMembers
#endif
// xdtor
FuncDeclaration *sdtor = sd->dtor;
if (sdtor)
dtxoff(pdt, sdtor->toSymbol(), 0);
//.........这里部分代码省略.........
示例4: toChars
void TypeInfoStructDeclaration::llvmDefine()
{
Logger::println("TypeInfoStructDeclaration::llvmDefine() %s", toChars());
LOG_SCOPE;
// make sure struct is resolved
assert(tinfo->ty == Tstruct);
TypeStruct *tc = static_cast<TypeStruct *>(tinfo);
StructDeclaration *sd = tc->sym;
// can't emit typeinfo for forward declarations
if (sd->sizeok != 1)
{
sd->error("cannot emit TypeInfo for forward declaration");
fatal();
}
sd->codegen(Type::sir);
IrStruct* irstruct = sd->ir.irStruct;
RTTIBuilder b(Type::typeinfostruct);
// char[] name
b.push_string(sd->toPrettyChars());
// void[] init
// never emit a null array, even for zero initialized typeinfo
// the size() method uses this array!
size_t init_size = getTypeStoreSize(tc->irtype->getType());
b.push_void_array(init_size, irstruct->getInitSymbol());
// toX functions ground work
static TypeFunction *tftohash;
static TypeFunction *tftostring;
if (!tftohash)
{
Scope sc;
tftohash = new TypeFunction(NULL, Type::thash_t, 0, LINKd);
#if DMDV2
tftohash ->mod = MODconst;
#endif
tftohash = static_cast<TypeFunction *>(tftohash->semantic(0, &sc));
#if DMDV2
Type *retType = Type::tchar->invariantOf()->arrayOf();
#else
Type *retType = Type::tchar->arrayOf();
#endif
tftostring = new TypeFunction(NULL, retType, 0, LINKd);
tftostring = static_cast<TypeFunction *>(tftostring->semantic(0, &sc));
}
// this one takes a parameter, so we need to build a new one each time
// to get the right type. can we avoid this?
TypeFunction *tfcmpptr;
{
Scope sc;
Parameters *arguments = new Parameters;
#if STRUCTTHISREF
// arg type is ref const T
Parameter *arg = new Parameter(STCref, tc->constOf(), NULL, NULL);
#else
// arg type is const T*
Parameter *arg = new Parameter(STCin, tc->pointerTo(), NULL, NULL);
#endif
arguments->push(arg);
tfcmpptr = new TypeFunction(arguments, Type::tint32, 0, LINKd);
#if DMDV2
tfcmpptr->mod = MODconst;
#endif
tfcmpptr = static_cast<TypeFunction *>(tfcmpptr->semantic(0, &sc));
}
// well use this module for all overload lookups
Module *gm = getModule();
// toHash
FuncDeclaration* fd = find_method_overload(sd, Id::tohash, tftohash, gm);
b.push_funcptr(fd);
// opEquals
#if DMDV2
fd = sd->xeq;
#else
fd = find_method_overload(sd, Id::eq, tfcmpptr, gm);
#endif
b.push_funcptr(fd);
// opCmp
fd = find_method_overload(sd, Id::cmp, tfcmpptr, gm);
b.push_funcptr(fd);
// toString
fd = find_method_overload(sd, Id::tostring, tftostring, gm);
b.push_funcptr(fd);
// uint m_flags;
unsigned hasptrs = tc->hasPointers() ? 1 : 0;
b.push_uint(hasptrs);
//.........这里部分代码省略.........
示例5: assert
//.........这里部分代码省略.........
/* There are problems doing this in the general case because
* Scope keeps track of things like 'offset'
*/
if (s->isEnumDeclaration() || (s->isAggregateDeclaration() && s->ident))
{
//printf("setScope %s %s\n", s->kind(), s->toChars());
s->setScope(sc2);
}
}
for (size_t i = 0; i < members_dim; i++)
{
Dsymbol *s = (Dsymbol *)members->data[i];
s->semantic(sc2);
#if 0
if (sizeok == 2)
{ //printf("forward reference\n");
break;
}
#endif
}
#if DMDV1
/* This doesn't work for DMDV2 because (ref S) and (S) parameter
* lists will overload the same.
*/
/* The TypeInfo_Struct is expecting an opEquals and opCmp with
* a parameter that is a pointer to the struct. But if there
* isn't one, but is an opEquals or opCmp with a value, write
* another that is a shell around the value:
* int opCmp(struct *p) { return opCmp(*p); }
*/
TypeFunction *tfeqptr;
{
Parameters *arguments = new Parameters;
Parameter *arg = new Parameter(STCin, handle, Id::p, NULL);
arguments->push(arg);
tfeqptr = new TypeFunction(arguments, Type::tint32, 0, LINKd);
tfeqptr = (TypeFunction *)tfeqptr->semantic(0, sc);
}
TypeFunction *tfeq;
{
Parameters *arguments = new Parameters;
Parameter *arg = new Parameter(STCin, type, NULL, NULL);
arguments->push(arg);
tfeq = new TypeFunction(arguments, Type::tint32, 0, LINKd);
tfeq = (TypeFunction *)tfeq->semantic(0, sc);
}
Identifier *id = Id::eq;
for (int i = 0; i < 2; i++)
{
Dsymbol *s = search_function(this, id);
FuncDeclaration *fdx = s ? s->isFuncDeclaration() : NULL;
if (fdx)
{ FuncDeclaration *fd = fdx->overloadExactMatch(tfeqptr);
if (!fd)
{ fd = fdx->overloadExactMatch(tfeq);
if (fd)
{ // Create the thunk, fdptr
FuncDeclaration *fdptr = new FuncDeclaration(loc, loc, fdx->ident, STCundefined, tfeqptr);
Expression *e = new IdentifierExp(loc, Id::p);
示例6: printf
//.........这里部分代码省略.........
if (dim != 1)
goto Ldimerror;
RootObject *o = (*e->args)[0];
Dsymbol *s = getDsymbol(o);
if (!s)
{
#if 0
Expression *x = isExpression(o);
Type *t = isType(o);
if (x) printf("e = %s %s\n", Token::toChars(x->op), x->toChars());
if (t) printf("t = %d %s\n", t->ty, t->toChars());
#endif
e->error("first argument is not a symbol");
goto Lfalse;
}
if (s->isImport())
{
s = s->isImport()->mod;
}
//printf("getAttributes %s, attrs = %p, scope = %p\n", s->toChars(), s->userAttribDecl, s->scope);
UserAttributeDeclaration *udad = s->userAttribDecl;
TupleExp *tup = new TupleExp(e->loc, udad ? udad->getAttributes() : new Expressions());
return tup->semantic(sc);
}
else if (e->ident == Id::getFunctionAttributes)
{
/// extract all function attributes as a tuple (const/shared/inout/pure/nothrow/etc) except UDAs.
if (dim != 1)
goto Ldimerror;
RootObject *o = (*e->args)[0];
Dsymbol *s = getDsymbol(o);
Type *t = isType(o);
TypeFunction *tf = NULL;
if (s)
{
if (FuncDeclaration *f = s->isFuncDeclaration())
t = f->type;
else if (VarDeclaration *v = s->isVarDeclaration())
t = v->type;
}
if (t)
{
if (t->ty == Tfunction)
tf = (TypeFunction *)t;
else if (t->ty == Tdelegate)
tf = (TypeFunction *)t->nextOf();
else if (t->ty == Tpointer && t->nextOf()->ty == Tfunction)
tf = (TypeFunction *)t->nextOf();
}
if (!tf)
{
e->error("first argument is not a function");
goto Lfalse;
}
Expressions *mods = new Expressions();
PushAttributes pa;
pa.mods = mods;
tf->modifiersApply(&pa, &PushAttributes::fp);
tf->attributesApply(&pa, &PushAttributes::fp, TRUSTformatSystem);
TupleExp *tup = new TupleExp(e->loc, mods);
示例7: incUsage
void ReturnStatement::toIR(IRState *irs)
{
Blockx *blx = irs->blx;
incUsage(irs, loc);
if (exp)
{ elem *e;
FuncDeclaration *func = irs->getFunc();
assert(func);
assert(func->type->ty == Tfunction);
TypeFunction *tf = (TypeFunction *)(func->type);
enum RET retmethod = tf->retStyle();
if (retmethod == RETstack)
{
elem *es;
/* If returning struct literal, write result
* directly into return value
*/
if (exp->op == TOKstructliteral)
{ StructLiteralExp *se = (StructLiteralExp *)exp;
char save[sizeof(StructLiteralExp)];
memcpy(save, se, sizeof(StructLiteralExp));
se->sym = irs->shidden;
se->soffset = 0;
se->fillHoles = 1;
e = exp->toElemDtor(irs);
memcpy(se, save, sizeof(StructLiteralExp));
}
else
e = exp->toElemDtor(irs);
assert(e);
if (exp->op == TOKstructliteral ||
(func->nrvo_can && func->nrvo_var))
{
// Return value via hidden pointer passed as parameter
// Write exp; return shidden;
es = e;
}
else
{
// Return value via hidden pointer passed as parameter
// Write *shidden=exp; return shidden;
int op;
tym_t ety;
ety = e->Ety;
es = el_una(OPind,ety,el_var(irs->shidden));
op = (tybasic(ety) == TYstruct) ? OPstreq : OPeq;
es = el_bin(op, ety, es, e);
if (op == OPstreq)
es->ET = exp->type->toCtype();
#if DMDV2
/* Call postBlit() on *shidden
*/
Type *tb = exp->type->toBasetype();
//if (tb->ty == Tstruct) exp->dump(0);
if ((exp->op == TOKvar || exp->op == TOKdotvar || exp->op == TOKstar || exp->op == TOKthis) &&
tb->ty == Tstruct)
{ StructDeclaration *sd = ((TypeStruct *)tb)->sym;
if (sd->postblit)
{ FuncDeclaration *fd = sd->postblit;
if (fd->storage_class & STCdisable)
{
fd->toParent()->error(loc, "is not copyable because it is annotated with @disable");
}
elem *ec = el_var(irs->shidden);
ec = callfunc(loc, irs, 1, Type::tvoid, ec, tb->pointerTo(), fd, fd->type, NULL, NULL);
es = el_bin(OPcomma, ec->Ety, es, ec);
}
#if 0
/* It has been moved, so disable destructor
*/
if (exp->op == TOKvar)
{ VarExp *ve = (VarExp *)exp;
VarDeclaration *v = ve->var->isVarDeclaration();
if (v && v->rundtor)
{
elem *er = el_var(v->rundtor->toSymbol());
er = el_bin(OPeq, TYint, er, el_long(TYint, 0));
es = el_bin(OPcomma, TYint, es, er);
}
}
#endif
}
#endif
}
e = el_var(irs->shidden);
e = el_bin(OPcomma, e->Ety, es, e);
}
#if DMDV2
else if (tf->isref)
{ // Reference return, so convert to a pointer
Expression *ae = exp->addressOf(NULL);
e = ae->toElemDtor(irs);
//.........这里部分代码省略.........
示例8: search_function
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;
}
示例9: while
void VisitorNodeTyper::visit(class ExprCall *n) {
ExprSymbol* sym = dynamic_cast<ExprSymbol*>(n->getCallee());
TypeFunction* tf = 0;
// If there are arguments, pass through them to find there types
if (n->getArgs())
{
for (std::vector<Expr*>::iterator it = n->getArgs()->begin(); it != n->getArgs()->end(); it++)
{
(*it)->accept(*this);
}
}
// Set looking for mangled mode to avoid not in symbol table exception
bool old_look_for_mangled = this->look_for_mangled;
this->look_for_mangled = true;
n->getCallee()->accept(*this);
this->look_for_mangled = old_look_for_mangled;
tf = dynamic_cast<TypeFunction*>(n->getCallee()->getType());
std::vector<Signature*>* ss = 0;
Class* cur_class = 0;
if (!tf->getClass())
{
ss = this->sigs[tf->getName()];
}
else
{
std::map<std::string, std::vector<Signature*>* >* spc;
cur_class = tf->getClass();
while (cur_class != 0)
{
spc = this->sigs_per_class[cur_class];
if (spc)
{
ss = (*spc)[tf->getName()];
if (ss)
{
break;
}
}
cur_class = cur_class->getParent();
}
if (!spc)
throw __FILE__ "(" QUOTE(__LINE__) "): No signature table for class " + tf->getClass()->getName() + ".";
}
// TODO optimize
if (!ss)
throw __FILE__ "(" QUOTE(__LINE__) "): Symbol " + tf->getName() + " not in signature tables.";
// Select good function
std::vector<Signature*>::iterator it;
bool insert_this = false;
std::vector<Type*>* choosen_sig = 0;
for (it = ss->begin(); it != ss->end(); it++)
{
// Test for method
if (areCompatible(n->getArgs(), (*it)->getTypes(), true))
{
if (tf->getClass())
{
tf = tf->getClass()->getMethodType((*it)->getMangledName());
n->getCallee()->setType(tf);
}
tf->setName((*it)->getMangledName());
if (choosen_sig)
throw __FILE__ "(" QUOTE(__LINE__) "): Overloading ambiguity !";
tf->setStatic(false);
choosen_sig = (*it)->getTypes();
// Function is non static, get left part of callee and add it on front of arg stack (this)
insert_this = true;
}
// Test for function OR static method
else if(areCompatible(n->getArgs(), (*it)->getTypes()))
{
if (tf->getClass())
{
tf = tf->getClass()->getMethodType((*it)->getMangledName());
n->getCallee()->setType(tf);
}
tf->setName((*it)->getMangledName());
if (choosen_sig)
throw __FILE__ "(" QUOTE(__LINE__) "): Overloading ambiguity !";
choosen_sig = (*it)->getTypes();
tf->setStatic(true);
if (sym)
{
sym->setName((*it)->getMangledName());
}
}
}
if (!choosen_sig)
throw __FILE__ "(" QUOTE(__LINE__) "): No method " + tf->getName()+ " found.";
if (insert_this)
{
ExprOP2* e2 = dynamic_cast<ExprOP2*>(n->getCallee());
//.........这里部分代码省略.........
示例10: incUsage
void ReturnStatement::toIR(IRState *irs)
{
Blockx *blx = irs->blx;
enum BC bc;
incUsage(irs, loc);
if (exp)
{ elem *e;
FuncDeclaration *func = irs->getFunc();
assert(func);
assert(func->type->ty == Tfunction);
TypeFunction *tf = (TypeFunction *)(func->type);
enum RET retmethod = tf->retStyle();
if (retmethod == RETstack)
{
elem *es;
/* If returning struct literal, write result
* directly into return value
*/
if (exp->op == TOKstructliteral)
{ StructLiteralExp *se = (StructLiteralExp *)exp;
char save[sizeof(StructLiteralExp)];
memcpy(save, se, sizeof(StructLiteralExp));
se->sym = irs->shidden;
se->soffset = 0;
se->fillHoles = 1;
e = exp->toElemDtor(irs);
memcpy(se, save, sizeof(StructLiteralExp));
}
else
e = exp->toElemDtor(irs);
assert(e);
if (exp->op == TOKstructliteral ||
(func->nrvo_can && func->nrvo_var))
{
// Return value via hidden pointer passed as parameter
// Write exp; return shidden;
es = e;
}
else
{
// Return value via hidden pointer passed as parameter
// Write *shidden=exp; return shidden;
int op;
tym_t ety;
ety = e->Ety;
es = el_una(OPind,ety,el_var(irs->shidden));
op = (tybasic(ety) == TYstruct) ? OPstreq : OPeq;
es = el_bin(op, ety, es, e);
if (op == OPstreq)
es->ET = exp->type->toCtype();
#if 0//DMDV2
/* Call postBlit() on *shidden
*/
Type *tb = exp->type->toBasetype();
//if (tb->ty == Tstruct) exp->dump(0);
if (exp->isLvalue() && tb->ty == Tstruct)
{ StructDeclaration *sd = ((TypeStruct *)tb)->sym;
if (sd->postblit)
{ FuncDeclaration *fd = sd->postblit;
if (fd->storage_class & STCdisable)
{
fd->toParent()->error(loc, "is not copyable because it is annotated with @disable");
}
elem *ec = el_var(irs->shidden);
ec = callfunc(loc, irs, 1, Type::tvoid, ec, tb->pointerTo(), fd, fd->type, NULL, NULL);
es = el_bin(OPcomma, ec->Ety, es, ec);
}
}
#endif
}
e = el_var(irs->shidden);
e = el_bin(OPcomma, e->Ety, es, e);
}
#if DMDV2
else if (tf->isref)
{ // Reference return, so convert to a pointer
Expression *ae = exp->addressOf(NULL);
e = ae->toElemDtor(irs);
}
#endif
else
{
e = exp->toElemDtor(irs);
assert(e);
}
elem_setLoc(e, loc);
block_appendexp(blx->curblock, e);
bc = BCretexp;
}
else
bc = BCret;
block *btry = blx->curblock->Btry;
//.........这里部分代码省略.........
示例11: Parameter
FuncDeclaration *buildXopCmp(StructDeclaration *sd, Scope *sc)
{
//printf("StructDeclaration::buildXopCmp() %s\n", toChars());
if (Dsymbol *cmp = search_function(sd, Id::cmp))
{
if (FuncDeclaration *fd = cmp->isFuncDeclaration())
{
TypeFunction *tfcmpptr;
{
Scope scx;
/* const int opCmp(ref const S s);
*/
Parameters *parameters = new Parameters;
parameters->push(new Parameter(STCref | STCconst, sd->type, NULL, NULL));
tfcmpptr = new TypeFunction(parameters, Type::tint32, 0, LINKd);
tfcmpptr->mod = MODconst;
tfcmpptr = (TypeFunction *)tfcmpptr->semantic(Loc(), &scx);
}
fd = fd->overloadExactMatch(tfcmpptr);
if (fd)
return fd;
}
}
else
{
#if 0 // FIXME: doesn't work for recursive alias this
/* Check opCmp member exists.
* Consider 'alias this', but except opDispatch.
*/
Expression *e = new DsymbolExp(sd->loc, sd);
e = new DotIdExp(sd->loc, e, Id::cmp);
Scope *sc2 = sc->push();
e = e->trySemantic(sc2);
sc2->pop();
if (e)
{
Dsymbol *s = NULL;
switch (e->op)
{
case TOKoverloadset: s = ((OverExp *)e)->vars; break;
case TOKimport: s = ((ScopeExp *)e)->sds; break;
case TOKvar: s = ((VarExp *)e)->var; break;
default: break;
}
if (!s || s->ident != Id::cmp)
e = NULL; // there's no valid member 'opCmp'
}
if (!e)
return NULL; // bitwise comparison would work
/* Essentially, a struct which does not define opCmp is not comparable.
* At this time, typeid(S).compare might be correct that throwing "not implement" Error.
* But implementing it would break existing code, such as:
*
* struct S { int value; } // no opCmp
* int[S] aa; // Currently AA key uses bitwise comparison
* // (It's default behavior of TypeInfo_Strust.compare).
*
* Not sure we should fix this inconsistency, so just keep current behavior.
*/
#else
return NULL;
#endif
}
if (!sd->xerrcmp)
{
// object._xopCmp
Identifier *id = Lexer::idPool("_xopCmp");
Expression *e = new IdentifierExp(sd->loc, Id::empty);
e = new DotIdExp(sd->loc, e, Id::object);
e = new DotIdExp(sd->loc, e, id);
e = e->semantic(sc);
Dsymbol *s = getDsymbol(e);
if (!s)
{
::error(Loc(), "ICE: %s not found in object module. You must update druntime", id->toChars());
fatal();
}
assert(s);
sd->xerrcmp = s->isFuncDeclaration();
}
Loc declLoc = Loc(); // loc is unnecessary so __xopCmp is never called directly
Loc loc = Loc(); // loc is unnecessary so errors are gagged
Parameters *parameters = new Parameters;
parameters->push(new Parameter(STCref | STCconst, sd->type, Id::p, NULL));
parameters->push(new Parameter(STCref | STCconst, sd->type, Id::q, NULL));
TypeFunction *tf = new TypeFunction(parameters, Type::tint32, 0, LINKd);
Identifier *id = Id::xopCmp;
FuncDeclaration *fop = new FuncDeclaration(declLoc, Loc(), id, STCstatic, tf);
Expression *e1 = new IdentifierExp(loc, Id::p);
Expression *e2 = new IdentifierExp(loc, Id::q);
Expression *e = new CallExp(loc, new DotIdExp(loc, e2, Id::cmp), e1);
fop->fbody = new ReturnStatement(loc, e);
//.........这里部分代码省略.........
示例12: visit
void visit(CallExp *e)
{
/* If the function returns by ref, check each argument that is
* passed as 'return ref'.
*/
Type *t1 = e->e1->type->toBasetype();
TypeFunction *tf;
if (t1->ty == Tdelegate)
tf = (TypeFunction *)((TypeDelegate *)t1)->next;
else if (t1->ty == Tfunction)
tf = (TypeFunction *)t1;
else
return;
if (tf->isref)
{
if (e->arguments && e->arguments->dim)
{
/* j=1 if _arguments[] is first argument,
* skip it because it is not passed by ref
*/
int j = (tf->linkage == LINKd && tf->varargs == 1);
for (size_t i = j; i < e->arguments->dim; ++i)
{
Expression *arg = (*e->arguments)[i];
size_t nparams = Parameter::dim(tf->parameters);
if (i - j < nparams && i >= j)
{
Parameter *p = Parameter::getNth(tf->parameters, i - j);
const StorageClass stc = tf->parameterStorageClass(p);
if ((stc & (STCout | STCref)) && (stc & STCreturn))
arg->accept(this);
else if ((stc & STCscope) && (stc & STCreturn))
{
if (arg->op == TOKdelegate)
{
DelegateExp *de = (DelegateExp *)arg;
if (de->func->isNested())
er->byexp.push(de);
}
else
escapeByValue(arg, er);
}
}
}
}
// If 'this' is returned by ref, check it too
if (e->e1->op == TOKdotvar && t1->ty == Tfunction)
{
DotVarExp *dve = (DotVarExp *)e->e1;
if (dve->var->storage_class & STCreturn || tf->isreturn)
{
if ((dve->var->storage_class & STCscope) || tf->isscope)
escapeByValue(dve->e1, er);
else if ((dve->var->storage_class & STCref) || tf->isref)
dve->e1->accept(this);
}
}
// If it's a delegate, check it too
if (e->e1->op == TOKvar && t1->ty == Tdelegate)
{
escapeByValue(e->e1, er);
}
}
else
er->byexp.push(e);
}
示例13: dtxoff
void TypeInfoStructDeclaration::toDt(dt_t **pdt)
{
//printf("TypeInfoStructDeclaration::toDt() '%s'\n", toChars());
unsigned offset = Type::typeinfostruct->structsize;
dtxoff(pdt, Type::typeinfostruct->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Struct
dtdword(pdt, 0); // monitor
assert(tinfo->ty == Tstruct);
TypeStruct *tc = (TypeStruct *)tinfo;
StructDeclaration *sd = tc->sym;
/* Put out:
* char[] name;
* void[] init;
* hash_t function(void*) xtoHash;
* int function(void*,void*) xopEquals;
* int function(void*,void*) xopCmp;
* char[] function(void*) xtoString;
* uint m_flags;
*
* name[]
*/
const char *name = sd->toPrettyChars();
size_t namelen = strlen(name);
dtdword(pdt, namelen);
//dtabytes(pdt, TYnptr, 0, namelen + 1, name);
dtxoff(pdt, toSymbol(), offset, TYnptr);
offset += namelen + 1;
// void[] init;
dtdword(pdt, sd->structsize); // init.length
if (sd->zeroInit)
dtdword(pdt, 0); // NULL for 0 initialization
else
dtxoff(pdt, sd->toInitializer(), 0, TYnptr); // init.ptr
FuncDeclaration *fd;
FuncDeclaration *fdx;
TypeFunction *tf;
Type *ta;
Dsymbol *s;
static TypeFunction *tftohash;
static TypeFunction *tftostring;
if (!tftohash)
{
Scope sc;
tftohash = new TypeFunction(NULL, Type::thash_t, 0, LINKd);
tftohash = (TypeFunction *)tftohash->semantic(0, &sc);
tftostring = new TypeFunction(NULL, Type::tchar->arrayOf(), 0, LINKd);
tftostring = (TypeFunction *)tftostring->semantic(0, &sc);
}
TypeFunction *tfeqptr;
{
Scope sc;
Parameters *arguments = new Parameters;
#if STRUCTTHISREF
// arg type is ref const T
Parameter *arg = new Parameter(STCref, tc->constOf(), NULL, NULL);
#else
// arg type is const T*
Parameter *arg = new Parameter(STCin, tc->pointerTo(), NULL, NULL);
#endif
arguments->push(arg);
tfeqptr = new TypeFunction(arguments, Type::tint32, 0, LINKd);
tfeqptr = (TypeFunction *)tfeqptr->semantic(0, &sc);
}
#if 0
TypeFunction *tfeq;
{
Scope sc;
Array *arguments = new Array;
Parameter *arg = new Parameter(In, tc, NULL, NULL);
arguments->push(arg);
tfeq = new TypeFunction(arguments, Type::tint32, 0, LINKd);
tfeq = (TypeFunction *)tfeq->semantic(0, &sc);
}
#endif
s = search_function(sd, Id::tohash);
fdx = s ? s->isFuncDeclaration() : NULL;
if (fdx)
{ fd = fdx->overloadExactMatch(tftohash);
if (fd)
dtxoff(pdt, fd->toSymbol(), 0, TYnptr);
else
//fdx->error("must be declared as extern (D) uint toHash()");
dtdword(pdt, 0);
}
//.........这里部分代码省略.........
示例14: Parameter
FuncDeclaration *StructDeclaration::buildXopEquals(Scope *sc)
{
if (!search_function(this, Id::eq))
return NULL;
/* static bool__xopEquals(in void* p, in void* q) {
* return ( *cast(const S*)(p) ).opEquals( *cast(const S*)(q) );
* }
*/
Parameters *parameters = new Parameters;
parameters->push(new Parameter(STCin, Type::tvoidptr, Id::p, NULL));
parameters->push(new Parameter(STCin, Type::tvoidptr, Id::q, NULL));
TypeFunction *tf = new TypeFunction(parameters, Type::tbool, 0, LINKd);
tf = (TypeFunction *)tf->semantic(loc, sc);
Identifier *id = Lexer::idPool("__xopEquals");
FuncDeclaration *fop = new FuncDeclaration(loc, 0, id, STCstatic, tf);
Expression *e = new CallExp(0,
new DotIdExp(0,
new PtrExp(0, new CastExp(0,
new IdentifierExp(0, Id::p), type->pointerTo()->constOf())),
Id::eq),
new PtrExp(0, new CastExp(0,
new IdentifierExp(0, Id::q), type->pointerTo()->constOf())));
fop->fbody = new ReturnStatement(loc, e);
size_t index = members->dim;
members->push(fop);
sc = sc->push();
sc->stc = 0;
sc->linkage = LINKd;
unsigned errors = global.startGagging();
fop->semantic(sc);
if (errors == global.gaggedErrors)
{ fop->semantic2(sc);
if (errors == global.gaggedErrors)
{ fop->semantic3(sc);
if (errors == global.gaggedErrors)
fop->addMember(sc, this, 1);
}
}
if (global.endGagging(errors)) // if errors happened
{
members->remove(index);
if (!xerreq)
{
Expression *e = new IdentifierExp(loc, Id::empty);
e = new DotIdExp(loc, e, Id::object);
e = new DotIdExp(loc, e, Lexer::idPool("_xopEquals"));
e = e->semantic(sc);
Dsymbol *s = getDsymbol(e);
FuncDeclaration *fd = s->isFuncDeclaration();
xerreq = fd;
}
fop = xerreq;
}
sc->pop();
return fop;
}
示例15: dtxoff
void TypeInfoStructDeclaration::toDt(dt_t **pdt)
{
//printf("TypeInfoStructDeclaration::toDt() '%s'\n", toChars());
unsigned offset = Type::typeinfostruct->structsize;
dtxoff(pdt, Type::typeinfostruct->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Struct
dtsize_t(pdt, 0); // monitor
assert(tinfo->ty == Tstruct);
TypeStruct *tc = (TypeStruct *)tinfo;
StructDeclaration *sd = tc->sym;
/* Put out:
* char[] name;
* void[] init;
* hash_t function(in void*) xtoHash;
* bool function(in void*, in void*) xopEquals;
* int function(in void*, in void*) xopCmp;
* string function(const(void)*) xtoString;
* uint m_flags;
* xgetMembers;
* xdtor;
* xpostblit;
* uint m_align;
* version (X86_64)
* TypeInfo m_arg1;
* TypeInfo m_arg2;
*
* name[]
*/
const char *name = sd->toPrettyChars();
size_t namelen = strlen(name);
dtsize_t(pdt, namelen);
//dtabytes(pdt, TYnptr, 0, namelen + 1, name);
dtxoff(pdt, toSymbol(), offset, TYnptr);
offset += namelen + 1;
// void[] init;
dtsize_t(pdt, sd->structsize); // init.length
if (sd->zeroInit)
dtsize_t(pdt, 0); // NULL for 0 initialization
else
dtxoff(pdt, sd->toInitializer(), 0, TYnptr); // init.ptr
FuncDeclaration *fd;
FuncDeclaration *fdx;
Dsymbol *s;
static TypeFunction *tftohash;
static TypeFunction *tftostring;
if (!tftohash)
{
Scope sc;
tftohash = new TypeFunction(NULL, Type::thash_t, 0, LINKd);
tftohash->mod = MODconst;
tftohash = (TypeFunction *)tftohash->semantic(0, &sc);
tftostring = new TypeFunction(NULL, Type::tchar->invariantOf()->arrayOf(), 0, LINKd);
tftostring = (TypeFunction *)tftostring->semantic(0, &sc);
}
TypeFunction *tfcmpptr;
{
Scope sc;
Parameters *arguments = new Parameters;
#if STRUCTTHISREF
// arg type is ref const T
Parameter *arg = new Parameter(STCref, tc->constOf(), NULL, NULL);
#else
// arg type is const T*
Parameter *arg = new Parameter(STCin, tc->pointerTo(), NULL, NULL);
#endif
arguments->push(arg);
tfcmpptr = new TypeFunction(arguments, Type::tint32, 0, LINKd);
tfcmpptr->mod = MODconst;
tfcmpptr = (TypeFunction *)tfcmpptr->semantic(0, &sc);
}
s = search_function(sd, Id::tohash);
fdx = s ? s->isFuncDeclaration() : NULL;
if (fdx)
{ fd = fdx->overloadExactMatch(tftohash);
if (fd)
dtxoff(pdt, fd->toSymbol(), 0, TYnptr);
else
//fdx->error("must be declared as extern (D) uint toHash()");
dtsize_t(pdt, 0);
}
else
dtsize_t(pdt, 0);
if (sd->xeq)
dtxoff(pdt, sd->xeq->toSymbol(), 0, TYnptr);
else
//.........这里部分代码省略.........