Esempio n. 1
0
NullablePtr<SILInstruction>
Projection::
createAddrProjection(SILBuilder &B, SILLocation Loc, SILValue Base) const {
    // Grab Base's type.
    SILType BaseTy = Base.getType();

    // If BaseTy is not an address type, bail.
    if (!BaseTy.isAddress())
        return nullptr;

    // If this projection is associated with an object type, convert its type to
    // an address type.
    //
    // *NOTE* We purposely do not handle local storage types here since we want to
    // always fail in such a case. That is handled by checking that Ty is an
    // address.
    SILType Ty = Type.isObject()? Type.getAddressType() : Type;

    if (!Ty.isAddress())
        return nullptr;

    // Ok, we now know that the type of Base and the type represented by the base
    // of this projection match and that this projection can be represented as
    // value. Create the instruction if we can. Otherwise, return nullptr.
    switch (getKind()) {
    case ProjectionKind::Struct:
        return B.createStructElementAddr(Loc, Base, cast<VarDecl>(getDecl()));
    case ProjectionKind::Tuple:
        return B.createTupleElementAddr(Loc, Base, getIndex());
    case ProjectionKind::Index: {
        auto Ty = SILType::getBuiltinIntegerType(32, B.getASTContext());
        auto *IntLiteral = B.createIntegerLiteral(Loc, Ty, getIndex());
        return B.createIndexAddr(Loc, Base, IntLiteral);
    }
    case ProjectionKind::Enum:
        return B.createUncheckedTakeEnumDataAddr(Loc, Base,
                cast<EnumElementDecl>(getDecl()));
    case ProjectionKind::Class:
        return B.createRefElementAddr(Loc, Base, cast<VarDecl>(getDecl()));
    }
}
/// Given an index_raw_pointer Ptr, size_of(Metatype) * Distance create an
/// address_to_pointer (index_addr ptr, Distance : $*Metatype) : $RawPointer
/// instruction.
static SILValue createIndexAddrFrom(IndexRawPointerInst *I,
                                    MetatypeInst *Metatype,
                                    BuiltinInst *TruncOrBitCast,
                                    SILValue Ptr, SILValue Distance,
                                    SILType RawPointerTy,
                                    SILBuilder &Builder) {
  Builder.setCurrentDebugScope(I->getDebugScope());
  SILType InstanceType =
    Metatype->getType().getMetatypeInstanceType(I->getModule());

  // index_raw_pointer's address type is currently always strict.
  auto *NewPTAI = Builder.createPointerToAddress(
    I->getLoc(), Ptr, InstanceType.getAddressType(),
    /*isStrict*/ true, /*isInvariant*/ false);

  auto *DistanceAsWord =
      Builder.createBuiltin(I->getLoc(), TruncOrBitCast->getName(),
                             TruncOrBitCast->getType(), {}, Distance);

  auto *NewIAI = Builder.createIndexAddr(I->getLoc(), NewPTAI, DistanceAsWord);
  auto *NewATPI =
    Builder.createAddressToPointer(I->getLoc(), NewIAI, RawPointerTy);
  return NewATPI;
}