本文整理汇总了C++中AggregateDeclaration类的典型用法代码示例。如果您正苦于以下问题:C++ AggregateDeclaration类的具体用法?C++ AggregateDeclaration怎么用?C++ AggregateDeclaration使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了AggregateDeclaration类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: assert
void AnonDeclaration::semantic(Scope *sc)
{
//printf("\tAnonDeclaration::semantic %s %p\n", isunion ? "union" : "struct", this);
assert(sc->parent);
Dsymbol *parent = sc->parent->pastMixin();
AggregateDeclaration *ad = parent->isAggregateDeclaration();
if (!ad || (!ad->isStructDeclaration() && !ad->isClassDeclaration()))
{
error("can only be a part of an aggregate");
return;
}
alignment = sc->structalign;
if (decl)
{
sc = sc->push();
sc->stc &= ~(STCauto | STCscope | STCstatic | STCtls | STCgshared);
sc->inunion = isunion;
sc->offset = 0;
sc->flags = 0;
for (size_t i = 0; i < decl->dim; i++)
{
Dsymbol *s = (*decl)[i];
s->semantic(sc);
}
sc = sc->pop();
}
}
示例2: semantic
void AliasThis::semantic(Scope *sc)
{
Dsymbol *parent = sc->parent;
if (parent)
parent = parent->pastMixin();
AggregateDeclaration *ad = NULL;
if (parent)
ad = parent->isAggregateDeclaration();
if (ad)
{
assert(ad->members);
Dsymbol *s = ad->search(loc, ident, 0);
if (!s)
{ s = sc->search(loc, ident, 0);
if (s)
::error(loc, "%s is not a member of %s", s->toChars(), ad->toChars());
else
::error(loc, "undefined identifier %s", ident->toChars());
}
else if (ad->aliasthis && s != ad->aliasthis)
error("there can be only one alias this");
ad->aliasthis = s;
}
else
error("alias this can only appear in struct or class declaration, not %s", parent ? parent->toChars() : "nowhere");
}
示例3: assert
void AliasThis::semantic(Scope *sc)
{
Dsymbol *p = sc->parent->pastMixin();
AggregateDeclaration *ad = p->isAggregateDeclaration();
if (!ad)
{
::error(loc, "alias this can only be a member of aggregate, not %s %s",
p->kind(), p->toChars());
return;
}
assert(ad->members);
Dsymbol *s = ad->search(loc, ident);
if (!s)
{
s = sc->search(loc, ident, NULL);
if (s)
::error(loc, "%s is not a member of %s", s->toChars(), ad->toChars());
else
::error(loc, "undefined identifier %s", ident->toChars());
return;
}
else if (ad->aliasthis && s != ad->aliasthis)
{
::error(loc, "there can be only one alias this");
return;
}
if (ad->type->ty == Tstruct && ((TypeStruct *)ad->type)->sym != ad)
{
AggregateDeclaration *ad2 = ((TypeStruct *)ad->type)->sym;
assert(ad2->type == Type::terror);
ad->aliasthis = ad2->aliasthis;
return;
}
/* disable the alias this conversion so the implicit conversion check
* doesn't use it.
*/
ad->aliasthis = NULL;
Dsymbol *sx = s;
if (sx->isAliasDeclaration())
sx = sx->toAlias();
Declaration *d = sx->isDeclaration();
if (d && !d->isTupleDeclaration())
{
Type *t = d->type;
assert(t);
if (ad->type->implicitConvTo(t) > MATCHnomatch)
{
::error(loc, "alias this is not reachable as %s already converts to %s", ad->toChars(), t->toChars());
}
}
ad->aliasthis = s;
}
示例4: visit
void visit(NewExp *e)
{
//printf("NewExp::inlineCost3() %s\n", e->toChars());
AggregateDeclaration *ad = isAggregate(e->newtype);
if (ad && ad->isNested())
cost = COST_MAX;
else
cost++;
}
示例5: toParent2
void AggregateDeclaration::makeNested()
{
if (!enclosing && sizeok != SIZEOKdone && !isUnionDeclaration() && !isInterfaceDeclaration())
{
// If nested struct, add in hidden 'this' pointer to outer scope
if (!(storage_class & STCstatic))
{
Dsymbol *s = toParent2();
if (s)
{
AggregateDeclaration *ad = s->isAggregateDeclaration();
FuncDeclaration *fd = s->isFuncDeclaration();
if (fd)
{
enclosing = fd;
}
else if (isClassDeclaration() && ad && ad->isClassDeclaration())
{
enclosing = ad;
}
else if (isStructDeclaration() && ad)
{
if (TemplateInstance *ti = ad->parent->isTemplateInstance())
{
enclosing = ti->enclosing;
}
}
if (enclosing)
{
//printf("makeNested %s, enclosing = %s\n", toChars(), enclosing->toChars());
Type *t;
if (ad)
t = ad->handleType();
else if (fd)
{
AggregateDeclaration *ad2 = fd->isMember2();
if (ad2)
t = ad2->handleType();
else
t = Type::tvoidptr;
}
else
assert(0);
if (t->ty == Tstruct)
t = Type::tvoidptr; // t should not be a ref type
assert(!vthis);
vthis = new ThisDeclaration(loc, t);
//vthis->storage_class |= STCref;
members->push(vthis);
}
}
}
}
}
示例6: toParent2
void AggregateDeclaration::makeNested()
{
if (enclosing) // if already nested
return;
if (sizeok == SIZEOKdone)
return;
if (isUnionDeclaration() || isInterfaceDeclaration())
return;
if (storage_class & STCstatic)
return;
// If nested struct, add in hidden 'this' pointer to outer scope
Dsymbol *s = toParent2();
if (!s)
return;
AggregateDeclaration *ad = s->isAggregateDeclaration();
FuncDeclaration *fd = s->isFuncDeclaration();
Type *t = NULL;
if (fd)
{
enclosing = fd;
AggregateDeclaration *agg = fd->isMember2();
t = agg ? agg->handleType() : Type::tvoidptr;
}
else if (ad)
{
if (isClassDeclaration() && ad->isClassDeclaration())
{
enclosing = ad;
}
else if (isStructDeclaration())
{
if (TemplateInstance *ti = ad->parent->isTemplateInstance())
{
enclosing = ti->enclosing;
}
}
t = ad->handleType();
}
if (enclosing)
{
//printf("makeNested %s, enclosing = %s\n", toChars(), enclosing->toChars());
assert(t);
if (t->ty == Tstruct)
t = Type::tvoidptr; // t should not be a ref type
assert(!vthis);
vthis = new ThisDeclaration(loc, t);
//vthis->storage_class |= STCref;
members->push(vthis);
}
}
示例7: checkUnsafeAccess
bool checkUnsafeAccess(Scope *sc, Expression *e, bool readonly, bool printmsg)
{
if (e->op != TOKdotvar)
return false;
DotVarExp *dve = (DotVarExp *)e;
if (VarDeclaration *v = dve->var->isVarDeclaration())
{
if (sc->intypeof || !sc->func || !sc->func->isSafeBypassingInference())
return false;
AggregateDeclaration *ad = v->toParent2()->isAggregateDeclaration();
if (!ad)
return false;
if (v->overlapped && v->type->hasPointers() && sc->func->setUnsafe())
{
if (printmsg)
e->error("field %s.%s cannot access pointers in @safe code that overlap other fields",
ad->toChars(), v->toChars());
return true;
}
if (readonly || !e->type->isMutable())
return false;
if (v->type->hasPointers() && v->type->toBasetype()->ty != Tstruct)
{
if ((ad->type->alignment() < (unsigned)Target::ptrsize ||
(v->offset & (Target::ptrsize - 1))) &&
sc->func->setUnsafe())
{
if (printmsg)
e->error("field %s.%s cannot modify misaligned pointers in @safe code",
ad->toChars(), v->toChars());
return true;
}
}
if (v->overlapUnsafe && sc->func->setUnsafe())
{
if (printmsg)
e->error("field %s.%s cannot modify fields in @safe code that overlap fields with other storage classes",
ad->toChars(), v->toChars());
return true;
}
}
return false;
}
示例8: VarDeclaration
Dsymbol *ArrayScopeSymbol::search(Loc loc, Identifier *ident, int flags)
{
//printf("ArrayScopeSymbol::search('%s', flags = %d)\n", ident->toChars(), flags);
if (ident == Id::dollar)
{ VarDeclaration **pvar;
Expression *ce;
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(Loc(), td->objects->dim, Type::tsize_t);
v->init = new ExpInitializer(Loc(), 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(Loc(), type->arguments->dim, Type::tsize_t);
v->init = new ExpInitializer(Loc(), 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;
pvar = &ae->lengthVar;
ce = ae->e1;
}
else
/* Didn't find $, look in enclosing scope(s).
*/
return NULL;
while (ce->op == TOKcomma)
ce = ((CommaExp *)ce)->e2;
/* If we are indexing into an array that is really a type
* tuple, rewrite this as an index into a type tuple and
* try again.
*/
if (ce->op == TOKtype)
{
Type *t = ((TypeExp *)ce)->type;
if (t->ty == Ttuple)
{ type = (TypeTuple *)t;
goto L1;
}
}
/* *pvar is lazily initialized, so if we refer to $
* multiple times, it gets set only once.
*/
if (!*pvar) // if not already initialized
{ /* Create variable v and set it to the value of $
*/
VarDeclaration *v;
Type *t;
if (ce->op == TOKtuple)
{ /* It is for an expression tuple, so the
* length will be a const.
*/
Expression *e = new IntegerExp(Loc(), ((TupleExp *)ce)->exps->dim, Type::tsize_t);
v = new VarDeclaration(loc, Type::tsize_t, Id::dollar, new ExpInitializer(Loc(), e));
v->storage_class |= STCstatic | STCconst;
}
else if (ce->type && (t = ce->type->toBasetype()) != NULL &&
(t->ty == Tstruct || t->ty == Tclass))
{ // Look for opDollar
assert(exp->op == TOKarray || exp->op == TOKslice);
AggregateDeclaration *ad = NULL;
if (t->ty == Tclass)
//.........这里部分代码省略.........
示例9: el_var
//.........这里部分代码省略.........
}
else
{
ethis = el_var(irs->sthis);
}
}
else
{
/* No 'this' pointer for current function,
*/
if (thisfd->hasNestedFrameRefs())
{
/* OPframeptr is an operator that gets the frame pointer
* for the current function, i.e. for the x86 it gets
* the value of EBP
*/
ethis = el_long(TYnptr, 0);
ethis->Eoper = OPframeptr;
}
else
{
/* Use NULL if no references to the current function's frame
*/
ethis = el_long(TYnptr, 0);
}
}
}
else
{
if (!irs->sthis) // if no frame pointer for this function
{
fd->error(loc, "is a nested function and cannot be accessed from %s", irs->getFunc()->toPrettyChars());
return el_long(TYnptr, 0); // error recovery
}
/* Go up a nesting level, i.e. we need to find the 'this'
* of an enclosing function.
* Our 'enclosing function' may also be an inner class.
*/
ethis = el_var(irs->sthis);
Dsymbol *s = thisfd;
while (fd != s)
{
FuncDeclaration *fdp = s->toParent2()->isFuncDeclaration();
//printf("\ts = '%s'\n", s->toChars());
thisfd = s->isFuncDeclaration();
if (thisfd)
{
/* Enclosing function is a function.
*/
// Error should have been caught by front end
assert(thisfd->isNested() || thisfd->vthis);
}
else
{
/* Enclosed by an aggregate. That means the current
* function must be a member function of that aggregate.
*/
AggregateDeclaration *ad = s->isAggregateDeclaration();
if (!ad)
{
Lnoframe:
irs->getFunc()->error(loc, "cannot get frame pointer to %s", fd->toPrettyChars());
return el_long(TYnptr, 0); // error recovery
}
ClassDeclaration *cd = ad->isClassDeclaration();
ClassDeclaration *cdx = fd->isClassDeclaration();
if (cd && cdx && cdx->isBaseOf(cd, NULL))
break;
StructDeclaration *sd = ad->isStructDeclaration();
if (fd == sd)
break;
if (!ad->isNested() || !ad->vthis)
goto Lnoframe;
ethis = el_bin(OPadd, TYnptr, ethis, el_long(TYsize_t, ad->vthis->offset));
ethis = el_una(OPind, TYnptr, ethis);
}
if (fdparent == s->toParent2())
break;
/* Remember that frames for functions that have no
* nested references are skipped in the linked list
* of frames.
*/
if (fdp && fdp->hasNestedFrameRefs())
ethis = el_una(OPind, TYnptr, ethis);
s = s->toParent2();
assert(s);
}
}
#if 0
printf("ethis:\n");
elem_print(ethis);
printf("\n");
#endif
return ethis;
}
示例10: DtoNestedVariable
DValue* DtoNestedVariable(Loc& loc, Type* astype, VarDeclaration* vd, bool byref)
{
IF_LOG Logger::println("DtoNestedVariable for %s @ %s", vd->toChars(), loc.toChars());
LOG_SCOPE;
////////////////////////////////////
// Locate context value
Dsymbol* vdparent = vd->toParent2();
assert(vdparent);
IrFunction* irfunc = gIR->func();
// Check whether we can access the needed frame
FuncDeclaration *fd = irfunc->decl;
while (fd != vdparent) {
if (fd->isStatic()) {
error(loc, "function %s cannot access frame of function %s", irfunc->decl->toPrettyChars(), vdparent->toPrettyChars());
return new DVarValue(astype, vd, llvm::UndefValue::get(getPtrToType(DtoType(astype))));
}
fd = getParentFunc(fd, false);
assert(fd);
}
// is the nested variable in this scope?
if (vdparent == irfunc->decl)
{
LLValue* val = vd->ir.getIrValue();
return new DVarValue(astype, vd, val);
}
LLValue *dwarfValue = 0;
std::vector<LLValue*> dwarfAddr;
// get the nested context
LLValue* ctx = 0;
if (irfunc->nestedVar) {
// If this function has its own nested context struct, always load it.
ctx = irfunc->nestedVar;
dwarfValue = ctx;
} else if (irfunc->decl->isMember2()) {
// If this is a member function of a nested class without its own
// context, load the vthis member.
AggregateDeclaration* cd = irfunc->decl->isMember2();
LLValue* val = irfunc->thisArg;
if (cd->isClassDeclaration())
val = DtoLoad(val);
ctx = DtoLoad(DtoGEPi(val, 0, cd->vthis->ir.irField->index, ".vthis"));
} else {
// Otherwise, this is a simple nested function, load from the context
// argument.
ctx = DtoLoad(irfunc->nestArg);
dwarfValue = irfunc->nestArg;
if (global.params.symdebug)
gIR->DBuilder.OpDeref(dwarfAddr);
}
assert(ctx);
DtoCreateNestedContextType(vdparent->isFuncDeclaration());
assert(vd->ir.irLocal);
////////////////////////////////////
// Extract variable from nested context
LLValue* val = DtoBitCast(ctx, LLPointerType::getUnqual(irfunc->frameType));
IF_LOG {
Logger::cout() << "Context: " << *val << '\n';
Logger::cout() << "of type: " << *irfunc->frameType << '\n';
}
unsigned vardepth = vd->ir.irLocal->nestedDepth;
unsigned funcdepth = irfunc->depth;
IF_LOG {
Logger::cout() << "Variable: " << vd->toChars() << '\n';
Logger::cout() << "Variable depth: " << vardepth << '\n';
Logger::cout() << "Function: " << irfunc->decl->toChars() << '\n';
Logger::cout() << "Function depth: " << funcdepth << '\n';
}
if (vardepth == funcdepth) {
// This is not always handled above because functions without
// variables accessed by nested functions don't create new frames.
IF_LOG Logger::println("Same depth");
} else {
// Load frame pointer and index that...
if (dwarfValue && global.params.symdebug) {
gIR->DBuilder.OpOffset(dwarfAddr, val, vd->ir.irLocal->nestedDepth);
gIR->DBuilder.OpDeref(dwarfAddr);
}
IF_LOG Logger::println("Lower depth");
val = DtoGEPi(val, 0, vd->ir.irLocal->nestedDepth);
IF_LOG Logger::cout() << "Frame index: " << *val << '\n';
val = DtoAlignedLoad(val, (std::string(".frame.") + vdparent->toChars()).c_str());
IF_LOG Logger::cout() << "Frame: " << *val << '\n';
}
int idx = vd->ir.irLocal->nestedIndex;
assert(idx != -1 && "Nested context not yet resolved for variable.");
//.........这里部分代码省略.........
示例11: assert
int ForeachStatement::inferApplyArgTypes(Scope *sc, Dsymbol *&sapply)
{
if (!arguments || !arguments->dim)
return 0;
if (sapply) // prefer opApply
{
for (size_t u = 0; u < arguments->dim; u++)
{ Parameter *arg = (*arguments)[u];
if (arg->type)
{
arg->type = arg->type->semantic(loc, sc);
arg->type = arg->type->addStorageClass(arg->storageClass);
}
}
Expression *ethis;
Type *tab = aggr->type->toBasetype();
if (tab->ty == Tclass || tab->ty == Tstruct)
ethis = aggr;
else
{ assert(tab->ty == Tdelegate && aggr->op == TOKdelegate);
ethis = ((DelegateExp *)aggr)->e1;
}
/* Look for like an
* int opApply(int delegate(ref Type [, ...]) dg);
* overload
*/
FuncDeclaration *fd = sapply->isFuncDeclaration();
if (fd)
{ sapply = inferApplyArgTypesX(ethis, fd, arguments);
}
#if 0
TemplateDeclaration *td = sapply->isTemplateDeclaration();
if (td)
{ inferApplyArgTypesZ(td, arguments);
}
#endif
return sapply ? 1 : 0;
}
/* Return if no arguments need types.
*/
for (size_t u = 0; u < arguments->dim; u++)
{ Parameter *arg = (*arguments)[u];
if (!arg->type)
break;
}
AggregateDeclaration *ad;
Parameter *arg = (*arguments)[0];
Type *taggr = aggr->type;
assert(taggr);
Type *tab = taggr->toBasetype();
switch (tab->ty)
{
case Tarray:
case Tsarray:
case Ttuple:
if (arguments->dim == 2)
{
if (!arg->type)
{
arg->type = Type::tsize_t; // key type
arg->type = arg->type->addStorageClass(arg->storageClass);
}
arg = (*arguments)[1];
}
if (!arg->type && tab->ty != Ttuple)
{
arg->type = tab->nextOf(); // value type
arg->type = arg->type->addStorageClass(arg->storageClass);
}
break;
case Taarray:
{ TypeAArray *taa = (TypeAArray *)tab;
if (arguments->dim == 2)
{
if (!arg->type)
{
arg->type = taa->index; // key type
arg->type = arg->type->addStorageClass(arg->storageClass);
}
arg = (*arguments)[1];
}
if (!arg->type)
{
arg->type = taa->next; // value type
arg->type = arg->type->addStorageClass(arg->storageClass);
}
break;
}
case Tclass:
ad = ((TypeClass *)tab)->sym;
goto Laggr;
//.........这里部分代码省略.........
示例12: assert
ldc::DIType ldc::DIBuilder::CreateCompositeType(Type *type) {
Type *t = type->toBasetype();
assert((t->ty == Tstruct || t->ty == Tclass) &&
"Unsupported type for debug info in DIBuilder::CreateCompositeType");
AggregateDeclaration *sd;
if (t->ty == Tstruct) {
TypeStruct *ts = static_cast<TypeStruct *>(t);
sd = ts->sym;
} else {
TypeClass *tc = static_cast<TypeClass *>(t);
sd = tc->sym;
}
assert(sd);
// Use the actual type associated with the declaration, ignoring any
// const/wrappers.
LLType *T = DtoType(sd->type);
IrTypeAggr *ir = sd->type->ctype->isAggr();
assert(ir);
if (static_cast<llvm::MDNode *>(ir->diCompositeType) != nullptr) {
return ir->diCompositeType;
}
// if we don't know the aggregate's size, we don't know enough about it
// to provide debug info. probably a forward-declared struct?
if (sd->sizeok == SIZEOKnone) {
return DBuilder.createUnspecifiedType(sd->toChars());
}
// elements
llvm::SmallVector<LLMetadata *, 16> elems;
// defaults
llvm::StringRef name = sd->toChars();
unsigned linnum = sd->loc.linnum;
ldc::DICompileUnit CU(GetCU());
assert(CU && "Compilation unit missing or corrupted");
ldc::DIFile file = CreateFile(sd);
ldc::DIType derivedFrom = getNullDIType();
// set diCompositeType to handle recursive types properly
unsigned tag = (t->ty == Tstruct) ? llvm::dwarf::DW_TAG_structure_type
: llvm::dwarf::DW_TAG_class_type;
#if LDC_LLVM_VER >= 307
ir->diCompositeType = DBuilder.createReplaceableCompositeType(
#else
ir->diCompositeType = DBuilder.createReplaceableForwardDecl(
#endif
tag, name, CU, file, linnum);
if (!sd->isInterfaceDeclaration()) // plain interfaces don't have one
{
ClassDeclaration *classDecl = sd->isClassDeclaration();
if (classDecl && classDecl->baseClass) {
derivedFrom = CreateCompositeType(classDecl->baseClass->getType());
// needs a forward declaration to add inheritence information to elems
ldc::DIType fwd =
DBuilder.createClassType(CU, // compile unit where defined
name, // name
file, // file where defined
linnum, // line number where defined
getTypeAllocSize(T) * 8, // size in bits
getABITypeAlign(T) * 8, // alignment in bits
0, // offset in bits,
DIFlags::FlagFwdDecl, // flags
derivedFrom, // DerivedFrom
getEmptyDINodeArray(),
getNullDIType(), // VTableHolder
nullptr, // TemplateParms
uniqueIdent(t)); // UniqueIdentifier
auto dt = DBuilder.createInheritance(fwd, derivedFrom, 0,
#if LDC_LLVM_VER >= 306
DIFlags::FlagPublic
#else
0
#endif
);
elems.push_back(dt);
}
AddFields(sd, file, elems);
}
auto elemsArray = DBuilder.getOrCreateArray(elems);
ldc::DIType ret;
if (t->ty == Tclass) {
ret = DBuilder.createClassType(CU, // compile unit where defined
name, // name
file, // file where defined
linnum, // line number where defined
getTypeAllocSize(T) * 8, // size in bits
getABITypeAlign(T) * 8, // alignment in bits
0, // offset in bits,
DIFlagZero, // flags
derivedFrom, // DerivedFrom
elemsArray,
getNullDIType(), // VTableHolder
nullptr, // TemplateParms
uniqueIdent(t)); // UniqueIdentifier
//.........这里部分代码省略.........
示例13: assert
DValue *DtoNestedVariable(Loc &loc, Type *astype, VarDeclaration *vd,
bool byref) {
IF_LOG Logger::println("DtoNestedVariable for %s @ %s", vd->toChars(),
loc.toChars());
LOG_SCOPE;
////////////////////////////////////
// Locate context value
Dsymbol *vdparent = vd->toParent2();
assert(vdparent);
IrFunction *irfunc = gIR->func();
// Check whether we can access the needed frame
FuncDeclaration *fd = irfunc->decl;
while (fd && fd != vdparent) {
fd = getParentFunc(fd);
}
if (!fd) {
error(loc, "function `%s` cannot access frame of function `%s`",
irfunc->decl->toPrettyChars(), vdparent->toPrettyChars());
return new DLValue(astype, llvm::UndefValue::get(DtoPtrToType(astype)));
}
// is the nested variable in this scope?
if (vdparent == irfunc->decl) {
return makeVarDValue(astype, vd);
}
// get the nested context
LLValue *ctx = nullptr;
bool skipDIDeclaration = false;
auto currentCtx = gIR->funcGen().nestedVar;
if (currentCtx) {
Logger::println("Using own nested context of current function");
ctx = currentCtx;
} else if (irfunc->decl->isMember2()) {
Logger::println(
"Current function is member of nested class, loading vthis");
AggregateDeclaration *cd = irfunc->decl->isMember2();
LLValue *val = irfunc->thisArg;
if (cd->isClassDeclaration()) {
val = DtoLoad(val);
}
ctx = DtoLoad(DtoGEPi(val, 0, getVthisIdx(cd), ".vthis"));
skipDIDeclaration = true;
} else {
Logger::println("Regular nested function, loading context arg");
ctx = DtoLoad(irfunc->nestArg);
}
assert(ctx);
IF_LOG { Logger::cout() << "Context: " << *ctx << '\n'; }
DtoCreateNestedContextType(vdparent->isFuncDeclaration());
assert(isIrLocalCreated(vd));
////////////////////////////////////
// Extract variable from nested context
const auto frameType = LLPointerType::getUnqual(irfunc->frameType);
IF_LOG { Logger::cout() << "casting to: " << *irfunc->frameType << '\n'; }
LLValue *val = DtoBitCast(ctx, frameType);
IrLocal *const irLocal = getIrLocal(vd);
const auto vardepth = irLocal->nestedDepth;
const auto funcdepth = irfunc->depth;
IF_LOG {
Logger::cout() << "Variable: " << vd->toChars() << '\n';
Logger::cout() << "Variable depth: " << vardepth << '\n';
Logger::cout() << "Function: " << irfunc->decl->toChars() << '\n';
Logger::cout() << "Function depth: " << funcdepth << '\n';
}
if (vardepth == funcdepth) {
// This is not always handled above because functions without
// variables accessed by nested functions don't create new frames.
IF_LOG Logger::println("Same depth");
} else {
// Load frame pointer and index that...
IF_LOG Logger::println("Lower depth");
val = DtoGEPi(val, 0, vardepth);
IF_LOG Logger::cout() << "Frame index: " << *val << '\n';
val = DtoAlignedLoad(
val, (std::string(".frame.") + vdparent->toChars()).c_str());
IF_LOG Logger::cout() << "Frame: " << *val << '\n';
}
const auto idx = irLocal->nestedIndex;
assert(idx != -1 && "Nested context not yet resolved for variable.");
LLSmallVector<int64_t, 2> dwarfAddrOps;
LLValue *gep = DtoGEPi(val, 0, idx, vd->toChars());
val = gep;
IF_LOG {
//.........这里部分代码省略.........
示例14: assert
llvm::DIType ldc::DIBuilder::CreateCompositeType(Type *type)
{
Type* t = type->toBasetype();
assert((t->ty == Tstruct || t->ty == Tclass) &&
"Unsupported type for debug info in DIBuilder::CreateCompositeType");
AggregateDeclaration* sd;
if (t->ty == Tstruct)
{
TypeStruct* ts = static_cast<TypeStruct*>(t);
sd = ts->sym;
}
else
{
TypeClass* tc = static_cast<TypeClass*>(t);
sd = tc->sym;
}
assert(sd);
// Use the actual type associated with the declaration, ignoring any
// const/… wrappers.
LLType *T = DtoType(sd->type);
IrTypeAggr *ir = sd->type->irtype->isAggr();
assert(ir);
if (static_cast<llvm::MDNode *>(ir->diCompositeType) != 0)
return ir->diCompositeType;
// if we don't know the aggregate's size, we don't know enough about it
// to provide debug info. probably a forward-declared struct?
if (sd->sizeok == 0)
#if LDC_LLVM_VER >= 304
return DBuilder.createUnspecifiedType(sd->toChars());
#else
return llvm::DICompositeType(NULL);
#endif
// elements
std::vector<llvm::Value *> elems;
// defaults
llvm::StringRef name = sd->toChars();
unsigned linnum = sd->loc.linnum;
llvm::DICompileUnit CU(GetCU());
assert(CU && CU.Verify() && "Compilation unit missing or corrupted");
llvm::DIFile file = CreateFile(sd->loc);
llvm::DIType derivedFrom;
// set diCompositeType to handle recursive types properly
unsigned tag = (t->ty == Tstruct) ? llvm::dwarf::DW_TAG_structure_type
: llvm::dwarf::DW_TAG_class_type;
ir->diCompositeType = DBuilder.createForwardDecl(tag, name,
#if LDC_LLVM_VER >= 302
CU,
#endif
file, linnum);
if (!sd->isInterfaceDeclaration()) // plain interfaces don't have one
{
if (t->ty == Tstruct)
{
ArrayIter<VarDeclaration> it(sd->fields);
size_t narr = sd->fields.dim;
elems.reserve(narr);
for (; !it.done(); it.next())
{
VarDeclaration* vd = it.get();
llvm::DIType dt = CreateMemberType(vd->loc.linnum, vd->type, file, vd->toChars(), vd->offset);
elems.push_back(dt);
}
}
else
{
ClassDeclaration *classDecl = sd->isClassDeclaration();
AddBaseFields(classDecl, file, elems);
if (classDecl->baseClass)
derivedFrom = CreateCompositeType(classDecl->baseClass->getType());
}
}
llvm::DIArray elemsArray = DBuilder.getOrCreateArray(elems);
llvm::DIType ret;
if (t->ty == Tclass) {
ret = DBuilder.createClassType(
CU, // compile unit where defined
name, // name
file, // file where defined
linnum, // line number where defined
getTypeBitSize(T), // size in bits
getABITypeAlign(T)*8, // alignment in bits
0, // offset in bits,
llvm::DIType::FlagFwdDecl, // flags
derivedFrom, // DerivedFrom
elemsArray
);
} else {
ret = DBuilder.createStructType(
CU, // compile unit where defined
name, // name
file, // file where defined
//.........这里部分代码省略.........
示例15: DtoNestedContext
LLValue* DtoNestedContext(Loc loc, Dsymbol* sym)
{
Logger::println("DtoNestedContext for %s", sym->toPrettyChars());
LOG_SCOPE;
IrFunction* irfunc = gIR->func();
bool fromParent = true;
LLValue* val;
// if this func has its own vars that are accessed by nested funcs
// use its own context
if (irfunc->nestedVar) {
val = irfunc->nestedVar;
fromParent = false;
}
// otherwise, it may have gotten a context from the caller
else if (irfunc->nestArg)
val = DtoLoad(irfunc->nestArg);
// or just have a this argument
else if (irfunc->thisArg)
{
AggregateDeclaration* ad = irfunc->decl->isMember2();
val = ad->isClassDeclaration() ? DtoLoad(irfunc->thisArg) : irfunc->thisArg;
if (!ad->vthis)
{
// This is just a plain 'outer' reference of a class nested in a
// function (but without any variables in the nested context).
return val;
}
val = DtoLoad(DtoGEPi(val, 0, ad->vthis->ir.irField->index, ".vthis"));
}
else
{
// Use null instead of e.g. LLVM's undef to not break bitwise
// comparison for instances of nested struct types which don't have any
// nested references.
return llvm::ConstantPointerNull::get(getVoidPtrType());
}
struct FuncDeclaration* fd = 0;
if (AggregateDeclaration *ad = sym->isAggregateDeclaration())
// If sym is a nested struct or a nested class, pass the frame
// of the function where sym is declared.
fd = ad->toParent()->isFuncDeclaration();
else
if (FuncDeclaration* symfd = sym->isFuncDeclaration()) {
// Make sure we've had a chance to analyze nested context usage
DtoCreateNestedContextType(symfd);
// if this is for a function that doesn't access variables from
// enclosing scopes, it doesn't matter what we pass.
// Tell LLVM about it by passing an 'undef'.
if (symfd && symfd->ir.irFunc->depth == -1)
return llvm::UndefValue::get(getVoidPtrType());
// If sym is a nested function, and it's parent context is different than the
// one we got, adjust it.
fd = getParentFunc(symfd, true);
}
if (fd) {
Logger::println("For nested function, parent is %s", fd->toChars());
FuncDeclaration* ctxfd = irfunc->decl;
Logger::println("Current function is %s", ctxfd->toChars());
if (fromParent) {
ctxfd = getParentFunc(ctxfd, true);
assert(ctxfd && "Context from outer function, but no outer function?");
}
Logger::println("Context is from %s", ctxfd->toChars());
unsigned neededDepth = fd->ir.irFunc->depth;
unsigned ctxDepth = ctxfd->ir.irFunc->depth;
Logger::cout() << "Needed depth: " << neededDepth << '\n';
Logger::cout() << "Context depth: " << ctxDepth << '\n';
if (neededDepth >= ctxDepth) {
// assert(neededDepth <= ctxDepth + 1 && "How are we going more than one nesting level up?");
// fd needs the same context as we do, so all is well
Logger::println("Calling sibling function or directly nested function");
} else {
val = DtoBitCast(val, LLPointerType::getUnqual(ctxfd->ir.irFunc->frameType));
val = DtoGEPi(val, 0, neededDepth);
val = DtoAlignedLoad(val, (std::string(".frame.") + fd->toChars()).c_str());
}
}
Logger::cout() << "result = " << *val << '\n';
Logger::cout() << "of type " << *val->getType() << '\n';
return val;
}