mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
SILArgument: Make Decls mandatory for function arguments.
Swift SVN r11099
This commit is contained in:
@@ -25,10 +25,10 @@ class SILArgument : public ValueBase {
|
||||
void operator delete(void *Ptr, size_t) = delete;
|
||||
|
||||
SILBasicBlock *ParentBB;
|
||||
ValueDecl *Decl;
|
||||
const ValueDecl *Decl;
|
||||
public:
|
||||
explicit
|
||||
SILArgument(SILType Ty, SILBasicBlock *ParentBB, ValueDecl *D = nullptr);
|
||||
SILArgument(SILType Ty, SILBasicBlock *ParentBB, const ValueDecl *D = nullptr);
|
||||
|
||||
/// getType() is ok since this is known to only have one type.
|
||||
SILType getType(unsigned i = 0) const { return ValueBase::getType(i); }
|
||||
|
||||
@@ -26,8 +26,20 @@ using namespace swift;
|
||||
// SILArgument Implementation
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
SILArgument::SILArgument(SILType Ty, SILBasicBlock *ParentBB, ValueDecl *D)
|
||||
SILArgument::SILArgument(SILType Ty, SILBasicBlock *ParentBB, const ValueDecl *D)
|
||||
: ValueBase(ValueKind::SILArgument, Ty), ParentBB(ParentBB), Decl(D) {
|
||||
// Function arguments need to have a decl.
|
||||
assert(
|
||||
// Unless the function is transparent,
|
||||
!ParentBB->getParent()->isTransparent() &&
|
||||
// or an ObjC thunk,
|
||||
ParentBB->getParent()->getAbstractCC() != AbstractCC::ObjCMethod &&
|
||||
// or comes from a SIL file.
|
||||
!ParentBB->getParent()->getLocation().is<SILFileLocation>() &&
|
||||
// Is this the initial basic block in the function?
|
||||
ParentBB->getParent()->size() == 1
|
||||
? D != nullptr
|
||||
: true );
|
||||
ParentBB->addArgument(this);
|
||||
}
|
||||
|
||||
|
||||
@@ -269,7 +269,7 @@ public:
|
||||
|
||||
RValue visitType(CanType t) {
|
||||
SILValue arg = new (gen.SGM.M)
|
||||
SILArgument(gen.getLoweredType(t), parent, loc.getAsASTNode<VarDecl>());
|
||||
SILArgument(gen.getLoweredType(t), parent, loc.getAsASTNode<ValueDecl>());
|
||||
ManagedValue mv = isa<LValueType>(t)
|
||||
? ManagedValue(arg, ManagedValue::LValue)
|
||||
: gen.emitManagedRValueWithCleanup(arg);
|
||||
|
||||
@@ -629,7 +629,14 @@ struct ArgumentInitVisitor :
|
||||
assert(I->kind == Initialization::Kind::Ignored &&
|
||||
"any pattern should match a black-hole Initialization");
|
||||
auto &lowering = gen.getTypeLowering(P->getType());
|
||||
SILValue arg = makeArgument(P->getType(), f.begin(), P);
|
||||
|
||||
auto &AC = gen.getASTContext();
|
||||
auto VD = new (AC) VarDecl(/*static*/ false, SourceLoc(),
|
||||
// FIXME: we should probably number them.
|
||||
AC.getIdentifier("_"), P->getType(),
|
||||
f.getDeclContext());
|
||||
|
||||
SILValue arg = makeArgument(P->getType(), f.begin(), VD);
|
||||
lowering.emitDestroyRValue(gen.B, P, arg);
|
||||
return arg;
|
||||
}
|
||||
@@ -676,7 +683,7 @@ static void emitCaptureArguments(SILGenFunction & gen, ValueDecl *capture) {
|
||||
// the captured value, and the address of the value itself.
|
||||
SILType ty = gen.getLoweredType(capture->getType()).getAddressType();
|
||||
SILValue box = new (gen.SGM.M) SILArgument(SILType::getObjectPointerType(c),
|
||||
gen.F.begin());
|
||||
gen.F.begin(), capture);
|
||||
SILValue addr = new (gen.SGM.M) SILArgument(ty, gen.F.begin(), capture);
|
||||
gen.VarLocs[capture] = SILGenFunction::VarLoc::getAddress(addr, box);
|
||||
gen.Cleanups.pushCleanup<CleanupCaptureBox>(box);
|
||||
@@ -735,7 +742,7 @@ static void emitCaptureArguments(SILGenFunction & gen, ValueDecl *capture) {
|
||||
void SILGenFunction::emitProlog(AnyFunctionRef TheClosure,
|
||||
ArrayRef<Pattern *> paramPatterns,
|
||||
Type resultType) {
|
||||
emitProlog(paramPatterns, resultType);
|
||||
emitProlog(paramPatterns, resultType, TheClosure.getAsDeclContext());
|
||||
|
||||
// Emit the capture argument variables. These are placed last because they
|
||||
// become the first curry level of the SIL function.
|
||||
@@ -746,12 +753,16 @@ void SILGenFunction::emitProlog(AnyFunctionRef TheClosure,
|
||||
}
|
||||
|
||||
void SILGenFunction::emitProlog(ArrayRef<Pattern *> paramPatterns,
|
||||
Type resultType) {
|
||||
Type resultType, DeclContext *DeclCtx) {
|
||||
// If the return type is address-only, emit the indirect return argument.
|
||||
const TypeLowering &returnTI = getTypeLowering(resultType);
|
||||
if (returnTI.isReturnedIndirectly()) {
|
||||
IndirectReturnAddress = new (SGM.M) SILArgument(returnTI.getLoweredType(),
|
||||
F.begin());
|
||||
auto &AC = getASTContext();
|
||||
auto VD = new (AC) VarDecl(/*static*/ false, SourceLoc(),
|
||||
AC.getIdentifier("$return_value"), resultType,
|
||||
DeclCtx);
|
||||
IndirectReturnAddress = new (SGM.M)
|
||||
SILArgument(returnTI.getLoweredType(), F.begin(), VD);
|
||||
}
|
||||
|
||||
// Emit the argument variables in calling convention order.
|
||||
|
||||
@@ -1931,23 +1931,31 @@ static void emitConstructorMetatypeArg(SILGenFunction &gen,
|
||||
// In addition to the declared arguments, the constructor implicitly takes
|
||||
// the metatype as its first argument, like a static function.
|
||||
Type metatype = ctor->getType()->castTo<AnyFunctionType>()->getInput();
|
||||
auto &AC = gen.getASTContext();
|
||||
auto VD = new (AC) VarDecl(/*static*/ false, SourceLoc(),
|
||||
AC.getIdentifier("$metatype"), metatype,
|
||||
ctor->getDeclContext());
|
||||
new (gen.F.getModule()) SILArgument(gen.getLoweredType(metatype),
|
||||
gen.F.begin());
|
||||
gen.F.begin(), VD);
|
||||
}
|
||||
|
||||
static RValue emitImplicitValueConstructorArg(SILGenFunction &gen,
|
||||
SILLocation loc,
|
||||
CanType ty) {
|
||||
CanType ty,
|
||||
DeclContext *DC) {
|
||||
// Restructure tuple arguments.
|
||||
if (CanTupleType tupleTy = dyn_cast<TupleType>(ty)) {
|
||||
RValue tuple(ty);
|
||||
for (auto fieldType : tupleTy.getElementTypes())
|
||||
tuple.addElement(emitImplicitValueConstructorArg(gen, loc, fieldType));
|
||||
tuple.addElement(emitImplicitValueConstructorArg(gen, loc, fieldType, DC));
|
||||
|
||||
return tuple;
|
||||
} else {
|
||||
auto &AC = gen.getASTContext();
|
||||
auto VD = new (AC) VarDecl(/*static*/ false, SourceLoc(),
|
||||
AC.getIdentifier("$implicit_value"), ty, DC);
|
||||
SILValue arg = new (gen.F.getModule()) SILArgument(gen.getLoweredType(ty),
|
||||
gen.F.begin());
|
||||
gen.F.begin(), VD);
|
||||
return RValue(gen, loc, ty, ManagedValue::forUnmanaged(arg));
|
||||
}
|
||||
}
|
||||
@@ -1969,20 +1977,27 @@ static void emitImplicitValueConstructor(SILGenFunction &gen,
|
||||
RegularLocation Loc(ctor);
|
||||
Loc.markAutoGenerated();
|
||||
auto *TP = cast<TuplePattern>(ctor->getBodyParams());
|
||||
SILType selfTy = gen.getLoweredType(ctor->getImplicitSelfDecl()->getType());
|
||||
auto selfTyCan = ctor->getImplicitSelfDecl()->getType();
|
||||
SILType selfTy = gen.getLoweredType(selfTyCan);
|
||||
|
||||
// Emit the indirect return argument, if any.
|
||||
SILValue resultSlot;
|
||||
if (selfTy.isAddressOnly(gen.SGM.M))
|
||||
resultSlot = new (gen.F.getModule()) SILArgument(selfTy, gen.F.begin());
|
||||
if (selfTy.isAddressOnly(gen.SGM.M)) {
|
||||
auto &AC = gen.getASTContext();
|
||||
auto VD = new (AC) VarDecl(/*static*/ false, SourceLoc(),
|
||||
AC.getIdentifier("$return_value"), selfTyCan,
|
||||
ctor);
|
||||
resultSlot = new (gen.F.getModule()) SILArgument(selfTy, gen.F.begin(), VD);
|
||||
}
|
||||
|
||||
// Emit the elementwise arguments.
|
||||
SmallVector<RValue, 4> elements;
|
||||
for (size_t i = 0, size = TP->getFields().size(); i < size; ++i) {
|
||||
auto *P = cast<TypedPattern>(TP->getFields()[i].getPattern());
|
||||
|
||||
elements.push_back(emitImplicitValueConstructorArg(gen, Loc,
|
||||
P->getType()->getCanonicalType()));
|
||||
elements.push_back(
|
||||
emitImplicitValueConstructorArg(gen, Loc,
|
||||
P->getType()->getCanonicalType(), ctor));
|
||||
}
|
||||
|
||||
emitConstructorMetatypeArg(gen, ctor);
|
||||
@@ -2067,7 +2082,8 @@ void SILGenFunction::emitValueConstructor(ConstructorDecl *ctor) {
|
||||
}
|
||||
|
||||
// Emit the prolog.
|
||||
emitProlog(ctor->getBodyParams(), ctor->getImplicitSelfDecl()->getType());
|
||||
emitProlog(ctor->getBodyParams(), ctor->getImplicitSelfDecl()->getType(),
|
||||
ctor);
|
||||
emitConstructorMetatypeArg(*this, ctor);
|
||||
|
||||
// Create a basic block to jump to for the implicit 'self' return.
|
||||
@@ -2118,20 +2134,26 @@ void SILGenFunction::emitValueConstructor(ConstructorDecl *ctor) {
|
||||
}
|
||||
|
||||
static void emitAddressOnlyEnumConstructor(SILGenFunction &gen,
|
||||
SILType enumTy,
|
||||
EnumElementDecl *element) {
|
||||
SILType enumTy,
|
||||
EnumElementDecl *element) {
|
||||
RegularLocation Loc(element);
|
||||
Loc.markAutoGenerated();
|
||||
|
||||
// Emit the indirect return slot.
|
||||
auto &AC = gen.getASTContext();
|
||||
auto VD = new (AC) VarDecl(/*static*/ false, SourceLoc(),
|
||||
AC.getIdentifier("$return_value"),
|
||||
enumTy.getSwiftType(),
|
||||
element->getDeclContext());
|
||||
SILValue resultSlot
|
||||
= new (gen.F.getModule()) SILArgument(enumTy, gen.F.begin());
|
||||
= new (gen.F.getModule()) SILArgument(enumTy, gen.F.begin(), VD);
|
||||
|
||||
// Emit the exploded constructor argument.
|
||||
ManagedValue argValue;
|
||||
if (element->hasArgumentType()) {
|
||||
RValue arg = emitImplicitValueConstructorArg(gen, Loc,
|
||||
element->getArgumentType()->getCanonicalType());
|
||||
RValue arg = emitImplicitValueConstructorArg
|
||||
(gen, Loc, element->getArgumentType()->getCanonicalType(),
|
||||
element->getDeclContext());
|
||||
argValue = std::move(arg).getAsSingleValue(gen, Loc);
|
||||
}
|
||||
emitConstructorMetatypeArg(gen, element);
|
||||
@@ -2159,8 +2181,10 @@ static void emitLoadableEnumConstructor(SILGenFunction &gen,
|
||||
// Emit the exploded constructor argument.
|
||||
SILValue argValue;
|
||||
if (element->hasArgumentType()) {
|
||||
RValue arg = emitImplicitValueConstructorArg(gen, Loc,
|
||||
element->getArgumentType()->getCanonicalType());
|
||||
RValue arg = emitImplicitValueConstructorArg
|
||||
(gen, Loc,
|
||||
element->getArgumentType()->getCanonicalType(),
|
||||
element->getDeclContext());
|
||||
argValue = std::move(arg).forwardAsSingleValue(gen, Loc);
|
||||
}
|
||||
|
||||
@@ -2198,20 +2222,22 @@ namespace {
|
||||
{
|
||||
SILGenFunction &gen;
|
||||
SmallVectorImpl<SILValue> &args;
|
||||
DeclContext *DC;
|
||||
public:
|
||||
ArgumentForwardVisitor(SILGenFunction &gen,
|
||||
SmallVectorImpl<SILValue> &args)
|
||||
: gen(gen), args(args) {}
|
||||
SmallVectorImpl<SILValue> &args,
|
||||
DeclContext *DC)
|
||||
: gen(gen), args(args), DC(DC) {}
|
||||
|
||||
void makeArgument(Type ty) {
|
||||
void makeArgument(Type ty, VarDecl *varDecl) {
|
||||
assert(ty && "no type?!");
|
||||
// Destructure tuple arguments.
|
||||
if (TupleType *tupleTy = ty->getAs<TupleType>()) {
|
||||
for (auto fieldType : tupleTy->getElementTypes())
|
||||
makeArgument(fieldType);
|
||||
makeArgument(fieldType, varDecl);
|
||||
} else {
|
||||
SILValue arg = new (gen.F.getModule()) SILArgument(gen.getLoweredType(ty),
|
||||
gen.F.begin());
|
||||
gen.F.begin(), varDecl);
|
||||
args.push_back(arg);
|
||||
}
|
||||
}
|
||||
@@ -2222,8 +2248,8 @@ namespace {
|
||||
|
||||
void visitTypedPattern(TypedPattern *P) {
|
||||
// FIXME: work around a bug in visiting the "self" argument of methods
|
||||
if (isa<NamedPattern>(P->getSubPattern()))
|
||||
makeArgument(P->getType());
|
||||
if (auto NP = dyn_cast<NamedPattern>(P->getSubPattern()))
|
||||
makeArgument(P->getType(), NP->getDecl());
|
||||
else
|
||||
visit(P->getSubPattern());
|
||||
}
|
||||
@@ -2234,11 +2260,15 @@ namespace {
|
||||
}
|
||||
|
||||
void visitAnyPattern(AnyPattern *P) {
|
||||
makeArgument(P->getType());
|
||||
auto &AC = gen.getASTContext();
|
||||
auto VD = new (AC) VarDecl(/*static*/ false, SourceLoc(),
|
||||
// FIXME: we should probably number them.
|
||||
AC.getIdentifier("_"), P->getType(), DC);
|
||||
makeArgument(P->getType(), VD);
|
||||
}
|
||||
|
||||
void visitNamedPattern(NamedPattern *P) {
|
||||
makeArgument(P->getType());
|
||||
makeArgument(P->getType(), P->getDecl());
|
||||
}
|
||||
|
||||
#define PATTERN(Id, Parent)
|
||||
@@ -2295,7 +2325,7 @@ void SILGenFunction::emitClassConstructorAllocator(ConstructorDecl *ctor) {
|
||||
SmallVector<SILValue, 8> args;
|
||||
|
||||
// Forward the constructor arguments.
|
||||
ArgumentForwardVisitor(*this, args).visit(ctor->getBodyParams());
|
||||
ArgumentForwardVisitor(*this, args, ctor).visit(ctor->getBodyParams());
|
||||
|
||||
emitConstructorMetatypeArg(*this, ctor);
|
||||
|
||||
@@ -2391,7 +2421,8 @@ void SILGenFunction::emitClassConstructorInitializer(ConstructorDecl *ctor) {
|
||||
emitLocalVariable(selfDecl);
|
||||
|
||||
// Emit the prolog for the non-self arguments.
|
||||
emitProlog(ctor->getBodyParams(), TupleType::getEmpty(F.getASTContext()));
|
||||
emitProlog(ctor->getBodyParams(), TupleType::getEmpty(F.getASTContext()),
|
||||
ctor);
|
||||
|
||||
SILType selfTy = getLoweredLoadableType(selfDecl->getType());
|
||||
SILValue selfArg = new (SGM.M) SILArgument(selfTy, F.begin(), selfDecl);
|
||||
@@ -2538,7 +2569,7 @@ void SILGenFunction::emitCurryThunk(FuncDecl *fd,
|
||||
|
||||
// Forward the curried formal arguments.
|
||||
auto forwardedPatterns = fd->getBodyParamPatterns().slice(0, paramCount);
|
||||
ArgumentForwardVisitor forwarder(*this, curriedArgs);
|
||||
ArgumentForwardVisitor forwarder(*this, curriedArgs, fd);
|
||||
for (auto *paramPattern : reversed(forwardedPatterns))
|
||||
forwarder.visit(paramPattern);
|
||||
|
||||
@@ -2589,7 +2620,7 @@ void SILGenFunction::emitForeignThunk(SILDeclRef thunk) {
|
||||
// inputs according to the foreign convention.
|
||||
auto forwardedPatterns = fd->getBodyParamPatterns();
|
||||
SmallVector<SILValue, 8> args;
|
||||
ArgumentForwardVisitor forwarder(*this, args);
|
||||
ArgumentForwardVisitor forwarder(*this, args, fd);
|
||||
for (auto *paramPattern : reversed(forwardedPatterns))
|
||||
forwarder.visit(paramPattern);
|
||||
|
||||
@@ -2620,7 +2651,7 @@ void SILGenFunction::emitGeneratorFunction(SILDeclRef function, Expr *value) {
|
||||
RegularLocation Loc(value);
|
||||
Loc.markAutoGenerated();
|
||||
|
||||
emitProlog({ }, value->getType());
|
||||
emitProlog({ }, value->getType(), function.getDecl()->getDeclContext());
|
||||
prepareEpilog(value->getType(), CleanupLocation::getCleanupLocation(Loc));
|
||||
emitReturnExpr(Loc, value);
|
||||
emitEpilog(Loc);
|
||||
|
||||
@@ -448,7 +448,7 @@ public:
|
||||
void emitProlog(AnyFunctionRef TheClosure, ArrayRef<Pattern*> paramPatterns,
|
||||
Type resultType);
|
||||
void emitProlog(ArrayRef<Pattern*> paramPatterns,
|
||||
Type resultType);
|
||||
Type resultType, DeclContext *DeclCtx);
|
||||
|
||||
/// \brief Create (but do not emit) the epilog branch, and save the
|
||||
/// current cleanups depth as the destination for return statement branches.
|
||||
|
||||
@@ -340,14 +340,14 @@ ClosureCloner::populateCloned() {
|
||||
SILArgument *ReleaseArgument = *I++;
|
||||
SILValue MappedValue =
|
||||
new (M) SILArgument((*I)->getType().getObjectType(),
|
||||
ClonedEntryBB);
|
||||
ClonedEntryBB, (*I)->getDecl());
|
||||
BoxArgumentMap.insert(std::make_pair(ReleaseArgument, MappedValue));
|
||||
AddrArgumentMap.insert(std::make_pair(*I, MappedValue));
|
||||
++ArgNo;
|
||||
} else {
|
||||
// Otherwise, create a new argument which copies the original argument
|
||||
SILValue MappedValue =
|
||||
new (M) SILArgument((*I)->getType(), ClonedEntryBB);
|
||||
new (M) SILArgument((*I)->getType(), ClonedEntryBB, (*I)->getDecl());
|
||||
ValueMap.insert(std::make_pair(*I, MappedValue));
|
||||
}
|
||||
++ArgNo;
|
||||
|
||||
@@ -128,7 +128,8 @@ void TypeSubCloner::populateCloned() {
|
||||
auto I = OrigEntryBB->bbarg_begin(), E = OrigEntryBB->bbarg_end();
|
||||
while (I != E) {
|
||||
SILValue MappedValue =
|
||||
new (M) SILArgument(remapType((*I)->getType()), ClonedEntryBB);
|
||||
new (M) SILArgument(remapType((*I)->getType()), ClonedEntryBB,
|
||||
(*I)->getDecl());
|
||||
ValueMap.insert(std::make_pair(*I, MappedValue));
|
||||
++I;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user