Allocating constructors are expected to allocate and assign 'this' on their own.

This implementation is very lame, because we don't currently have a
way to detect (in Sema or SIL) where 'this' gets uniquely assigned,
and turn that assignment into initialization.

Also, I'm starting to hate the name 'allocating' constructor, because
it's the opposite of the Itanium C++'s notion of the allocating
constructor. Will think up a better name.




Swift SVN r3347
This commit is contained in:
Doug Gregor
2012-12-04 01:06:30 +00:00
parent 445193a8e7
commit 08c9b5c7b2
6 changed files with 45 additions and 19 deletions

View File

@@ -266,27 +266,36 @@ static void emitClassConstructor(IRGenModule &IGM, ConstructorDecl *CD) {
// Emit the "this" variable
Initialization I;
I.registerObject(IGF, I.getObjectForDecl(thisDecl),
thisDecl->hasFixedLifetime() ? NotOnHeap : OnHeap, classTI);
thisDecl->hasFixedLifetime() ? NotOnHeap : OnHeap,
classTI);
Address addr = I.emitVariable(IGF, thisDecl, classTI);
FullExpr scope(IGF);
// Allocate the class.
// FIXME: Long-term, we clearly need a specialized runtime entry point.
if (!CD->getAttrs().isAllocatingConstructor()) {
FullExpr scope(IGF);
// Allocate the class.
// FIXME: Long-term, we clearly need a specialized runtime entry point.
llvm::Value *metadata = emitNominalMetadataRef(IGF, curClass, thisType);
llvm::Value *metadata = emitNominalMetadataRef(IGF, curClass, thisType);
llvm::Value *size = layout.emitSize(IGF);
llvm::Value *align = layout.emitAlign(IGF);
llvm::Value *val = IGF.emitAllocObjectCall(metadata, size, align,
"reference.new");
llvm::Type *destType = layout.getType()->getPointerTo();
llvm::Value *castVal = IGF.Builder.CreateBitCast(val, destType);
IGF.Builder.CreateStore(castVal, addr);
llvm::Value *size = layout.emitSize(IGF);
llvm::Value *align = layout.emitAlign(IGF);
llvm::Value *val = IGF.emitAllocObjectCall(metadata, size, align,
"reference.new");
llvm::Type *destType = layout.getType()->getPointerTo();
llvm::Value *castVal = IGF.Builder.CreateBitCast(val, destType);
IGF.Builder.CreateStore(castVal, addr);
scope.pop();
I.markInitialized(IGF, I.getObjectForDecl(thisDecl));
scope.pop();
I.markInitialized(IGF, I.getObjectForDecl(thisDecl));
} else {
// FIXME: Sema or SIL should identify where 'this' gets assigned, so we
// can do the initialization at that point, rather than zero'ing now
// and assigning later.
auto ptrType = layout.getType()->getPointerTo();
IGF.Builder.CreateStore(llvm::ConstantPointerNull::get(ptrType), addr);
}
IGF.emitConstructorBody(CD);
}