本文整理汇总了C++中AggregateDeclaration::isClassDeclaration方法的典型用法代码示例。如果您正苦于以下问题:C++ AggregateDeclaration::isClassDeclaration方法的具体用法?C++ AggregateDeclaration::isClassDeclaration怎么用?C++ AggregateDeclaration::isClassDeclaration使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类AggregateDeclaration
的用法示例。
在下文中一共展示了AggregateDeclaration::isClassDeclaration方法的13个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: semantic
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: makeNested
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);
}
}
}
}
}
示例3: makeNested
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);
}
}
示例4: println
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 {
//.........这里部分代码省略.........
示例5: DICompositeType
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
//.........这里部分代码省略.........
示例6: isAggregateMember
ClassDeclaration *Dsymbol::isClassMember() // are we a member of a class?
{
AggregateDeclaration *ad = isAggregateMember();
return ad ? ad->isClassDeclaration() : NULL;
}
示例7: if
//.........这里部分代码省略.........
}
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;
}
示例8: 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.");
//.........这里部分代码省略.........
示例9: semantic
void AnonDeclaration::semantic(Scope *sc)
{
//printf("\tAnonDeclaration::semantic %s %p\n", isunion ? "union" : "struct", this);
Scope *scx = NULL;
if (scope)
{ sc = scope;
scx = scope;
scope = NULL;
}
unsigned dprogress_save = Module::dprogress;
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;
}
if (decl)
{
AnonymousAggregateDeclaration aad;
int adisunion;
if (sc->anonAgg)
{ ad = sc->anonAgg;
adisunion = sc->inunion;
}
else
adisunion = ad->isUnionDeclaration() != NULL;
// printf("\tsc->anonAgg = %p\n", sc->anonAgg);
// printf("\tad = %p\n", ad);
// printf("\taad = %p\n", &aad);
sc = sc->push();
sc->anonAgg = &aad;
sc->stc &= ~(STCauto | STCscope | STCstatic | STCtls | STCgshared);
sc->inunion = isunion;
sc->offset = 0;
sc->flags = 0;
aad.structalign = sc->structalign;
aad.parent = ad;
for (unsigned i = 0; i < decl->dim; i++)
{
Dsymbol *s = (Dsymbol *)decl->data[i];
s->semantic(sc);
if (isunion)
sc->offset = 0;
if (aad.sizeok == 2)
{
break;
}
}
sc = sc->pop();
// If failed due to forward references, unwind and try again later
if (aad.sizeok == 2)
{
ad->sizeok = 2;
//printf("\tsetting ad->sizeok %p to 2\n", ad);
if (!sc->anonAgg)
{
scope = scx ? scx : new Scope(*sc);
scope->setNoFree();
scope->module->addDeferredSemantic(this);
}
Module::dprogress = dprogress_save;
//printf("\tforward reference %p\n", this);
return;
}
if (sem == 0)
{ Module::dprogress++;
sem = 1;
//printf("\tcompleted %p\n", this);
}
else
;//printf("\talready completed %p\n", this);
// 0 sized structs are set to 1 byte
if (aad.structsize == 0)
{
aad.structsize = 1;
aad.alignsize = 1;
}
// Align size of anonymous aggregate
//printf("aad.structalign = %d, aad.alignsize = %d, sc->offset = %d\n", aad.structalign, aad.alignsize, sc->offset);
ad->alignmember(aad.structalign, aad.alignsize, &sc->offset);
//ad->structsize = sc->offset;
//printf("sc->offset = %d\n", sc->offset);
// Add members of aad to ad
//.........这里部分代码省略.........
示例10: visit
void visit(CallExp *e)
{
//printf("CallExp(): %s\n", e->toChars());
/* Check each argument that is
* passed as 'return scope'.
*/
Type *t1 = e->e1->type->toBasetype();
TypeFunction *tf = NULL;
TypeDelegate *dg = NULL;
if (t1->ty == Tdelegate)
{
dg = (TypeDelegate *)t1;
tf = (TypeFunction *)dg->next;
}
else if (t1->ty == Tfunction)
tf = (TypeFunction *)t1;
else
return;
if (e->arguments && e->arguments->dim)
{
/* j=1 if _arguments[] is first argument,
* skip it because it is not passed by ref
*/
size_t j = (tf->linkage == LINKd && tf->varargs == 1);
for (size_t i = j; i < e->arguments->dim; ++i)
{
Expression *arg = (*e->arguments)[i];
size_t nparams = Parameter::dim(tf->parameters);
if (i - j < nparams && i >= j)
{
Parameter *p = Parameter::getNth(tf->parameters, i - j);
const StorageClass stc = tf->parameterStorageClass(p);
if ((stc & (STCscope)) && (stc & STCreturn))
arg->accept(this);
else if ((stc & (STCref)) && (stc & STCreturn))
escapeByRef(arg, er);
}
}
}
// If 'this' is returned, check it too
if (e->e1->op == TOKdotvar && t1->ty == Tfunction)
{
DotVarExp *dve = (DotVarExp *)e->e1;
FuncDeclaration *fd = dve->var->isFuncDeclaration();
AggregateDeclaration *ad = NULL;
if (global.params.vsafe && tf->isreturn && fd && (ad = fd->isThis()) != NULL)
{
if (ad->isClassDeclaration() || tf->isscope) // this is 'return scope'
dve->e1->accept(this);
else if (ad->isStructDeclaration()) // this is 'return ref'
escapeByRef(dve->e1, er);
}
else if (dve->var->storage_class & STCreturn || tf->isreturn)
{
if (dve->var->storage_class & STCscope)
dve->e1->accept(this);
else if (dve->var->storage_class & STCref)
escapeByRef(dve->e1, er);
}
}
/* If returning the result of a delegate call, the .ptr
* field of the delegate must be checked.
*/
if (dg)
{
if (tf->isreturn)
e->e1->accept(this);
}
}
示例11: CU
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
//.........这里部分代码省略.........
示例12: 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;
}
示例13: DtoNestedVariable
DValue* DtoNestedVariable(Loc loc, Type* astype, VarDeclaration* vd, bool byref)
{
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;
LLType *int64Ty = LLType::getInt64Ty(gIR->context());
// get the nested context
LLValue* ctx = 0;
if (irfunc->decl->isMember2())
{
#if DMDV2
AggregateDeclaration* cd = irfunc->decl->isMember2();
LLValue* val = irfunc->thisArg;
if (cd->isClassDeclaration())
val = DtoLoad(val);
#else
ClassDeclaration* cd = irfunc->decl->isMember2()->isClassDeclaration();
LLValue* val = DtoLoad(irfunc->thisArg);
#endif
ctx = DtoLoad(DtoGEPi(val, 0,cd->vthis->ir.irField->index, ".vthis"));
}
else if (irfunc->nestedVar) {
ctx = irfunc->nestedVar;
dwarfValue = ctx;
} else {
ctx = DtoLoad(irfunc->nestArg);
dwarfValue = irfunc->nestArg;
if (global.params.symdebug)
dwarfOpDeref(dwarfAddr);
}
assert(ctx);
DtoCreateNestedContextType(vdparent->isFuncDeclaration());
assert(vd->ir.irLocal);
////////////////////////////////////
// Extract variable from nested context
if (nestedCtx == NCArray) {
LLValue* val = DtoBitCast(ctx, getPtrToType(getVoidPtrType()));
val = DtoGEPi1(val, vd->ir.irLocal->nestedIndex);
val = DtoAlignedLoad(val);
assert(vd->ir.irLocal->value);
val = DtoBitCast(val, vd->ir.irLocal->value->getType(), vd->toChars());
return new DVarValue(astype, vd, val);
}
else if (nestedCtx == NCHybrid) {
LLValue* val = DtoBitCast(ctx, LLPointerType::getUnqual(irfunc->frameType));
Logger::cout() << "Context: " << *val << '\n';
Logger::cout() << "of type: " << *val->getType() << '\n';
unsigned vardepth = vd->ir.irLocal->nestedDepth;
unsigned funcdepth = irfunc->depth;
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.
Logger::println("Same depth");
} else {
// Load frame pointer and index that...
if (dwarfValue && global.params.symdebug) {
dwarfOpOffset(dwarfAddr, val, vd->ir.irLocal->nestedDepth);
dwarfOpDeref(dwarfAddr);
}
Logger::println("Lower depth");
val = DtoGEPi(val, 0, vd->ir.irLocal->nestedDepth);
//.........这里部分代码省略.........