SILArgument: Make Decls mandatory for function arguments.

Swift SVN r11099
This commit is contained in:
Adrian Prantl
2013-12-10 23:30:23 +00:00
parent 61318e33f0
commit 2acb71831e
8 changed files with 100 additions and 45 deletions

View File

@@ -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);