本文整理汇总了C++中Dsymbol类的典型用法代码示例。如果您正苦于以下问题:C++ Dsymbol类的具体用法?C++ Dsymbol怎么用?C++ Dsymbol使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了Dsymbol类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: importAll
void Module::semantic()
{
if (semanticstarted)
return;
//printf("+Module::semantic(this = %p, '%s'): parent = %p\n", this, toChars(), parent);
semanticstarted = 1;
// Note that modules get their own scope, from scratch.
// This is so regardless of where in the syntax a module
// gets imported, it is unaffected by context.
Scope *sc = scope; // see if already got one from importAll()
if (!sc)
{ printf("test2\n");
Scope::createGlobal(this); // create root scope
}
//printf("Module = %p, linkage = %d\n", sc->scopesym, sc->linkage);
#if 0
// Add import of "object" if this module isn't "object"
if (ident != Id::object)
{
Import *im = new Import(0, NULL, Id::object, NULL, 0);
members->shift(im);
}
// Add all symbols into module's symbol table
symtab = new DsymbolTable();
for (size_t i = 0; i < members->dim; i++)
{ Dsymbol *s = (Dsymbol *)members->data[i];
s->addMember(NULL, sc->scopesym, 1);
}
/* Set scope for the symbols so that if we forward reference
* a symbol, it can possibly be resolved on the spot.
* If this works out well, it can be extended to all modules
* before any semantic() on any of them.
*/
for (size_t i = 0; i < members->dim; i++)
{ Dsymbol *s = (Dsymbol *)members->data[i];
s->setScope(sc);
}
#endif
// Do semantic() on members that don't depend on others
for (size_t i = 0; i < members->dim; i++)
{ Dsymbol *s = members->tdata()[i];
//printf("\tModule('%s'): '%s'.semantic0()\n", toChars(), s->toChars());
s->semantic0(sc);
}
// Pass 1 semantic routines: do public side of the definition
for (size_t i = 0; i < members->dim; i++)
{ Dsymbol *s = members->tdata()[i];
//printf("\tModule('%s'): '%s'.semantic()\n", toChars(), s->toChars());
s->semantic(sc);
runDeferredSemantic();
}
if (!scope)
{ sc = sc->pop();
sc->pop(); // 2 pops because Scope::createGlobal() created 2
}
semanticRun = semanticstarted;
//printf("-Module::semantic(this = %p, '%s'): parent = %p\n", this, toChars(), parent);
}
示例2: error
Dsymbol *ArrayScopeSymbol::search(Loc loc, Identifier *ident, int flags)
{
//printf("ArrayScopeSymbol::search('%s', flags = %d)\n", ident->toChars(), flags);
if (ident == Id::length || ident == Id::dollar)
{ VarDeclaration **pvar;
Expression *ce;
if (ident == Id::length && !global.params.useDeprecated)
error("using 'length' inside [ ] is deprecated, use '$' instead");
L1:
if (td)
{ /* $ gives the number of elements in the tuple
*/
VarDeclaration *v = new VarDeclaration(loc, Type::tsize_t, Id::dollar, NULL);
Expression *e = new IntegerExp(0, td->objects->dim, Type::tsize_t);
v->init = new ExpInitializer(0, e);
v->storage_class |= STCstatic | STCconst;
v->semantic(sc);
return v;
}
if (type)
{ /* $ gives the number of type entries in the type tuple
*/
VarDeclaration *v = new VarDeclaration(loc, Type::tsize_t, Id::dollar, NULL);
Expression *e = new IntegerExp(0, type->arguments->dim, Type::tsize_t);
v->init = new ExpInitializer(0, e);
v->storage_class |= STCstatic | STCconst;
v->semantic(sc);
return v;
}
if (exp->op == TOKindex)
{ /* array[index] where index is some function of $
*/
IndexExp *ie = (IndexExp *)exp;
pvar = &ie->lengthVar;
ce = ie->e1;
}
else if (exp->op == TOKslice)
{ /* array[lwr .. upr] where lwr or upr is some function of $
*/
SliceExp *se = (SliceExp *)exp;
pvar = &se->lengthVar;
ce = se->e1;
}
else if (exp->op == TOKarray)
{ /* array[e0, e1, e2, e3] where e0, e1, e2 are some function of $
* $ is a opDollar!(dim)() where dim is the dimension(0,1,2,...)
*/
ArrayExp *ae = (ArrayExp *)exp;
AggregateDeclaration *ad = NULL;
Type *t = ae->e1->type->toBasetype();
if (t->ty == Tclass)
{
ad = ((TypeClass *)t)->sym;
}
else if (t->ty == Tstruct)
{
ad = ((TypeStruct *)t)->sym;
}
assert(ad);
Dsymbol *dsym = search_function(ad, Id::opDollar);
if (!dsym) // no dollar exists -- search in higher scope
return NULL;
VarDeclaration *v = ae->lengthVar;
if (!v)
{ // $ is lazily initialized. Create it now.
TemplateDeclaration *td = dsym->isTemplateDeclaration();
if (td)
{ // Instantiate opDollar!(dim) with the index as a template argument
Objects *tdargs = new Objects();
tdargs->setDim(1);
Expression *x = new IntegerExp(0, ae->currentDimension, Type::tsize_t);
x = x->semantic(sc);
tdargs->data[0] = x;
//TemplateInstance *ti = new TemplateInstance(loc, td, tdargs);
//ti->semantic(sc);
DotTemplateInstanceExp *dte = new DotTemplateInstanceExp(loc, ae->e1, td->ident, tdargs);
v = new VarDeclaration(loc, NULL, Id::dollar, new ExpInitializer(0, dte));
}
else
{ /* opDollar exists, but it's a function, 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 (ae->arguments->dim != 1) {
ae->error("%s only defines opDollar for one dimension", ad->toChars());
return NULL;
//.........这里部分代码省略.........
示例3: if
Dsymbol *ScopeDsymbol::search(Loc loc, Identifier *ident, int flags)
{
//printf("%s->ScopeDsymbol::search(ident='%s', flags=x%x)\n", toChars(), ident->toChars(), flags);
//if (strcmp(ident->toChars(),"c") == 0) *(char*)0=0;
// Look in symbols declared in this module
Dsymbol *s = symtab ? symtab->lookup(ident) : NULL;
//printf("\ts = %p, imports = %p, %d\n", s, imports, imports ? imports->dim : 0);
if (s)
{
//printf("\ts = '%s.%s'\n",toChars(),s->toChars());
}
else if (imports)
{
OverloadSet *a = NULL;
// Look in imported modules
for (size_t i = 0; i < imports->dim; i++)
{ ScopeDsymbol *ss = (*imports)[i];
Dsymbol *s2;
// If private import, don't search it
if (flags & 1 && prots[i] == PROTprivate)
continue;
//printf("\tscanning import '%s', prots = %d, isModule = %p, isImport = %p\n", ss->toChars(), prots[i], ss->isModule(), ss->isImport());
/* Don't find private members if ss is a module
*/
s2 = ss->search(loc, ident, ss->isModule() ? 1 : 0);
if (!s)
s = s2;
else if (s2 && s != s2)
{
if (s->toAlias() == s2->toAlias())
{
/* After following aliases, we found the same symbol,
* so it's not an ambiguity.
* But if one alias is deprecated, prefer the other.
*/
if (s->isDeprecated())
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))
)
)
)
{
/* 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();
/* 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())
a->a[j] = s2;
goto Lcontinue;
}
}
a->push(s2);
Lcontinue:
continue;
}
if (flags & 4) // if return NULL on ambiguity
return NULL;
if (!(flags & 2))
ss->multiplyDefined(loc, s, s2);
break;
}
}
}
}
/* Build special symbol if we had multiple finds
*/
if (a)
{ assert(s);
a->push(s);
s = a;
}
if (s)
{
Declaration *d = s->isDeclaration();
if (d && d->protection == PROTprivate &&
//.........这里部分代码省略.........
示例4: 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;
}
示例5: assert
FuncDeclaration *AggregateDeclaration::buildDtor(Scope *sc)
{
//printf("AggregateDeclaration::buildDtor() %s\n", toChars());
Expression *e = NULL;
#if DMDV2
for (size_t i = 0; i < fields.dim; i++)
{
Dsymbol *s = fields.tdata()[i];
VarDeclaration *v = s->isVarDeclaration();
assert(v && v->storage_class & STCfield);
if (v->storage_class & STCref)
continue;
Type *tv = v->type->toBasetype();
dinteger_t dim = (tv->ty == Tsarray ? 1 : 0);
while (tv->ty == Tsarray)
{ TypeSArray *ta = (TypeSArray *)tv;
dim *= ((TypeSArray *)tv)->dim->toInteger();
tv = tv->nextOf()->toBasetype();
}
if (tv->ty == Tstruct)
{ TypeStruct *ts = (TypeStruct *)tv;
StructDeclaration *sd = ts->sym;
if (sd->dtor)
{ Expression *ex;
// this.v
ex = new ThisExp(0);
ex = new DotVarExp(0, ex, v, 0);
if (dim == 0)
{ // this.v.dtor()
ex = new DotVarExp(0, ex, sd->dtor, 0);
ex = new CallExp(0, ex);
}
else
{
// Typeinfo.destroy(cast(void*)&this.v);
Expression *ea = new AddrExp(0, ex);
ea = new CastExp(0, ea, Type::tvoid->pointerTo());
Expression *et = v->type->getTypeInfo(sc);
et = new DotIdExp(0, et, Id::destroy);
ex = new CallExp(0, et, ea);
}
e = Expression::combine(ex, e); // combine in reverse order
}
}
}
/* Build our own "destructor" which executes e
*/
if (e)
{ //printf("Building __fieldDtor()\n");
DtorDeclaration *dd = new DtorDeclaration(loc, 0, Lexer::idPool("__fieldDtor"));
dd->fbody = new ExpStatement(0, e);
dtors.shift(dd);
members->push(dd);
dd->semantic(sc);
}
#endif
switch (dtors.dim)
{
case 0:
return NULL;
case 1:
return dtors.tdata()[0];
default:
e = NULL;
for (size_t i = 0; i < dtors.dim; i++)
{ FuncDeclaration *fd = dtors.tdata()[i];
Expression *ex = new ThisExp(0);
ex = new DotVarExp(0, ex, fd, 0);
ex = new CallExp(0, ex);
e = Expression::combine(ex, e);
}
DtorDeclaration *dd = new DtorDeclaration(loc, 0, Lexer::idPool("__aggrDtor"));
dd->fbody = new ExpStatement(0, e);
members->push(dd);
dd->semantic(sc);
return dd;
}
}
示例6: obj_append
void FuncDeclaration::toObjFile(int multiobj)
{
FuncDeclaration *func = this;
ClassDeclaration *cd = func->parent->isClassDeclaration();
int reverse;
int has_arguments;
//printf("FuncDeclaration::toObjFile(%p, %s.%s)\n", func, parent->toChars(), func->toChars());
//if (type) printf("type = %s\n", func->type->toChars());
#if 0
//printf("line = %d\n",func->getWhere() / LINEINC);
EEcontext *ee = env->getEEcontext();
if (ee->EEcompile == 2)
{
if (ee->EElinnum < (func->getWhere() / LINEINC) ||
ee->EElinnum > (func->endwhere / LINEINC)
)
return; // don't compile this function
ee->EEfunc = func->toSymbol();
}
#endif
if (semanticRun >= PASSobj) // if toObjFile() already run
return;
// If errors occurred compiling it, such as bugzilla 6118
if (type && type->ty == Tfunction && ((TypeFunction *)type)->next->ty == Terror)
return;
if (!func->fbody)
{
return;
}
if (func->isUnitTestDeclaration() && !global.params.useUnitTests)
return;
if (multiobj && !isStaticDtorDeclaration() && !isStaticCtorDeclaration())
{ obj_append(this);
return;
}
if (semanticRun == PASSsemanticdone)
{
/* What happened is this function failed semantic3() with errors,
* but the errors were gagged.
* Try to reproduce those errors, and then fail.
*/
error("errors compiling the function");
return;
}
assert(semanticRun == PASSsemantic3done);
semanticRun = PASSobj;
if (global.params.verbose)
printf("function %s\n",func->toPrettyChars());
Symbol *s = func->toSymbol();
func_t *f = s->Sfunc;
#if TARGET_WINDOS
/* This is done so that the 'this' pointer on the stack is the same
* distance away from the function parameters, so that an overriding
* function can call the nested fdensure or fdrequire of its overridden function
* and the stack offsets are the same.
*/
if (isVirtual() && (fensure || frequire))
f->Fflags3 |= Ffakeeh;
#endif
#if TARGET_OSX
s->Sclass = SCcomdat;
#else
s->Sclass = SCglobal;
#endif
for (Dsymbol *p = parent; p; p = p->parent)
{
if (p->isTemplateInstance())
{
s->Sclass = SCcomdat;
break;
}
}
/* Vector operations should be comdat's
*/
if (isArrayOp)
s->Sclass = SCcomdat;
if (isNested())
{
// if (!(config.flags3 & CFG3pic))
// s->Sclass = SCstatic;
f->Fflags3 |= Fnested;
/* The enclosing function must have its code generated first,
* so we know things like where its local symbols are stored.
*/
FuncDeclaration *fdp = toAliasFunc()->toParent2()->isFuncDeclaration();
// Bug 8016 - only include the function if it is a template instance
Dsymbol * owner = NULL;
//.........这里部分代码省略.........
示例7: checkAccess
/*******************************
* Do access check for member of this class, this class being the
* type of the 'this' pointer used to access smember.
* Returns true if the member is not accessible.
*/
bool checkAccess(AggregateDeclaration *ad, Loc loc, Scope *sc, Dsymbol *smember)
{
FuncDeclaration *f = sc->func;
AggregateDeclaration *cdscope = sc->getStructClassScope();
#if LOG
printf("AggregateDeclaration::checkAccess() for %s.%s in function %s() in scope %s\n",
ad->toChars(), smember->toChars(),
f ? f->toChars() : NULL,
cdscope ? cdscope->toChars() : NULL);
#endif
Dsymbol *smemberparent = smember->toParent();
if (!smemberparent || !smemberparent->isAggregateDeclaration())
{
#if LOG
printf("not an aggregate member\n");
#endif
return false; // then it is accessible
}
// BUG: should enable this check
//assert(smember->parent->isBaseOf(this, NULL));
bool result;
Prot access;
if (smemberparent == ad)
{
Prot access2 = smember->prot();
result = access2.kind >= PROTpublic ||
hasPrivateAccess(ad, f) ||
isFriendOf(ad, cdscope) ||
(access2.kind == PROTpackage && hasPackageAccess(sc, ad)) ||
ad->getAccessModule() == sc->module;
#if LOG
printf("result1 = %d\n", result);
#endif
}
else if ((access = getAccess(ad, smember)).kind >= PROTpublic)
{
result = true;
#if LOG
printf("result2 = %d\n", result);
#endif
}
else if (access.kind == PROTpackage && hasPackageAccess(sc, ad))
{
result = true;
#if LOG
printf("result3 = %d\n", result);
#endif
}
else
{
result = isAccessible(smember, f, ad, cdscope);
#if LOG
printf("result4 = %d\n", result);
#endif
}
if (!result)
{
ad->error(loc, "member %s is not accessible", smember->toChars());
//printf("smember = %s %s, prot = %d, semanticRun = %d\n",
// smember->kind(), smember->toPrettyChars(), smember->prot(), smember->semanticRun);
return true;
}
return false;
}
示例8: 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);
tf = (TypeFunction *)tf->semantic(loc, sc);
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, e1, Id::cmp), e2);
fop->fbody = new ReturnStatement(loc, e);
//.........这里部分代码省略.........
示例9: setFieldOffset
void AnonDeclaration::setFieldOffset(AggregateDeclaration *ad, unsigned *poffset, bool isunion)
{
//printf("\tAnonDeclaration::setFieldOffset %s %p\n", isunion ? "union" : "struct", this);
if (decl)
{
/* This works by treating an AnonDeclaration as an aggregate 'member',
* so in order to place that member we need to compute the member's
* size and alignment.
*/
size_t fieldstart = ad->fields.dim;
/* Hackishly hijack ad's structsize and alignsize fields
* for use in our fake anon aggregate member.
*/
unsigned savestructsize = ad->structsize;
unsigned savealignsize = ad->alignsize;
ad->structsize = 0;
ad->alignsize = 0;
unsigned offset = 0;
for (size_t i = 0; i < decl->dim; i++)
{
Dsymbol *s = (*decl)[i];
s->setFieldOffset(ad, &offset, this->isunion);
if (this->isunion)
offset = 0;
}
unsigned anonstructsize = ad->structsize;
unsigned anonalignsize = ad->alignsize;
ad->structsize = savestructsize;
ad->alignsize = savealignsize;
// 0 sized structs are set to 1 byte
if (anonstructsize == 0)
{
anonstructsize = 1;
anonalignsize = 1;
}
/* Given the anon 'member's size and alignment,
* go ahead and place it.
*/
unsigned anonoffset = AggregateDeclaration::placeField(
poffset,
anonstructsize, anonalignsize, alignment,
&ad->structsize, &ad->alignsize,
isunion);
// Add to the anon fields the base offset of this anonymous aggregate
//printf("anon fields, anonoffset = %d\n", anonoffset);
for (size_t i = fieldstart; i < ad->fields.dim; i++)
{
VarDeclaration *v = ad->fields[i];
//printf("\t[%d] %s %d\n", i, v->toChars(), v->offset);
v->offset += anonoffset;
}
}
}
示例10: Loc
//.........这里部分代码省略.........
{
/* Do swap this and rhs
* tmp = this; this = s; tmp.dtor();
*/
//printf("\tswap copy\n");
Identifier *idtmp = Lexer::uniqueId("__tmp");
VarDeclaration *tmp = NULL;
AssignExp *ec = NULL;
if (sd->dtor)
{
tmp = new VarDeclaration(loc, sd->type, idtmp, new VoidInitializer(loc));
tmp->noscope = 1;
tmp->storage_class |= STCtemp | STCctfe;
e = new DeclarationExp(loc, tmp);
ec = new BlitExp(loc, new VarExp(loc, tmp), new ThisExp(loc));
e = Expression::combine(e, ec);
}
ec = new BlitExp(loc, new ThisExp(loc), new IdentifierExp(loc, Id::p));
e = Expression::combine(e, ec);
if (sd->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), sd->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 < sd->fields.dim; i++)
{
VarDeclaration *v = sd->fields[i];
// 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(sd, 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);
s = tempdecl;
}
#endif
sd->members->push(s);
s->addMember(sc, sd, 1);
sd->hasIdentityAssign = true; // 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;
}
示例11: error
// Put out instance of ModuleInfo for this Module
void Module::genmoduleinfo()
{
// resolve ModuleInfo
if (!moduleinfo)
{
error("object.d is missing the ModuleInfo struct");
fatal();
}
// check for patch
else
{
// The base struct should consist only of _flags/_index.
if (moduleinfo->structsize != 4 + 4)
{
error("object.d ModuleInfo class is incorrect");
fatal();
}
}
// use the RTTIBuilder
RTTIBuilder b(moduleinfo);
// some types
LLType* moduleinfoTy = moduleinfo->type->irtype->getLLType();
LLType* classinfoTy = Type::typeinfoclass->type->irtype->getLLType();
// importedModules[]
std::vector<LLConstant*> importInits;
LLConstant* importedModules = 0;
llvm::ArrayType* importedModulesTy = 0;
for (size_t i = 0; i < aimports.dim; i++)
{
Module *m = static_cast<Module *>(aimports.data[i]);
if (!m->needModuleInfo() || m == this)
continue;
// declare the imported module info
std::string m_name("_D");
m_name.append(m->mangle());
m_name.append("12__ModuleInfoZ");
llvm::GlobalVariable* m_gvar = gIR->module->getGlobalVariable(m_name);
if (!m_gvar) m_gvar = new llvm::GlobalVariable(*gIR->module, moduleinfoTy, false, llvm::GlobalValue::ExternalLinkage, NULL, m_name);
importInits.push_back(m_gvar);
}
// has import array?
if (!importInits.empty())
{
importedModulesTy = llvm::ArrayType::get(getPtrToType(moduleinfoTy), importInits.size());
importedModules = LLConstantArray::get(importedModulesTy, importInits);
}
// localClasses[]
LLConstant* localClasses = 0;
llvm::ArrayType* localClassesTy = 0;
ClassDeclarations aclasses;
//printf("members->dim = %d\n", members->dim);
for (size_t i = 0; i < members->dim; i++)
{
Dsymbol *member;
member = static_cast<Dsymbol *>(members->data[i]);
//printf("\tmember '%s'\n", member->toChars());
member->addLocalClass(&aclasses);
}
// fill inits
std::vector<LLConstant*> classInits;
for (size_t i = 0; i < aclasses.dim; i++)
{
ClassDeclaration* cd = aclasses[i];
DtoResolveClass(cd);
if (cd->isInterfaceDeclaration())
{
IF_LOG Logger::println("skipping interface '%s' in moduleinfo", cd->toPrettyChars());
continue;
}
else if (cd->sizeok != SIZEOKdone)
{
IF_LOG Logger::println("skipping opaque class declaration '%s' in moduleinfo", cd->toPrettyChars());
continue;
}
IF_LOG Logger::println("class: %s", cd->toPrettyChars());
LLConstant *c = DtoBitCast(cd->ir.irAggr->getClassInfoSymbol(), classinfoTy);
classInits.push_back(c);
}
// has class array?
if (!classInits.empty())
{
localClassesTy = llvm::ArrayType::get(classinfoTy, classInits.size());
localClasses = LLConstantArray::get(localClassesTy, classInits);
}
// These must match the values in druntime/src/object_.d
#define MIstandalone 4
#define MItlsctor 8
#define MItlsdtor 0x10
#define MIctor 0x20
#define MIdtor 0x40
#define MIxgetMembers 0x80
//.........这里部分代码省略.........
示例12: error
Initializer *StructInitializer::semantic(Scope *sc, Type *t, NeedInterpret needInterpret)
{
//printf("StructInitializer::semantic(t = %s) %s\n", t->toChars(), toChars());
t = t->toBasetype();
if (t->ty == Tsarray && t->nextOf()->toBasetype()->ty == Tstruct)
t = t->nextOf()->toBasetype();
if (t->ty == Tstruct)
{
StructDeclaration *sd = ((TypeStruct *)t)->sym;
if (sd->ctor)
{
error(loc, "%s %s has constructors, cannot use { initializers }, use %s( initializers ) instead",
sd->kind(), sd->toChars(), sd->toChars());
return new ErrorInitializer();
}
sd->size(loc);
if (sd->sizeok != SIZEOKdone)
return new ErrorInitializer();
size_t nfields = sd->fields.dim - sd->isNested();
//expandTuples for non-identity arguments?
Expressions *elements = new Expressions();
elements->setDim(nfields);
for (size_t i = 0; i < elements->dim; i++)
(*elements)[i] = NULL;
// Run semantic for explicitly given initializers
// TODO: this part is slightly different from StructLiteralExp::semantic.
bool errors = false;
for (size_t fieldi = 0, i = 0; i < field.dim; i++)
{
if (Identifier *id = field[i])
{
Dsymbol *s = sd->search(loc, id);
if (!s)
{
s = sd->search_correct(id);
if (s)
error(loc, "'%s' is not a member of '%s', did you mean '%s %s'?",
id->toChars(), sd->toChars(), s->kind(), s->toChars());
else
error(loc, "'%s' is not a member of '%s'", id->toChars(), sd->toChars());
return new ErrorInitializer();
}
s = s->toAlias();
// Find out which field index it is
for (fieldi = 0; 1; fieldi++)
{
if (fieldi >= nfields)
{
error(loc, "%s.%s is not a per-instance initializable field",
sd->toChars(), s->toChars());
return new ErrorInitializer();
}
if (s == sd->fields[fieldi])
break;
}
}
else if (fieldi >= nfields)
{
error(loc, "too many initializers for %s", sd->toChars());
return new ErrorInitializer();
}
VarDeclaration *vd = sd->fields[fieldi];
if ((*elements)[fieldi])
{
error(loc, "duplicate initializer for field '%s'", vd->toChars());
errors = true;
continue;
}
for (size_t j = 0; j < nfields; j++)
{
VarDeclaration *v2 = sd->fields[j];
bool overlap = (vd->offset < v2->offset + v2->type->size() &&
v2->offset < vd->offset + vd->type->size());
if (overlap && (*elements)[j])
{
error(loc, "overlapping initialization for field %s and %s",
v2->toChars(), vd->toChars());
errors = true;
continue;
}
}
assert(sc);
Initializer *iz = value[i];
iz = iz->semantic(sc, vd->type->addMod(t->mod), needInterpret);
Expression *ex = iz->toExpression();
if (ex->op == TOKerror)
{
errors = true;
continue;
}
value[i] = iz;
(*elements)[fieldi] = ex;
++fieldi;
}
//.........这里部分代码省略.........
示例13: assert
void StructDeclaration::semantic(Scope *sc)
{
//printf("+StructDeclaration::semantic(this=%p, %s '%s', sizeok = %d)\n", this, parent->toChars(), toChars(), sizeok);
//static int count; if (++count == 20) halt();
if (semanticRun >= PASSsemanticdone)
return;
unsigned dprogress_save = Module::dprogress;
int errors = global.errors;
Scope *scx = NULL;
if (scope)
{
sc = scope;
scx = scope; // save so we don't make redundant copies
scope = NULL;
}
if (!parent)
{
assert(sc->parent && sc->func);
parent = sc->parent;
}
assert(parent && !isAnonymous());
type = type->semantic(loc, sc);
if (type->ty == Tstruct && ((TypeStruct *)type)->sym != this)
{
TemplateInstance *ti = ((TypeStruct *)type)->sym->isInstantiated();
if (ti && isError(ti))
((TypeStruct *)type)->sym = this;
}
// Ungag errors when not speculative
Ungag ungag = ungagSpeculative();
if (semanticRun == PASSinit)
{
protection = sc->protection;
alignment = sc->structalign;
storage_class |= sc->stc;
if (storage_class & STCdeprecated)
isdeprecated = true;
if (storage_class & STCabstract)
error("structs, unions cannot be abstract");
userAttribDecl = sc->userAttribDecl;
}
else if (symtab)
{
if (sizeok == SIZEOKdone || !scx)
{
semanticRun = PASSsemanticdone;
return;
}
}
semanticRun = PASSsemantic;
if (!members) // if opaque declaration
{
semanticRun = PASSsemanticdone;
return;
}
if (!symtab)
symtab = new DsymbolTable();
if (sizeok == SIZEOKnone) // if not already done the addMember step
{
for (size_t i = 0; i < members->dim; i++)
{
Dsymbol *s = (*members)[i];
//printf("adding member '%s' to '%s'\n", s->toChars(), this->toChars());
s->addMember(sc, this, 1);
}
}
sizeok = SIZEOKnone;
Scope *sc2 = sc->push(this);
sc2->stc &= STCsafe | STCtrusted | STCsystem;
sc2->parent = this;
if (isUnionDeclaration())
sc2->inunion = 1;
sc2->protection = Prot(PROTpublic);
sc2->explicitProtection = 0;
sc2->structalign = STRUCTALIGN_DEFAULT;
sc2->userAttribDecl = NULL;
/* Set scope so if there are forward references, we still might be able to
* resolve individual members like enums.
*/
for (size_t i = 0; i < members->dim; i++)
{
Dsymbol *s = (*members)[i];
//printf("struct: setScope %s %s\n", s->kind(), s->toChars());
s->setScope(sc2);
}
for (size_t i = 0; i < members->dim; i++)
//.........这里部分代码省略.........
示例14: resolveProperties
/*********************************
* Operator overloading for op=
*/
Expression *BinAssignExp::op_overload(Scope *sc)
{
//printf("BinAssignExp::op_overload() (%s)\n", toChars());
#if DMDV2
if (e1->op == TOKarray)
{
ArrayExp *ae = (ArrayExp *)e1;
ae->e1 = ae->e1->semantic(sc);
ae->e1 = resolveProperties(sc, ae->e1);
AggregateDeclaration *ad = isAggregate(ae->e1->type);
if (ad)
{
/* Rewrite a[args]+=e2 as:
* a.opIndexOpAssign!("+")(e2, args);
*/
Dsymbol *fd = search_function(ad, Id::opIndexOpAssign);
if (fd)
{
Expression *e0 = resolveOpDollar(sc, ae);
Expressions *a = (Expressions *)ae->arguments->copy();
a->insert(0, e2);
Objects *tiargs = opToArg(sc, op);
Expression *e = new DotTemplateInstanceExp(loc, ae->e1, fd->ident, tiargs);
e = new CallExp(loc, e, a);
e = combine(e0, e);
e = e->semantic(sc);
return e;
}
// Didn't find it. Forward to aliasthis
if (ad->aliasthis && ae->e1->type != att1)
{
/* Rewrite a[arguments] op= e2 as:
* a.aliasthis[arguments] op= e2
*/
Expression *e1 = ae->copy();
((ArrayExp *)e1)->e1 = new DotIdExp(loc, ae->e1, ad->aliasthis->ident);
BinExp *be = (BinExp *)copy();
if (!be->att1 && ae->e1->type->checkAliasThisRec())
be->att1 = ae->e1->type;
be->e1 = e1;
if (Expression *e = be->trySemantic(sc))
return e;
}
att1 = NULL;
}
}
else if (e1->op == TOKslice)
{
SliceExp *se = (SliceExp *)e1;
se->e1 = se->e1->semantic(sc);
se->e1 = resolveProperties(sc, se->e1);
AggregateDeclaration *ad = isAggregate(se->e1->type);
if (ad)
{
/* Rewrite a[lwr..upr]+=e2 as:
* a.opSliceOpAssign!("+")(e2, lwr, upr);
*/
Dsymbol *fd = search_function(ad, Id::opSliceOpAssign);
if (fd)
{
Expression *e0 = resolveOpDollar(sc, se);
Expressions *a = new Expressions();
a->push(e2);
assert(!se->lwr || se->upr);
if (se->lwr)
{
a->push(se->lwr);
a->push(se->upr);
}
Objects *tiargs = opToArg(sc, op);
Expression *e = new DotTemplateInstanceExp(loc, se->e1, fd->ident, tiargs);
e = new CallExp(loc, e, a);
e = combine(e0, e);
e = e->semantic(sc);
return e;
}
// Didn't find it. Forward to aliasthis
if (ad->aliasthis && se->e1->type != att1)
{
/* Rewrite a[lwr..upr] op= e2 as:
* a.aliasthis[lwr..upr] op= e2
*/
Expression *e1 = se->copy();
((SliceExp *)e1)->e1 = new DotIdExp(loc, se->e1, ad->aliasthis->ident);
BinExp *be = (BinExp *)copy();
if (!be->att1 && se->e1->type->checkAliasThisRec())
be->att1 = se->e1->type;
be->e1 = e1;
if (Expression *e = be->trySemantic(sc))
return e;
//.........这里部分代码省略.........
示例15: resolveProperties
//.........这里部分代码省略.........
e = e->semantic(sc);
if (e->op == TOKvar)
{
d = ((VarExp *)e)->var;
if (! d->isFuncDeclaration() && ! d->isVarDeclaration())
d = NULL;
}
if (!d)
error("first argument of GNU_asm must be a function or variable declaration");
e = (*args)[1];
e = e->semantic(sc);
e = resolveProperties(sc, e);
e = e->ctfeInterpret();
e = e->toString();
if (e && ((StringExp *)e)->sz == 1)
s = ((StringExp *)e);
else
error("second argument of GNU_asm must be a character string");
if (d && s)
d->c_ident = Lexer::idPool((char*) s->string);
}
goto Lnodecl;
}
#endif
#if DMDV2
else if (ident == Id::startaddress)
{
if (!args || args->dim != 1)
error("function name expected for start address");
else
{
Expression *e = (*args)[0];
e = e->semantic(sc);
e = resolveProperties(sc, e);
e = e->ctfeInterpret();
(*args)[0] = e;
Dsymbol *sa = getDsymbol(e);
if (!sa || !sa->isFuncDeclaration())
error("function name expected for start address, not '%s'", e->toChars());
}
goto Lnodecl;
}
#endif
#if TARGET_NET
else if (ident == Lexer::idPool("assembly"))
{
}
#endif // TARGET_NET
else if (global.params.ignoreUnsupportedPragmas)
{
if (global.params.verbose)
{
/* Print unrecognized pragmas
*/
printf("pragma %s", ident->toChars());
if (args)
{
for (size_t i = 0; i < args->dim; i++)
{
Expression *e = (*args)[i];
e = e->semantic(sc);
e = resolveProperties(sc, e);
e = e->ctfeInterpret();
if (i == 0)
printf(" (");
else
printf(",");
printf("%s", e->toChars());
}
if (args->dim)
printf(")");
}
printf("\n");
}
goto Lnodecl;
}
else
error("unrecognized pragma(%s)", ident->toChars());
Ldecl:
if (decl)
{
for (size_t i = 0; i < decl->dim; i++)
{
Dsymbol *s = (*decl)[i];
s->semantic(sc);
}
}
return;
Lnodecl:
if (decl)
{
error("pragma is missing closing ';'");
goto Ldecl; // do them anyway, to avoid segfaults.
}
}