本文整理汇总了C++中VarDeclaration::toChars方法的典型用法代码示例。如果您正苦于以下问题:C++ VarDeclaration::toChars方法的具体用法?C++ VarDeclaration::toChars怎么用?C++ VarDeclaration::toChars使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类VarDeclaration
的用法示例。
在下文中一共展示了VarDeclaration::toChars方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: if
dt_t *StructInitializer::toDt()
{
Dts dts;
dt_t *dt;
dt_t *d;
dt_t **pdtend;
unsigned offset;
//printf("StructInitializer::toDt('%s')\n", toChars());
dts.setDim(ad->fields.dim);
dts.zero();
for (size_t i = 0; i < vars.dim; i++)
{
VarDeclaration *v = vars[i];
Initializer *val = value[i];
//printf("vars[%d] = %s\n", i, v->toChars());
for (size_t j = 0; 1; j++)
{
assert(j < dts.dim);
//printf(" adfield[%d] = %s\n", j, (ad->fields[j])->toChars());
if (ad->fields[j] == v)
{
if (dts[j])
error(loc, "field %s of %s already initialized", v->toChars(), ad->toChars());
dts[j] = val->toDt();
break;
}
}
}
dt = NULL;
pdtend = &dt;
offset = 0;
for (size_t j = 0; j < dts.dim; j++)
{
VarDeclaration *v = ad->fields[j];
d = dts[j];
if (!d)
{ // An instance specific initializer was not provided.
// Look to see if there's a default initializer from the
// struct definition
if (v->init && v->init->isVoidInitializer())
;
else if (v->init)
{
d = v->init->toDt();
}
else if (v->offset >= offset)
{
unsigned k;
unsigned offset2 = v->offset + v->type->size();
// Make sure this field does not overlap any explicitly
// initialized field.
for (k = j + 1; 1; k++)
{
if (k == dts.dim) // didn't find any overlap
{
v->type->toDt(&d);
break;
}
VarDeclaration *v2 = ad->fields[k];
if (v2->offset < offset2 && dts[k])
break; // overlap
}
}
}
if (d)
{
if (v->offset < offset)
error(loc, "duplicate union initialization for %s", v->toChars());
else
{ size_t sz = dt_size(d);
size_t vsz = v->type->size();
size_t voffset = v->offset;
if (sz > vsz)
{ assert(v->type->ty == Tsarray && vsz == 0);
error(loc, "zero length array %s has non-zero length initializer", v->toChars());
}
unsigned dim = 1;
for (Type *vt = v->type->toBasetype();
vt->ty == Tsarray;
vt = vt->nextOf()->toBasetype())
{ TypeSArray *tsa = (TypeSArray *)vt;
dim *= tsa->dim->toInteger();
}
//printf("sz = %d, dim = %d, vsz = %d\n", sz, dim, vsz);
assert(sz == vsz || sz * dim <= vsz);
for (size_t i = 0; i < dim; i++)
{
if (offset < voffset)
pdtend = dtnzeros(pdtend, voffset - offset);
if (!d)
//.........这里部分代码省略.........
示例2: addFieldInitializers
void IrAggr::addFieldInitializers(
llvm::SmallVectorImpl<llvm::Constant*>& constants,
const VarInitMap& explicitInitializers,
AggregateDeclaration* decl,
unsigned& offset,
bool populateInterfacesWithVtbls
)
{
if (ClassDeclaration* cd = decl->isClassDeclaration())
{
if (cd->baseClass)
{
addFieldInitializers(constants, explicitInitializers,
cd->baseClass, offset, populateInterfacesWithVtbls);
}
}
// Build up vector with one-to-one mapping to field indices.
const size_t n = decl->fields.dim;
llvm::SmallVector<VarInitConst, 16> data(n);
// Fill in explicit initializers.
for (size_t i = 0; i < n; ++i)
{
VarDeclaration* vd = decl->fields[i];
VarInitMap::const_iterator expl = explicitInitializers.find(vd);
if (expl != explicitInitializers.end())
data[i] = *expl;
}
// Fill in implicit initializers
for (size_t i = 0; i < n; i++)
{
if (data[i].first) continue;
VarDeclaration* vd = decl->fields[i];
/* Skip void initializers for unions. DMD bug 3991:
union X
{
int a = void;
dchar b = 'a';
}
*/
if (decl->isUnionDeclaration() && vd->init && vd->init->isVoidInitializer())
continue;
unsigned vd_begin = vd->offset;
unsigned vd_end = vd_begin + vd->type->size();
/* Skip zero size fields like zero-length static arrays, LDC issue 812:
class B {
ubyte[0] test;
}
*/
if (vd_begin == vd_end)
continue;
// make sure it doesn't overlap any explicit initializers.
bool overlaps = false;
if (type->ty == Tstruct)
{
// Only structs and unions can have overlapping fields.
for (size_t j = 0; j < n; ++j)
{
if (i == j || !data[j].first)
continue;
VarDeclaration* it = decl->fields[j];
unsigned f_begin = it->offset;
unsigned f_end = f_begin + it->type->size();
if (vd_begin >= f_end || vd_end <= f_begin)
continue;
overlaps = true;
break;
}
}
// add if no overlap found
if (!overlaps)
{
IF_LOG Logger::println("Implicit initializer: %s @+%u", vd->toChars(), vd->offset);
LOG_SCOPE;
data[i].first = vd;
data[i].second = get_default_initializer(vd, NULL);
}
}
// Sort data array by offset.
// TODO: Figure out whether this is really necessary, fields should already
// be in offset order. Not having do do this would mean we could use a plain
// llvm::Constant* vector for initializers and avoid all the VarInitConst business.
std::sort(data.begin(), data.end(), struct_init_data_sort);
// build array of constants and make sure explicit zero padding is inserted when necessary.
for (size_t i = 0; i < n; i++)
{
VarDeclaration* vd = data[i].first;
//.........这里部分代码省略.........
示例3: semantic
void AliasDeclaration::semantic(Scope *sc)
{
//printf("AliasDeclaration::semantic() %s\n", toChars());
if (aliassym)
{
if (aliassym->isTemplateInstance())
aliassym->semantic(sc);
return;
}
this->inSemantic = 1;
#if DMDV1 // don't really know why this is here
if (storage_class & STCconst)
error("cannot be const");
#endif
storage_class |= sc->stc & STCdeprecated;
// Given:
// alias foo.bar.abc def;
// it is not knowable from the syntax whether this is an alias
// for a type or an alias for a symbol. It is up to the semantic()
// pass to distinguish.
// If it is a type, then type is set and getType() will return that
// type. If it is a symbol, then aliassym is set and type is NULL -
// toAlias() will return aliasssym.
Dsymbol *s;
Type *t;
Expression *e;
/* This section is needed because resolve() will:
* const x = 3;
* alias x y;
* try to alias y to 3.
*/
s = type->toDsymbol(sc);
if (s
#if DMDV2
` && ((s->getType() && type->equals(s->getType())) || s->isEnumMember())
#endif
)
goto L2; // it's a symbolic alias
#if DMDV2
type = type->addStorageClass(storage_class);
if (storage_class & (STCref | STCnothrow | STCpure | STCdisable))
{ // For 'ref' to be attached to function types, and picked
// up by Type::resolve(), it has to go into sc.
sc = sc->push();
sc->stc |= storage_class & (STCref | STCnothrow | STCpure | STCshared | STCdisable);
type->resolve(loc, sc, &e, &t, &s);
sc = sc->pop();
}
else
#endif
type->resolve(loc, sc, &e, &t, &s);
if (s)
{
goto L2;
}
else if (e)
{
// Try to convert Expression to Dsymbol
if (e->op == TOKvar)
{ s = ((VarExp *)e)->var;
goto L2;
}
else if (e->op == TOKfunction)
{ s = ((FuncExp *)e)->fd;
goto L2;
}
else
{ error("cannot alias an expression %s", e->toChars());
t = e->type;
}
}
else if (t)
{
type = t;
}
if (overnext)
ScopeDsymbol::multiplyDefined(0, this, overnext);
this->inSemantic = 0;
return;
L2:
//printf("alias is a symbol %s %s\n", s->kind(), s->toChars());
type = NULL;
VarDeclaration *v = s->isVarDeclaration();
if (0 && v && v->linkage == LINKdefault)
{
error("forward reference of %s", v->toChars());
s = NULL;
}
else
{
FuncDeclaration *f = s->toAlias()->isFuncDeclaration();
if (f)
{
//.........这里部分代码省略.........
示例4: fit
/***************************************
* Fit elements[] to the corresponding type of field[].
* Input:
* loc
* sc
* elements The explicit arguments that given to construct object.
* stype The constructed object type.
* Returns false if any errors occur.
* Otherwise, returns true and elements[] are rewritten for the output.
*/
bool StructDeclaration::fit(Loc loc, Scope *sc, Expressions *elements, Type *stype)
{
if (!elements)
return true;
size_t nfields = fields.dim - isNested();
size_t offset = 0;
for (size_t i = 0; i < elements->dim; i++)
{
Expression *e = (*elements)[i];
if (!e)
continue;
e = resolveProperties(sc, e);
if (i >= nfields)
{
if (i == fields.dim - 1 && isNested() && e->op == TOKnull)
{
// CTFE sometimes creates null as hidden pointer; we'll allow this.
continue;
}
::error(loc, "more initializers than fields (%d) of %s", nfields, toChars());
return false;
}
VarDeclaration *v = fields[i];
if (v->offset < offset)
{
::error(loc, "overlapping initialization for %s", v->toChars());
return false;
}
offset = (unsigned)(v->offset + v->type->size());
Type *t = v->type;
if (stype)
t = t->addMod(stype->mod);
Type *origType = t;
Type *tb = t->toBasetype();
/* Look for case of initializing a static array with a too-short
* string literal, such as:
* char[5] foo = "abc";
* Allow this by doing an explicit cast, which will lengthen the string
* literal.
*/
if (e->op == TOKstring && tb->ty == Tsarray)
{
StringExp *se = (StringExp *)e;
Type *typeb = se->type->toBasetype();
TY tynto = tb->nextOf()->ty;
if (!se->committed &&
(typeb->ty == Tarray || typeb->ty == Tsarray) &&
(tynto == Tchar || tynto == Twchar || tynto == Tdchar) &&
se->length((int)tb->nextOf()->size()) < ((TypeSArray *)tb)->dim->toInteger())
{
e = se->castTo(sc, t);
goto L1;
}
}
while (!e->implicitConvTo(t) && tb->ty == Tsarray)
{
/* Static array initialization, as in:
* T[3][5] = e;
*/
t = tb->nextOf();
tb = t->toBasetype();
}
if (!e->implicitConvTo(t))
t = origType; // restore type for better diagnostic
e = e->implicitCastTo(sc, t);
L1:
if (e->op == TOKerror)
return false;
(*elements)[i] = e->isLvalue() ? callCpCtor(sc, e) : valueNoDtor(e);
}
return true;
}
示例5: DtoCreateNestedContext
void DtoCreateNestedContext(FuncDeclaration* fd) {
Logger::println("DtoCreateNestedContext for %s", fd->toChars());
LOG_SCOPE
DtoCreateNestedContextType(fd);
if (nestedCtx == NCArray) {
// construct nested variables array
if (!fd->nestedVars.empty())
{
Logger::println("has nested frame");
// start with adding all enclosing parent frames until a static parent is reached
int nparelems = 0;
if (!fd->isStatic())
{
Dsymbol* par = fd->toParent2();
while (par)
{
if (FuncDeclaration* parfd = par->isFuncDeclaration())
{
nparelems += parfd->nestedVars.size();
// stop at first static
if (parfd->isStatic())
break;
}
else if (par->isClassDeclaration())
{
// nothing needed
}
else
{
break;
}
par = par->toParent2();
}
}
int nelems = fd->nestedVars.size() + nparelems;
// make array type for nested vars
LLType* nestedVarsTy = LLArrayType::get(getVoidPtrType(), nelems);
// alloca it
// FIXME align ?
LLValue* nestedVars = DtoRawAlloca(nestedVarsTy, 0, ".nested_vars");
IrFunction* irfunction = fd->ir.irFunc;
// copy parent frame into beginning
if (nparelems)
{
LLValue* src = irfunction->nestArg;
if (!src)
{
assert(irfunction->thisArg);
assert(fd->isMember2());
LLValue* thisval = DtoLoad(irfunction->thisArg);
ClassDeclaration* cd = fd->isMember2()->isClassDeclaration();
assert(cd);
assert(cd->vthis);
src = DtoLoad(DtoGEPi(thisval, 0,cd->vthis->ir.irField->index, ".vthis"));
} else {
src = DtoLoad(src);
}
DtoMemCpy(nestedVars, src, DtoConstSize_t(nparelems*PTRSIZE),
getABITypeAlign(getVoidPtrType()));
}
// store in IrFunction
irfunction->nestedVar = nestedVars;
// go through all nested vars and assign indices
int idx = nparelems;
for (std::set<VarDeclaration*>::iterator i=fd->nestedVars.begin(); i!=fd->nestedVars.end(); ++i)
{
VarDeclaration* vd = *i;
if (!vd->ir.irLocal)
vd->ir.irLocal = new IrLocal(vd);
if (vd->isParameter())
{
Logger::println("nested param: %s", vd->toChars());
LLValue* gep = DtoGEPi(nestedVars, 0, idx);
LLValue* val = DtoBitCast(vd->ir.irLocal->value, getVoidPtrType());
DtoAlignedStore(val, gep);
}
else
{
Logger::println("nested var: %s", vd->toChars());
}
vd->ir.irLocal->nestedIndex = idx++;
}
}
}
else if (nestedCtx == NCHybrid) {
// construct nested variables array
if (!fd->nestedVars.empty())
{
IrFunction* irfunction = fd->ir.irFunc;
//.........这里部分代码省略.........
示例6: semantic
void ClassDeclaration::semantic(Scope *sc)
{
//printf("ClassDeclaration::semantic(%s), type = %p, sizeok = %d, this = %p\n", toChars(), type, sizeok, this);
//printf("\tparent = %p, '%s'\n", sc->parent, sc->parent ? sc->parent->toChars() : "");
//printf("sc->stc = %x\n", sc->stc);
//{ static int n; if (++n == 20) *(char*)0=0; }
if (!ident) // if anonymous class
{ const char *id = "__anonclass";
ident = Identifier::generateId(id);
}
if (!sc)
sc = scope;
if (!parent && sc->parent && !sc->parent->isModule())
parent = sc->parent;
type = type->semantic(loc, sc);
handle = type;
if (!members) // if opaque declaration
{ //printf("\tclass '%s' is forward referenced\n", toChars());
return;
}
if (symtab)
{ if (sizeok == SIZEOKdone || !scope)
{ //printf("\tsemantic for '%s' is already completed\n", toChars());
return; // semantic() already completed
}
}
else
symtab = new DsymbolTable();
Scope *scx = NULL;
if (scope)
{ sc = scope;
scx = scope; // save so we don't make redundant copies
scope = NULL;
}
unsigned dprogress_save = Module::dprogress;
int errors = global.errors;
if (sc->stc & STCdeprecated)
{
isdeprecated = true;
}
userAttributes = sc->userAttributes;
if (sc->linkage == LINKcpp)
error("cannot create C++ classes");
// Expand any tuples in baseclasses[]
for (size_t i = 0; i < baseclasses->dim; )
{
BaseClass *b = (*baseclasses)[i];
unsigned oldgag = global.gag;
if (global.isSpeculativeGagging() && !isSpeculative())
global.gag = 0;
b->type = b->type->semantic(loc, sc);
global.gag = oldgag;
Type *tb = b->type->toBasetype();
if (tb->ty == Ttuple)
{ TypeTuple *tup = (TypeTuple *)tb;
PROT protection = b->protection;
baseclasses->remove(i);
size_t dim = Parameter::dim(tup->arguments);
for (size_t j = 0; j < dim; j++)
{ Parameter *arg = Parameter::getNth(tup->arguments, j);
b = new BaseClass(arg->type, protection);
baseclasses->insert(i + j, b);
}
}
else
i++;
}
// See if there's a base class as first in baseclasses[]
if (baseclasses->dim)
{ TypeClass *tc;
BaseClass *b;
Type *tb;
b = (*baseclasses)[0];
//b->type = b->type->semantic(loc, sc);
tb = b->type->toBasetype();
if (tb->ty != Tclass)
{ if (b->type != Type::terror)
error("base type must be class or interface, not %s", b->type->toChars());
baseclasses->remove(0);
}
else
{
tc = (TypeClass *)(tb);
if (tc->sym->isDeprecated())
//.........这里部分代码省略.........
示例7: ErrorExp
Expression *StructInitializer::fill(Scope *sc, Type *t, NeedInterpret needInterpret)
{
//printf("StructInitializer::fill(sc = %p, '%s')\n", sc, toChars());
assert(t->ty == Tstruct);
StructDeclaration *sd = ((TypeStruct *)t)->sym;
sd->size(loc);
if (sd->sizeok != SIZEOKdone)
return new ErrorExp();
size_t nfields = sd->fields.dim - sd->isNested();
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
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, 0);
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 ErrorExp();
}
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 ErrorExp();
}
if (s == sd->fields[fieldi])
break;
}
}
else if (fieldi >= nfields)
{
error(loc, "too many initializers for %s", sd->toChars());
return new ErrorExp();
}
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;
}
if (errors)
return new ErrorExp();
// Fill in missing any elements with default initializers
for (size_t i = 0; i < elements->dim; i++)
{
if ((*elements)[i])
continue;
VarDeclaration *vd = sd->fields[i];
VarDeclaration *vx = vd;
if (vd->init && vd->init->isVoidInitializer())
vx = NULL;
// Find overlapped fields with the hole [vd->offset .. vd->offset->size()].
//.........这里部分代码省略.........
示例8: addBaseClassInits
void IrStruct::addBaseClassInits(
std::vector<llvm::Constant*>& constants,
ClassDeclaration* base,
size_t& offset,
size_t& field_index)
{
if (base->baseClass)
{
addBaseClassInits(constants, base->baseClass, offset, field_index);
}
IrTypeClass* tc = stripModifiers(base->type)->irtype->isClass();
assert(tc);
// go through fields
IrTypeAggr::iterator it;
for (it = tc->def_begin(); it != tc->def_end(); ++it)
{
VarDeclaration* vd = *it;
IF_LOG Logger::println("Adding default field %s %s (+%u)", vd->type->toChars(), vd->toChars(), vd->offset);
LOG_SCOPE;
assert(vd->offset >= offset && "default fields not sorted by offset");
// get next aligned offset for this type
size_t alignedoffset = realignOffset(offset, vd->type);
// insert explicit padding?
if (alignedoffset < vd->offset)
{
add_zeros(constants, vd->offset - alignedoffset);
}
// add default type
constants.push_back(get_default_initializer(vd, vd->init));
// advance offset to right past this field
offset = vd->offset + vd->type->size();
}
// has interface vtbls?
if (base->vtblInterfaces && base->vtblInterfaces->dim > 0)
{
// false when it's not okay to use functions from super classes
bool newinsts = (base == aggrdecl->isClassDeclaration());
size_t inter_idx = interfacesWithVtbls.size();
offset = (offset + PTRSIZE - 1) & ~(PTRSIZE - 1);
ArrayIter<BaseClass> it2(*base->vtblInterfaces);
for (; !it2.done(); it2.next())
{
BaseClass* b = it2.get();
constants.push_back(getInterfaceVtbl(b, newinsts, inter_idx));
offset += PTRSIZE;
// add to the interface list
interfacesWithVtbls.push_back(b);
inter_idx++;
}
}
}
示例9: fill
/***************************************
* Fill out remainder of elements[] with default initializers for fields[].
* Input:
* loc
* elements explicit arguments which given to construct object.
* ctorinit true if the elements will be used for default initialization.
* Returns false if any errors occur.
* Otherwise, returns true and the missing arguments will be pushed in elements[].
*/
bool StructDeclaration::fill(Loc loc, Expressions *elements, bool ctorinit)
{
assert(sizeok == SIZEOKdone);
size_t nfields = fields.dim - isNested();
if (elements)
{
size_t dim = elements->dim;
elements->setDim(nfields);
for (size_t i = dim; i < nfields; i++)
(*elements)[i] = NULL;
}
// Fill in missing any elements with default initializers
for (size_t i = 0; i < nfields; i++)
{
if (elements && (*elements)[i])
continue;
VarDeclaration *vd = fields[i];
VarDeclaration *vx = vd;
if (vd->init && vd->init->isVoidInitializer())
vx = NULL;
// Find overlapped fields with the hole [vd->offset .. vd->offset->size()].
size_t fieldi = i;
for (size_t j = 0; j < nfields; j++)
{
if (i == j)
continue;
VarDeclaration *v2 = fields[j];
bool overlap = (vd->offset < v2->offset + v2->type->size() &&
v2->offset < vd->offset + vd->type->size());
if (!overlap)
continue;
if (elements)
{
if ((*elements)[j])
{
vx = NULL;
break;
}
}
else
{
vd->overlapped = true;
}
if (v2->init && v2->init->isVoidInitializer())
continue;
if (elements)
{
/* Prefer first found non-void-initialized field
* union U { int a; int b = 2; }
* U u; // Error: overlapping initialization for field a and b
*/
if (!vx)
vx = v2, fieldi = j;
else if (v2->init)
{
::error(loc, "overlapping initialization for field %s and %s",
v2->toChars(), vd->toChars());
}
}
else
{
// Will fix Bugzilla 1432 by enabling this path always
/* Prefer explicitly initialized field
* union U { int a; int b = 2; }
* U u; // OK (u.b == 2)
*/
if (!vx || !vx->init && v2->init)
vx = v2, fieldi = j;
else if (vx != vd &&
!(vx->offset < v2->offset + v2->type->size() &&
v2->offset < vx->offset + vx->type->size()))
{
// Both vx and v2 fills vd, but vx and v2 does not overlap
}
else if (vx->init && v2->init)
{
::error(loc, "overlapping default initialization for field %s and %s",
v2->toChars(), vd->toChars());
}
else
assert(vx->init || !vx->init && !v2->init);
}
}
if (elements && vx)
{
Expression *e;
//.........这里部分代码省略.........
示例10: addAggregate
void AggrTypeBuilder::addAggregate(AggregateDeclaration *ad)
{
// mirror the ad->fields array but only fill in contributors
const size_t n = ad->fields.dim;
LLSmallVector<VarDeclaration*, 16> data(n, NULL);
unsigned int errors = global.errors;
// first fill in the fields with explicit initializers
for (size_t index = 0; index < n; ++index)
{
VarDeclaration *field = ad->fields[index];
// init is !null for explicit inits
if (field->init != NULL && !field->init->isVoidInitializer())
{
IF_LOG Logger::println("adding explicit initializer for struct field %s",
field->toChars());
size_t f_size = field->type->size();
size_t f_begin = field->offset;
size_t f_end = f_begin + f_size;
if (f_size == 0)
continue;
data[index] = field;
// make sure there is no overlap
for (size_t i = 0; i < index; i++)
{
if (data[i] != NULL)
{
VarDeclaration* vd = data[i];
size_t v_begin = vd->offset;
size_t v_end = v_begin + vd->type->size();
if (v_begin >= f_end || v_end <= f_begin)
continue;
ad->error(vd->loc, "has overlapping initialization for %s and %s",
field->toChars(), vd->toChars());
}
}
}
}
if (errors != global.errors)
{
// There was an overlapping initialization.
// Return if errors are gagged otherwise abort.
if (global.gag) return;
fatal();
}
// fill in default initializers
for (size_t index = 0; index < n; ++index)
{
if (data[index])
continue;
VarDeclaration *field = ad->fields[index];
size_t f_size = field->type->size();
size_t f_begin = field->offset;
size_t f_end = f_begin + f_size;
if (f_size == 0)
continue;
// make sure it doesn't overlap anything explicit
bool overlaps = false;
for (size_t i = 0; i < n; i++)
{
if (data[i])
{
size_t v_begin = data[i]->offset;
size_t v_end = v_begin + data[i]->type->size();
if (v_begin >= f_end || v_end <= f_begin)
continue;
overlaps = true;
break;
}
}
// if no overlap was found, add the default initializer
if (!overlaps)
{
IF_LOG Logger::println("adding default initializer for struct field %s",
field->toChars());
data[index] = field;
}
}
//
// ok. now we can build a list of llvm types. and make sure zeros are inserted if necessary.
//
// first we sort the list by offset
std::sort(data.begin(), data.end(), var_offset_sort_cb);
//.........这里部分代码省略.........
示例11: fill
/***************************************
* Fill out remainder of elements[] with default initializers for fields[].
* Input:
* loc
* elements explicit arguments which given to construct object.
* ctorinit true if the elements will be used for default initialization.
* Returns false if any errors occur.
* Otherwise, returns true and the missing arguments will be pushed in elements[].
*/
bool StructDeclaration::fill(Loc loc, Expressions *elements, bool ctorinit)
{
//printf("StructDeclaration::fill() %s\n", toChars());
assert(sizeok == SIZEOKdone);
size_t nfields = fields.dim - isNested();
bool errors = false;
if (elements)
{
size_t dim = elements->dim;
elements->setDim(nfields);
for (size_t i = dim; i < nfields; i++)
(*elements)[i] = NULL;
}
// Fill in missing any elements with default initializers
for (size_t i = 0; i < nfields; i++)
{
if (elements && (*elements)[i])
continue;
VarDeclaration *vd = fields[i];
VarDeclaration *vx = vd;
if (vd->init && vd->init->isVoidInitializer())
vx = NULL;
// Find overlapped fields with the hole [vd->offset .. vd->offset->size()].
size_t fieldi = i;
for (size_t j = 0; j < nfields; j++)
{
if (i == j)
continue;
VarDeclaration *v2 = fields[j];
bool overlap = (vd->offset < v2->offset + v2->type->size() &&
v2->offset < vd->offset + vd->type->size());
if (!overlap)
continue;
// vd and v2 are overlapping. If either has destructors, postblits, etc., then error
//printf("overlapping fields %s and %s\n", vd->toChars(), v2->toChars());
VarDeclaration *v = vd;
for (int k = 0; k < 2; ++k, v = v2)
{
Type *tv = v->type->baseElemOf();
Dsymbol *sv = tv->toDsymbol(NULL);
if (sv && !errors)
{
StructDeclaration *sd = sv->isStructDeclaration();
if (sd && (sd->dtor || sd->inv || sd->postblit))
{
error("destructors, postblits and invariants are not allowed in overlapping fields %s and %s", vd->toChars(), v2->toChars());
errors = true;
break;
}
}
}
if (elements)
{
if ((*elements)[j])
{
vx = NULL;
break;
}
}
else
{
vd->overlapped = true;
}
if (v2->init && v2->init->isVoidInitializer())
continue;
if (elements)
{
/* Prefer first found non-void-initialized field
* union U { int a; int b = 2; }
* U u; // Error: overlapping initialization for field a and b
*/
if (!vx)
vx = v2, fieldi = j;
else if (v2->init)
{
::error(loc, "overlapping initialization for field %s and %s",
v2->toChars(), vd->toChars());
}
}
else
{
// Will fix Bugzilla 1432 by enabling this path always
/* Prefer explicitly initialized field
* union U { int a; int b = 2; }
//.........这里部分代码省略.........
示例12: toDt
void StructDeclaration::toDt(dt_t **pdt)
{
if (zeroInit)
{
dtnzeros(pdt, structsize);
return;
}
unsigned offset;
dt_t *dt;
dt_t *sdt = NULL;
//printf("StructDeclaration::toDt(), this='%s'\n", toChars());
offset = 0;
// Note equivalence of this loop to class's
for (size_t i = 0; i < fields.dim; i++)
{
VarDeclaration *v = fields[i];
//printf("\tfield '%s' voffset %d, offset = %d\n", v->toChars(), v->offset, offset);
dt = NULL;
int sz;
if (v->storage_class & STCref)
{
sz = PTRSIZE;
if (v->offset >= offset)
dtnzeros(&dt, sz);
}
else
{
sz = v->type->size();
Initializer *init = v->init;
if (init)
{ //printf("\t\thas initializer %s\n", init->toChars());
ExpInitializer *ei = init->isExpInitializer();
Type *tb = v->type->toBasetype();
if (init->isVoidInitializer())
;
else if (ei && tb->ty == Tsarray)
((TypeSArray *)tb)->toDtElem(&dt, ei->exp);
else
dt = init->toDt();
}
else if (v->offset >= offset)
v->type->toDt(&dt);
}
if (dt)
{
if (v->offset < offset)
error("overlapping initialization for struct %s.%s", toChars(), v->toChars());
else
{
if (offset < v->offset)
dtnzeros(&sdt, v->offset - offset);
dtcat(&sdt, dt);
offset = v->offset + sz;
}
}
}
if (offset < structsize)
dtnzeros(&sdt, structsize - offset);
#ifdef IN_GCC
dtcontainer(pdt, type, sdt);
#else
dtcat(pdt, sdt);
#endif
dt_optimize(*pdt);
}
示例13: DtoCreateNestedContextType
static void DtoCreateNestedContextType(FuncDeclaration* fd) {
Logger::println("DtoCreateNestedContextType for %s", fd->toChars());
LOG_SCOPE
DtoDeclareFunction(fd);
if (fd->ir.irFunc->nestedContextCreated)
return;
fd->ir.irFunc->nestedContextCreated = true;
if (fd->nestedVars.empty()) {
// fill nestedVars
size_t nnest = fd->closureVars.dim;
for (size_t i = 0; i < nnest; ++i)
{
VarDeclaration* vd = static_cast<VarDeclaration*>(fd->closureVars.data[i]);
fd->nestedVars.insert(vd);
}
}
// construct nested variables array
if (!fd->nestedVars.empty())
{
Logger::println("has nested frame");
// start with adding all enclosing parent frames until a static parent is reached
LLStructType* innerFrameType = NULL;
unsigned depth = -1;
if (!fd->isStatic()) {
if (FuncDeclaration* parfd = getParentFunc(fd, true)) {
// Make sure the parent has already been analyzed.
DtoCreateNestedContextType(parfd);
innerFrameType = parfd->ir.irFunc->frameType;
if (innerFrameType)
depth = parfd->ir.irFunc->depth;
}
}
fd->ir.irFunc->depth = ++depth;
Logger::cout() << "Function " << fd->toChars() << " has depth " << depth << '\n';
typedef std::vector<LLType*> TypeVec;
TypeVec types;
if (depth != 0) {
assert(innerFrameType);
// Add frame pointer types for all but last frame
if (depth > 1) {
for (unsigned i = 0; i < (depth - 1); ++i) {
types.push_back(innerFrameType->getElementType(i));
}
}
// Add frame pointer type for last frame
types.push_back(LLPointerType::getUnqual(innerFrameType));
}
if (Logger::enabled() && depth != 0) {
Logger::println("Frame types: ");
LOG_SCOPE;
for (TypeVec::iterator i = types.begin(); i != types.end(); ++i)
Logger::cout() << **i << '\n';
}
// Add the direct nested variables of this function, and update their indices to match.
// TODO: optimize ordering for minimal space usage?
for (std::set<VarDeclaration*>::iterator i=fd->nestedVars.begin(); i!=fd->nestedVars.end(); ++i)
{
VarDeclaration* vd = *i;
if (!vd->ir.irLocal)
vd->ir.irLocal = new IrLocal(vd);
vd->ir.irLocal->nestedIndex = types.size();
vd->ir.irLocal->nestedDepth = depth;
if (vd->isParameter()) {
// Parameters will have storage associated with them (to handle byref etc.),
// so handle those cases specially by storing a pointer instead of a value.
const IrParameter* irparam = vd->ir.irParam;
const bool refout = vd->storage_class & (STCref | STCout);
const bool lazy = vd->storage_class & STClazy;
const bool byref = irparam->arg->byref;
const bool isVthisPtr = irparam->isVthis && !byref;
if (!(refout || (byref && !lazy)) || isVthisPtr) {
// This will be copied to the nesting frame.
if (lazy)
types.push_back(irparam->value->getType()->getContainedType(0));
else
types.push_back(DtoType(vd->type));
} else {
types.push_back(irparam->value->getType());
}
} else if (isSpecialRefVar(vd)) {
types.push_back(DtoType(vd->type->pointerTo()));
} else {
types.push_back(DtoType(vd->type));
}
if (Logger::enabled()) {
Logger::cout() << "Nested var '" << vd->toChars() <<
"' of type " << *types.back() << "\n";
}
}
//.........这里部分代码省略.........
示例14: toObjFile
//.........这里部分代码省略.........
}
if (vthis)
{
assert(!vthis->csym);
sthis = vthis->toSymbol();
irs.sthis = sthis;
if (!(f->Fflags3 & Fnested))
f->Fflags3 |= Fmember;
}
Symbol **params;
// Estimate number of parameters, pi
size_t pi = (v_arguments != NULL);
if (parameters)
pi += parameters->dim;
// Allow extra 2 for sthis and shidden
params = (Symbol **)alloca((pi + 2) * sizeof(Symbol *));
// Get the actual number of parameters, pi, and fill in the params[]
pi = 0;
if (v_arguments)
{
params[pi] = v_arguments->toSymbol();
pi += 1;
}
if (parameters)
{
for (size_t i = 0; i < parameters->dim; i++)
{ VarDeclaration *v = (*parameters)[i];
if (v->csym)
{
error("compiler error, parameter '%s', bugzilla 2962?", v->toChars());
assert(0);
}
params[pi + i] = v->toSymbol();
}
pi += parameters->dim;
}
if (reverse)
{ // Reverse params[] entries
for (size_t i = 0; i < pi/2; i++)
{
Symbol *sptmp = params[i];
params[i] = params[pi - 1 - i];
params[pi - 1 - i] = sptmp;
}
}
if (shidden)
{
#if 0
// shidden becomes last parameter
params[pi] = shidden;
#else
// shidden becomes first parameter
memmove(params + 1, params, pi * sizeof(params[0]));
params[0] = shidden;
#endif
pi++;
}
if (sthis)
示例15: DtoCreateNestedContext
void DtoCreateNestedContext(FuncDeclaration* fd) {
Logger::println("DtoCreateNestedContext for %s", fd->toChars());
LOG_SCOPE
DtoCreateNestedContextType(fd);
// construct nested variables array
if (!fd->nestedVars.empty())
{
IrFunction* irfunction = fd->ir.irFunc;
unsigned depth = irfunction->depth;
LLStructType *frameType = irfunction->frameType;
// Create frame for current function and append to frames list
// FIXME: alignment ?
LLValue* frame = 0;
if (fd->needsClosure())
frame = DtoGcMalloc(frameType, ".frame");
else
frame = DtoRawAlloca(frameType, 0, ".frame");
// copy parent frames into beginning
if (depth != 0) {
LLValue* src = irfunction->nestArg;
if (!src) {
assert(irfunction->thisArg);
assert(fd->isMember2());
LLValue* thisval = DtoLoad(irfunction->thisArg);
AggregateDeclaration* cd = fd->isMember2();
assert(cd);
assert(cd->vthis);
Logger::println("Indexing to 'this'");
if (cd->isStructDeclaration())
src = DtoExtractValue(thisval, cd->vthis->ir.irField->index, ".vthis");
else
src = DtoLoad(DtoGEPi(thisval, 0, cd->vthis->ir.irField->index, ".vthis"));
} else {
src = DtoLoad(src);
}
if (depth > 1) {
src = DtoBitCast(src, getVoidPtrType());
LLValue* dst = DtoBitCast(frame, getVoidPtrType());
DtoMemCpy(dst, src, DtoConstSize_t((depth-1) * PTRSIZE),
getABITypeAlign(getVoidPtrType()));
}
// Copy nestArg into framelist; the outer frame is not in the list of pointers
src = DtoBitCast(src, frameType->getContainedType(depth-1));
LLValue* gep = DtoGEPi(frame, 0, depth-1);
DtoAlignedStore(src, gep);
}
// store context in IrFunction
irfunction->nestedVar = frame;
// go through all nested vars and assign addresses where possible.
for (std::set<VarDeclaration*>::iterator i=fd->nestedVars.begin(); i!=fd->nestedVars.end(); ++i)
{
VarDeclaration* vd = *i;
LLValue* gep = DtoGEPi(frame, 0, vd->ir.irLocal->nestedIndex, vd->toChars());
if (vd->isParameter()) {
Logger::println("nested param: %s", vd->toChars());
LOG_SCOPE
IrParameter* parm = vd->ir.irParam;
if (parm->arg->byref)
{
storeVariable(vd, gep);
}
else
{
Logger::println("Copying to nested frame");
// The parameter value is an alloca'd stack slot.
// Copy to the nesting frame and leave the alloca for
// the optimizers to clean up.
DtoStore(DtoLoad(parm->value), gep);
gep->takeName(parm->value);
parm->value = gep;
}
} else {
Logger::println("nested var: %s", vd->toChars());
assert(!vd->ir.irLocal->value);
vd->ir.irLocal->value = gep;
}
if (global.params.symdebug) {
LLSmallVector<LLValue*, 2> addr;
dwarfOpOffset(addr, frameType, vd->ir.irLocal->nestedIndex);
DtoDwarfLocalVariable(frame, vd, addr);
}
}
}
}