コード例 #1
0
ファイル: ArgumentSource.cpp プロジェクト: d-ronnqvist/swift
void ArgumentSource::forwardInto(SILGenFunction &SGF, Initialization *dest) && {
  switch (StoredKind) {
  case Kind::Invalid:
    llvm_unreachable("argument source is invalid");
  case Kind::LValue:
    llvm_unreachable("cannot forward an l-value");
  case Kind::RValue: {
    auto loc = getKnownRValueLocation();
    std::move(*this).asKnownRValue().forwardInto(SGF, loc, dest);
    return;
  }
  case Kind::Expr: {
    auto e = std::move(*this).asKnownExpr();
    SGF.emitExprInto(e, dest);
    return;
  }
  case Kind::Tuple: {
    auto loc = getKnownTupleLocation();
    auto rvalue = std::move(*this).getKnownTupleAsRValue(SGF, SGFContext(dest));
    if (!rvalue.isInContext())
      std::move(rvalue).forwardInto(SGF, loc, dest);
    return;
  }
  }
  llvm_unreachable("bad kind");
}
コード例 #2
0
ファイル: SILGenBuiltin.cpp プロジェクト: JoniusLi/swift-1
/// Emit Builtin.initialize by evaluating the operand directly into
/// the address.
static ManagedValue emitBuiltinInit(SILGenFunction &SGF,
                                    SILLocation loc,
                                    SubstitutionMap substitutions,
                                    PreparedArguments &&preparedArgs,
                                    SGFContext C) {
  auto argsOrError = decomposeArguments(SGF, loc, std::move(preparedArgs), 2);
  if (!argsOrError)
    return ManagedValue::forUnmanaged(SGF.emitEmptyTuple(loc));

  auto args = *argsOrError;

  CanType formalType =
    substitutions.getReplacementTypes()[0]->getCanonicalType();
  auto &formalTL = SGF.getTypeLowering(formalType);

  SILValue addr = SGF.emitRValueAsSingleValue(args[1]).getUnmanagedValue();
  addr = SGF.B.createPointerToAddress(
    loc, addr, formalTL.getLoweredType().getAddressType(),
    /*isStrict*/ true,
    /*isInvariant*/ false);

  TemporaryInitialization init(addr, CleanupHandle::invalid());
  SGF.emitExprInto(args[0], &init);

  return ManagedValue::forUnmanaged(SGF.emitEmptyTuple(loc));
}
コード例 #3
0
ファイル: ArgumentSource.cpp プロジェクト: 007Indian/swift
void ArgumentSource::forwardInto(SILGenFunction &gen, Initialization *dest) && {
  assert(!isLValue());
  if (isRValue()) {
    auto loc = getKnownRValueLocation();
    return std::move(*this).asKnownRValue().forwardInto(gen, loc, dest);
  }

  auto e = std::move(*this).asKnownExpr();
  return gen.emitExprInto(e, dest);
}
コード例 #4
0
ファイル: ArgumentSource.cpp プロジェクト: 007Indian/swift
ManagedValue ArgumentSource::materialize(SILGenFunction &gen) && {
  assert(!isLValue());
  if (isRValue()) {
    auto loc = getKnownRValueLocation();
    return std::move(*this).asKnownRValue().materialize(gen, loc);
  }

  auto expr = std::move(*this).asKnownExpr();
  auto temp = gen.emitTemporary(expr, gen.getTypeLowering(expr->getType()));
  gen.emitExprInto(expr, temp.get());
  return temp->getManagedAddress();
}
コード例 #5
0
ファイル: ArgumentSource.cpp プロジェクト: benlangmuir/swift
void ArgumentSource::forwardInto(SILGenFunction &SGF, Initialization *dest) && {
  switch (StoredKind) {
  case Kind::Invalid:
    llvm_unreachable("argument source is invalid");
  case Kind::LValue:
    llvm_unreachable("cannot forward an l-value");
  case Kind::RValue: {
    auto loc = getKnownRValueLocation();
    std::move(*this).asKnownRValue(SGF).ensurePlusOne(SGF, loc).forwardInto(SGF, loc, dest);
    return;
  }
  case Kind::Expr: {
    auto e = std::move(*this).asKnownExpr();
    SGF.emitExprInto(e, dest);
    return;
  }
  }
  llvm_unreachable("bad kind");
}
コード例 #6
0
ファイル: SILGenBuiltin.cpp プロジェクト: 0x4d4746h/swift
/// Emit Builtin.initialize by evaluating the operand directly into
/// the address.
static ManagedValue emitBuiltinInit(SILGenFunction &gen,
                                    SILLocation loc,
                                    ArrayRef<Substitution> substitutions,
                                    Expr *tuple,
                                    CanFunctionType formalApplyType,
                                    SGFContext C) {
  auto args = decomposeArguments(gen, tuple, 2);

  CanType formalType = substitutions[0].getReplacement()->getCanonicalType();
  auto &formalTL = gen.getTypeLowering(formalType);

  SILValue addr = gen.emitRValueAsSingleValue(args[1]).getUnmanagedValue();
  addr = gen.B.createPointerToAddress(loc, addr,
                                 formalTL.getLoweredType().getAddressType());

  TemporaryInitialization init(addr, CleanupHandle::invalid());
  gen.emitExprInto(args[0], &init);
  
  return ManagedValue::forUnmanaged(gen.emitEmptyTuple(loc));
}
コード例 #7
0
static void emitImplicitValueConstructor(SILGenFunction &gen,
                                         ConstructorDecl *ctor) {
  RegularLocation Loc(ctor);
  Loc.markAutoGenerated();
  // FIXME: Handle 'self' along with the other arguments.
  auto *paramList = ctor->getParameterList(1);
  auto selfTyCan = ctor->getImplicitSelfDecl()->getType()->getInOutObjectType();
  SILType selfTy = gen.getLoweredType(selfTyCan);

  // Emit the indirect return argument, if any.
  SILValue resultSlot;
  if (selfTy.isAddressOnly(gen.SGM.M)) {
    auto &AC = gen.getASTContext();
    auto VD = new (AC) ParamDecl(/*IsLet*/ false, SourceLoc(), SourceLoc(),
                                 AC.getIdentifier("$return_value"),
                                 SourceLoc(),
                                 AC.getIdentifier("$return_value"), selfTyCan,
                                 ctor);
    resultSlot = new (gen.F.getModule()) SILArgument(gen.F.begin(), selfTy, VD);
  }

  // Emit the elementwise arguments.
  SmallVector<RValue, 4> elements;
  for (size_t i = 0, size = paramList->size(); i < size; ++i) {
    auto &param = paramList->get(i);

    elements.push_back(
      emitImplicitValueConstructorArg(gen, Loc,
                                      param->getType()->getCanonicalType(),
                                      ctor));
  }

  emitConstructorMetatypeArg(gen, ctor);

  auto *decl = selfTy.getStructOrBoundGenericStruct();
  assert(decl && "not a struct?!");

  // If we have an indirect return slot, initialize it in-place.
  if (resultSlot) {

    auto elti = elements.begin(), eltEnd = elements.end();
    for (VarDecl *field : decl->getStoredProperties()) {
      auto fieldTy = selfTy.getFieldType(field, gen.SGM.M);
      auto &fieldTL = gen.getTypeLowering(fieldTy);
      SILValue slot = gen.B.createStructElementAddr(Loc, resultSlot, field,
                                                    fieldTL.getLoweredType().getAddressType());
      InitializationPtr init(new KnownAddressInitialization(slot));

      // An initialized 'let' property has a single value specified by the
      // initializer - it doesn't come from an argument.
      if (!field->isStatic() && field->isLet() &&
          field->getParentInitializer()) {
        assert(field->getType()->isEqual(field->getParentInitializer()
                                         ->getType()) && "Checked by sema");

        // Cleanup after this initialization.
        FullExpr scope(gen.Cleanups, field->getParentPatternBinding());
        gen.emitExprInto(field->getParentInitializer(), init.get());
        continue;
      }

      assert(elti != eltEnd && "number of args does not match number of fields");
      (void)eltEnd;
      std::move(*elti).forwardInto(gen, Loc, init.get());
      ++elti;
    }
    gen.B.createReturn(ImplicitReturnLocation::getImplicitReturnLoc(Loc),
                       gen.emitEmptyTuple(Loc));
    return;
  }

  // Otherwise, build a struct value directly from the elements.
  SmallVector<SILValue, 4> eltValues;

  auto elti = elements.begin(), eltEnd = elements.end();
  for (VarDecl *field : decl->getStoredProperties()) {
    auto fieldTy = selfTy.getFieldType(field, gen.SGM.M);
    SILValue v;

    // An initialized 'let' property has a single value specified by the
    // initializer - it doesn't come from an argument.
    if (!field->isStatic() && field->isLet() && field->getParentInitializer()) {
      // Cleanup after this initialization.
      FullExpr scope(gen.Cleanups, field->getParentPatternBinding());
      v = gen.emitRValue(field->getParentInitializer())
             .forwardAsSingleStorageValue(gen, fieldTy, Loc);
    } else {
      assert(elti != eltEnd && "number of args does not match number of fields");
      (void)eltEnd;
      v = std::move(*elti).forwardAsSingleStorageValue(gen, fieldTy, Loc);
      ++elti;
    }

    eltValues.push_back(v);
  }

  SILValue selfValue = gen.B.createStruct(Loc, selfTy, eltValues);
  gen.B.createReturn(ImplicitReturnLocation::getImplicitReturnLoc(Loc),
                     selfValue);
  return;
}