Use the first element of a struct as a source for

extra inhabitants.

Obviously this should eventually be generalized to
take from any element, but this is good enough to
give us zero-cost abstraction via single-field structs.

Contains some bugfixes for the tuple-extra-inhabitant
changes as well, because test coverage for optional
structs is obviously quite a bit richer than for
optional tuples.

All of this is leading towards unblocking IRGen for
importing CFStringRef as Unmanaged<CFString>!.

Swift SVN r17243
This commit is contained in:
John McCall
2014-05-02 10:29:55 +00:00
parent 422df2e3bb
commit c0e4242bec
8 changed files with 142 additions and 50 deletions

View File

@@ -137,6 +137,27 @@ namespace {
return eltTI.getFixedExtraInhabitantCount(IGM);
}
// This is dead code in NonFixedTupleTypeInfo.
llvm::ConstantInt *getFixedExtraInhabitantValue(IRGenModule &IGM,
unsigned bits,
unsigned index) const {
auto &eltTI = cast<FixedTypeInfo>(asImpl().getFields()[0].getTypeInfo());
return eltTI.getFixedExtraInhabitantValue(IGM, bits, index);
}
// This is dead code in NonFixedTupleTypeInfo.
llvm::Value *maskFixedExtraInhabitant(IRGenFunction &IGF,
llvm::Value *tupleValue) const {
// Truncate down to the width of the element, mask it recursively,
// and then zext back out to the payload size.
auto &eltTI = cast<FixedTypeInfo>(asImpl().getFields()[0].getTypeInfo());
unsigned eltWidth = eltTI.getFixedSize().getValueInBits();
auto eltTy = llvm::IntegerType::get(IGF.IGM.getLLVMContext(), eltWidth);
auto eltValue = IGF.Builder.CreateTrunc(tupleValue, eltTy);
eltValue = eltTI.maskFixedExtraInhabitant(IGF, eltValue);
return IGF.Builder.CreateZExt(eltValue, tupleValue->getType());
}
llvm::Value *getExtraInhabitantIndex(IRGenFunction &IGF,
Address tupleAddr,
CanType tupleType) const override {