本文整理汇总了C++中VarDeclaration::isOut方法的典型用法代码示例。如果您正苦于以下问题:C++ VarDeclaration::isOut方法的具体用法?C++ VarDeclaration::isOut怎么用?C++ VarDeclaration::isOut使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类VarDeclaration
的用法示例。
在下文中一共展示了VarDeclaration::isOut方法的3个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: buildClosure
void FuncDeclaration::buildClosure(IRState *irs)
{
if (needsClosure())
{ // Generate closure on the heap
// BUG: doesn't capture variadic arguments passed to this function
#if DMDV2
/* BUG: doesn't handle destructors for the local variables.
* The way to do it is to make the closure variables the fields
* of a class object:
* class Closure
* { vtbl[]
* monitor
* ptr to destructor
* sthis
* ... closure variables ...
* ~this() { call destructor }
* }
*/
#endif
//printf("FuncDeclaration::buildClosure()\n");
Symbol *sclosure;
sclosure = symbol_name("__closptr",SCauto,Type::tvoidptr->toCtype());
sclosure->Sflags |= SFLtrue | SFLfree;
symbol_add(sclosure);
irs->sclosure = sclosure;
unsigned offset = PTRSIZE; // leave room for previous sthis
for (size_t i = 0; i < closureVars.dim; i++)
{ VarDeclaration *v = closureVars[i];
assert(v->isVarDeclaration());
#if DMDV2
if (v->needsAutoDtor())
/* Because the value needs to survive the end of the scope!
*/
v->error("has scoped destruction, cannot build closure");
if (v->isargptr)
/* See Bugzilla 2479
* This is actually a bug, but better to produce a nice
* message at compile time rather than memory corruption at runtime
*/
v->error("cannot reference variadic arguments from closure");
#endif
/* Align and allocate space for v in the closure
* just like AggregateDeclaration::addField() does.
*/
unsigned memsize;
unsigned memalignsize;
structalign_t xalign;
#if DMDV2
if (v->storage_class & STClazy)
{
/* Lazy variables are really delegates,
* so give same answers that TypeDelegate would
*/
memsize = PTRSIZE * 2;
memalignsize = memsize;
xalign = global.structalign;
}
else if (v->isRef() || v->isOut())
{ // reference parameters are just pointers
memsize = PTRSIZE;
memalignsize = memsize;
xalign = global.structalign;
}
else
#endif
{
memsize = v->type->size();
memalignsize = v->type->alignsize();
xalign = v->alignment;
}
AggregateDeclaration::alignmember(xalign, memalignsize, &offset);
v->offset = offset;
offset += memsize;
/* Can't do nrvo if the variable is put in a closure, since
* what the shidden points to may no longer exist.
*/
if (nrvo_can && nrvo_var == v)
{
nrvo_can = 0;
}
}
// offset is now the size of the closure
// Allocate memory for the closure
elem *e;
e = el_long(TYsize_t, offset);
e = el_bin(OPcall, TYnptr, el_var(rtlsym[RTLSYM_ALLOCMEMORY]), e);
// Assign block of memory to sclosure
// sclosure = allocmemory(sz);
e = el_bin(OPeq, TYvoid, el_var(sclosure), e);
// Set the first element to sthis
// *(sclosure + 0) = sthis;
elem *ethis;
if (irs->sthis)
//.........这里部分代码省略.........
示例2: DtoCreateNestedContext
//.........这里部分代码省略.........
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);
#if DMDV2
AggregateDeclaration* cd = fd->isMember2();
#else
ClassDeclaration* cd = fd->isMember2()->isClassDeclaration();
#endif
assert(cd);
assert(cd->vthis);
Logger::println("Indexing to 'this'");
#if DMDV2
if (cd->isStructDeclaration())
src = DtoExtractValue(thisval, cd->vthis->ir.irField->index, ".vthis");
else
#endif
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
LLValue* value = vd->ir.irLocal->value;
if (llvm::isa<llvm::AllocaInst>(llvm::GetUnderlyingObject(value))) {
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.
assert(!vd->ir.irLocal->byref);
DtoStore(DtoLoad(value), gep);
gep->takeName(value);
vd->ir.irLocal->value = gep;
} else {
Logger::println("Adding pointer to nested frame");
// The parameter value is something else, such as a
// passed-in pointer (for 'ref' or 'out' parameters) or
// a pointer arg with byval attribute.
// Store the address into the frame.
assert(vd->ir.irLocal->byref);
storeVariable(vd, gep);
}
} else if (vd->isRef() || vd->isOut()) {
// This slot is initialized in DtoNestedInit, to handle things like byref foreach variables
// which move around in memory.
assert(vd->ir.irLocal->byref);
} else {
Logger::println("nested var: %s", vd->toChars());
if (vd->ir.irLocal->value)
Logger::cout() << "Pre-existing value: " << *vd->ir.irLocal->value << '\n';
assert(!vd->ir.irLocal->value);
vd->ir.irLocal->value = gep;
assert(!vd->ir.irLocal->byref);
}
if (global.params.symdebug) {
LLSmallVector<LLValue*, 2> addr;
dwarfOpOffset(addr, frameType, vd->ir.irLocal->nestedIndex);
DtoDwarfLocalVariable(frame, vd, addr);
}
}
} else if (FuncDeclaration* parFunc = getParentFunc(fd, true)) {
// Propagate context arg properties if the context arg is passed on unmodified.
DtoDeclareFunction(parFunc);
fd->ir.irFunc->frameType = parFunc->ir.irFunc->frameType;
fd->ir.irFunc->depth = parFunc->ir.irFunc->depth;
}
}
else {
assert(0 && "Not implemented yet");
}
}
示例3: DtoCreateNestedContextType
//.........这里部分代码省略.........
DtoDeclareFunction(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()) {
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.
IrParameter * irparam = vd->ir.irParam;
LLValue* value = irparam->value;
assert(value);
LLType* type = value->getType();
bool refout = vd->storage_class & (STCref | STCout);
bool lazy = vd->storage_class & STClazy;
bool byref = irparam->arg->byref;
#if STRUCTTHISREF
bool isVthisPtr = irparam->isVthis && !byref;
#else
bool isVthisPtr = irparam->isVthis;
#endif
if ((!refout && (!byref || lazy)) || isVthisPtr) {
// This will be copied to the nesting frame.
if (lazy)
type = type->getContainedType(0);
else
type = DtoType(vd->type);
vd->ir.irParam->byref = false;
} else {
vd->ir.irParam->byref = true;
}
types.push_back(type);
} else if (vd->isRef() || vd->isOut()) {
// Foreach variables can also be by reference, for instance.
types.push_back(DtoType(vd->type->pointerTo()));
vd->ir.irLocal->byref = true;
} else {
types.push_back(DtoType(vd->type));
vd->ir.irLocal->byref = false;
}
if (Logger::enabled()) {
Logger::println("Nested var: %s", vd->toChars());
Logger::cout() << "of type: " << *types.back() << '\n';
}
}
LLStructType* frameType = LLStructType::create(gIR->context(), types,
std::string("nest.") + fd->toChars());
Logger::cout() << "frameType = " << *frameType << '\n';
// Store type in IrFunction
fd->ir.irFunc->frameType = frameType;
} else if (FuncDeclaration* parFunc = getParentFunc(fd, true)) {
// Propagate context arg properties if the context arg is passed on unmodified.
DtoCreateNestedContextType(parFunc);
fd->ir.irFunc->frameType = parFunc->ir.irFunc->frameType;
fd->ir.irFunc->depth = parFunc->ir.irFunc->depth;
}
}
else {
assert(0 && "Not implemented yet");
}
}