Commit Graph

6754 Commits

Author SHA1 Message Date
Chris Lattner
a8d8e14254 introduce AbstractStorageDecl. Right now, just
move OverriddenDecl and usesObjCGetterAndSetter() up to it.
This allows usesObjCGetterAndSetter to subsume the logic
for subscript decls as well.



Swift SVN r12535
2014-01-18 19:08:39 +00:00
Chris Lattner
bb3c0d52dc Unfortunately, two conflated NFC patches:
1) Revert my change to give DeclContext a dump method, it confuses the debugger.
2) Refactor SILGen::requiresObjCPropertyEntryPoints out to 
   VarDecl::usesObjCGetterAndSetter.


Swift SVN r12526
2014-01-18 02:00:23 +00:00
Chris Lattner
b4735381d0 Plumb the DeclContext of the use site down to the "doesVarDeclMemberProduceLValue"
function.  Pretty soon, whether something is an lvalue or not will depend on who is
asking.


Swift SVN r12507
2014-01-17 22:14:02 +00:00
Doug Gregor
4d6fc894be Propagate nil returned from a self.init or super.init call.
What we actually do here will likely change depending on how we want
to handle error propagation in general, but for now it suffices to
propagate the nil via an early exit.

Swift SVN r12440
2014-01-17 00:17:15 +00:00
Jordan Rose
11008f0ed1 Split diagnostics out into separate files.
Thanks to the way we've set up our diagnostics engine, there's not actually
a reason for /everything/ to get rebuilt when /one/ diagnostic changes.
I've split them up into five categories for now: Parse, Sema, SIL, IRGen,
and Frontend, plus a set of "Common" diagnostics that are used in multiple
areas of the compiler. We can massage this later.

No functionality change, but should speed up compile times!

Swift SVN r12438
2014-01-17 00:15:12 +00:00
Doug Gregor
133bb13848 Always assume that the result of calling self.init or super.init is of the appropriate subclass type.
Eliminates some Swift-side checking for a memory safety problem that
can only originate in Objective-C.

Swift SVN r12413
2014-01-16 19:58:09 +00:00
Doug Gregor
30a34e5a56 Lower the rebinding of 'self' in a super.init call to a cast when it can't fail.
Swift-rooted class hierarchies don't permit the replacement of "self",
so it's guaranteed that the 'self' returned from a 'super.init'
invocation is identical to the previous self. Elide the unconditional
checked downcast (that manifests as a call to
swift_dynamicCastClassUnconditional in the runtime) by putting in the
moral equivalent of a bitcast.

For Objective-C-rooted hierarchies, 'self' can be replaced, so memory
safety dictates that we use the unconditional checked downcast. Note
that this path is still unsafe against nil returns.

Swift SVN r12401
2014-01-16 06:01:22 +00:00
Doug Gregor
3a6db8292e Revert "Introduce the self_downcast SIL instruction to downcast the result of super.init."
We need to model the difference between Objective-C- and Swift-rooted
class hierarchies in SIL. IRGen is too late to handle nil returns.

This reverts commit 549db981ea0136a67aee3029aefe18a05d3c8833.

Swift SVN r12400
2014-01-16 06:01:21 +00:00
Doug Gregor
d19065048b Introduce the self_downcast SIL instruction to downcast the result of super.init.
No functional difference from the unconditional checked downcast we
had before, but this gives IRGen the chance to specialize the
implementation.

Swift SVN r12382
2014-01-16 04:24:56 +00:00
Doug Gregor
e5adce56ad Clarify SILGen lowering of the self-rebinding expression. NFC
Swift SVN r12377
2014-01-16 01:40:03 +00:00
Chris Lattner
c264d334fa teach SILGenApply about 'let' declarations, so that @autoclosure lets
get marked transparent the same way @autoclosure var's do.


Swift SVN r12368
2014-01-16 00:41:54 +00:00
John McCall
3c0d18dc1f Pass a ResilienceExpansion when mangling a SILDeclRef.
Swift SVN r12366
2014-01-16 00:36:39 +00:00
Chris Lattner
1b6c2e321e change a few "createCopyValue"'s to "emitCopyValue" so that trivial types
don't get copyvalues.  This is mostly to make sure that only Typelowering and
silcloner are calling createCopyValue.


Swift SVN r12365
2014-01-16 00:27:32 +00:00
John McCall
a1b469ed2f ExplosionKind -> ResilienceExpansion. NFC.
Swift SVN r12364
2014-01-16 00:25:29 +00:00
Chris Lattner
e180f9b601 Properly handle the case when a member_ref_expr on an rvalue struct
causes an abstraction change.


Swift SVN r12354
2014-01-15 22:19:03 +00:00
John McCall
1ccf23487e Remove unnecessary ASTContext& argument from getOptionalObjectType().
Swift SVN r12344
2014-01-15 21:00:58 +00:00
Chris Lattner
261b21a10f various random cleanups to pattern processing stuff, NFC.
Swift SVN r12335
2014-01-15 19:12:45 +00:00
Chris Lattner
eacb823fd5 fix rdar://15821990 - Don't emit default value for type var in instance init() body.
Swift SVN r12319
2014-01-15 05:31:43 +00:00
Joe Groff
990212b1c6 SILGen: When applying the result function of a function, do not reabstract to the original callee's abstraction pattern.
We already reabstracted the result function to the substituted function type. Quick fix for <rdar://problem/15598596>.

Swift SVN r12307
2014-01-15 01:20:14 +00:00
Chris Lattner
fe41a8ad6b Closures over address-only let decls: these will often be captured
by box (which is not "Constant" closure kind) because partial_apply
can't handle copy-in semantics.


Swift SVN r12278
2014-01-14 04:47:58 +00:00
John McCall
817e80bde5 Implicit conversions for UncheckedOptional.
rdar://15189000
rdar://15189009

Swift SVN r12260
2014-01-13 23:15:03 +00:00
Doug Gregor
57d278a9bd Given -.cxx_construct the proper return type; it returns self.
Initialization via .cxx_construct is now functional.


Swift SVN r12255
2014-01-13 21:55:49 +00:00
Doug Gregor
5664bee5fb Mark 'self' as uninitialized in the ivar initializer (-.cxx_construct).
This ensures that DI will initialize the ivars rather than assigning
to them.


Swift SVN r12246
2014-01-13 21:22:06 +00:00
Doug Gregor
c6b880a9b7 Definite initialization for initializers relying on a separate ivar initializer.
When we decide to emit a separate ivar initializer method (via the
Objective-C entry point -.cxx_construct), we no longer initialize the
ivars within the initializer. This only happens for derived classes,
so teach DI about uninitialized 'self' values that require a
super.init call but don't require the ivars to be initialized.



Swift SVN r12240
2014-01-13 19:41:16 +00:00
Chris Lattner
7db7d4a813 Three changes:
- constify the Initialization::getAddressOrNull/hasAddress functions.
 - Teach the initialization logic that 'let' initializations can be
   split into tuple subelements by address (i.e. i
   getSubInitializationsForTuple works on them) when the let decl has
   a backing memory allocation.
 - Teach LetValueInitialization to produce a backing memory object
   for address-only tuple arguments, since they are passed as multiple
   SILArguments and need some place in memory to reassemble them.

The collection fixes a bad miscompilation where the RValue logic emitted
a temporary (through getSingleValue) which we then accidentally lifetime
extended for the duration of the argument.  This led to bad things when
the temporary got destroyed too early.

Thanks to MichaelG for helping narrow down this problem, it initially looked
like a sil optimizer bug.


Swift SVN r12234
2014-01-13 17:24:40 +00:00
Chris Lattner
36b765eac9 Switch the rest of the ArgumentInitVisitor cases over to using
RValue::forwardInto.  While this isn't directly related to my
current problem, it is obvious goodness.  This avoids materializing
"as a single value" the argument values, which means that we don't
create a temporary holding the value when we have tuple elements,
allowing us to generate more efficient code (particularly for
address-only tuple).



Swift SVN r12233
2014-01-13 17:02:42 +00:00
Chris Lattner
c058f51fc9 LetValueInitialization::bindValue and bindArgument do the same thing,
so merge them.  ArgumentInitVisitor is very very similar to 
InitializeTupleValues, so start using RValue::forwardInto in
ArgumentInitVisitor for some cases instead of duplciating logic.  This
gives ArgumentInitVisitor some extra magic for lets which I'll be using
in a bit.


Swift SVN r12231
2014-01-13 16:53:01 +00:00
Chris Lattner
8f467059b0 Remove the return value of ArgumentInitVisitor, nothing consumes it.
Doing so makes it plain that the empty tuple case doesn't need to 
synthesize a tupleinst to return.  Eliminating this gets rid of the
weird dead empty tuple you may have seen get dropped in the prolog
of functions taking no arguments.

Also, push around RValue handling a bit in ArgumentInitVisitor, NFC
for this part.



Swift SVN r12230
2014-01-13 16:39:03 +00:00
Doug Gregor
ea209da4be When needed, emit a Objective-C .cxx_construct method to initialize stored properties.
When a class that will be allocated by the Objective-C runtime also
requires all of its stored properties have initial values, move that
complete initialization of the object into -.cxx_construct, which is
invoked by the runtime after +alloc.

Definite initialization doesn't like the resulting initializers (which
don't initialize any of their ivars) at all, so no end-to-end testing yet.

Swift SVN r12229
2014-01-13 16:31:23 +00:00
Chris Lattner
cab4e1caf6 emit debug_value for class constructors that don't need a box (i.e. root classes).
We don't need it for value constructors or derived classes, since those have an
allocation for self that carries debug info.


Swift SVN r12214
2014-01-12 07:16:14 +00:00
Chris Lattner
76bea38d3e emit debug_value for 'self' in class destructors of all sorts, and
rename emitDestructorProlog -> emitSelfDecl, since that is what it 
does.


Swift SVN r12213
2014-01-12 06:44:11 +00:00
Doug Gregor
6957209b84 Add a note indicating that we shouldn't emit ivar initialization in ObjC initializers.
Swift SVN r12212
2014-01-12 04:49:26 +00:00
Doug Gregor
fc7dfb2fae Start emitting .cxx_construct methods for Objective-C-derived classes.
When we're using Objective-C's memory allocation, emit .cxx_construct
methods whenever we have instance variables with in-class
initializers. Presently, these methods are just empty stubs.

Swift SVN r12211
2014-01-12 04:31:52 +00:00
Doug Gregor
804a23e32f Only emit the Objective-C -dealloc method if it does something.
Instance variable destruction is handled separately by -.cxx_destruct,
and the message send to the superclass's -dealloc is handled by the
Objective-C runtime, so we only need to emit a -dealloc if there is
any user code in it.

Swift SVN r12210
2014-01-12 02:07:01 +00:00
Doug Gregor
19f0aaf44c Only emit the Objective-C -.cxx_destruct when it has something to do.
This saves some deallocation time in the Objective-C runtime for
simple Swift classes that inherit from Objective-C classes.

Swift SVN r12208
2014-01-12 01:32:09 +00:00
Doug Gregor
7950fc2df6 Only emit the Objective-C entry point for the ivar destroyer (-.cxx_destruct).
The Swift entry point will never be referenced by anything, so don't
bother generating it.

Swift SVN r12207
2014-01-12 00:50:12 +00:00
Doug Gregor
3524a79fa0 Emit .cxx_destruct for destruction of ivars in Objective-C-derived classes.
The Objective-C runtime executes the .cxx_destruct method after the
last -dealloc has executed when destroying an object, allowing the
instance variables to remain live even after the subclass's
destructor/-dealloc has executed, which is important for memory
safety. This fixes the majority of <rdar://problem/15136592>.

Note that IRGenModule::getAddrOfIVarDestroyer() contains  an egregious
hack to find the ivar destructor SIL function via a linear
search. We need a better way to find SIL functions that we know exist,
because LinkEntity does not suffice.

Swift SVN r12206
2014-01-12 00:17:42 +00:00
Doug Gregor
34113ffee4 Emit both Swift and Objective-C entry points for -dealloc.
The Swift entry point is required for the Swift metadata, while the
Objective-C entry point goes into the Objective-C metadata. As part of
this, stop emitting the destroying destructor for classes that use
Objective-C allocation: it won't work anyway.

Swift SVN r12199
2014-01-11 04:37:39 +00:00
Chris Lattner
f8570072cd Teach SILGen to generate debug_value and debug_value_addr for 'let' decls.
Right now I unconditionally generate these, because silgen doesn't have
easy access to whether "-g" is passed or not.  We can either make SILGen
know about this, or we can have optimizations strip these uses out.
Opinions welcome!

As an example, something like:
protocol P { func bonk() }

func foo(let a : Int, let b : P) -> Int {
  let x = a
  b.bonk()
  return x
}

compiles into:

sil @_TF1t3fooFT1aSi1bPS_1P__Si : $@thin (Int64, @in P) -> Int64 {
bb0(%0 : $Int64, %1 : $*P):
  debug_value %0 : $Int64  // let a               // id: %2
  debug_value_addr %1 : $*P  // let b             // id: %3
  debug_value %0 : $Int64  // let x               // id: %4
  %5 = project_existential %1 : $*P to $*@sil_self P // user: %7
  %6 = protocol_method %1 : $*P, #P.bonk!1 : $@cc(witness_method) @callee_owned (@inout Self) -> () // user: %7
  %7 = apply %6(%5) : $@cc(witness_method) @callee_owned (@inout Self) -> ()
  destroy_addr %1 : $*P                           // id: %8
  return %0 : $Int64                              // id: %9
}



Swift SVN r12193
2014-01-11 02:08:58 +00:00
Joe Groff
ee85fb341a SILGen: Strip non-semantic pattern nodes before dispatching.
Fixes a crash when redundant parens wrapped a subpattern.

Swift SVN r12164
2014-01-10 23:15:32 +00:00
Doug Gregor
f05263d4fe Objective-C's -dealloc is a deallocating destructor, not a destroying destructor.
Because Objective-C doesn't have the notion of a destroying
destructor, this is a matter of cleanliness rather than
correctness. Still, it's better not to lie.


Swift SVN r12160
2014-01-10 23:08:42 +00:00
Doug Gregor
1b746bc3b5 Move the creation of deallocating destructors from IRGen to SILGen.
This is the first (and only) use of the dealloc_ref instruction.

Swift SVN r12145
2014-01-10 22:32:55 +00:00
Doug Gregor
7b0783f985 Move the "gather all substitutions" operation into the AST. SILGen also needs it.
Swift SVN r12142
2014-01-10 22:32:51 +00:00
Doug Gregor
2bf20ccbc3 Add the ClassDecl::getDestructor() convenience method.
Swift SVN r12140
2014-01-10 22:32:49 +00:00
Chris Lattner
c081e7ddb1 random comment cleanups.
Swift SVN r12133
2014-01-10 20:25:24 +00:00
Chris Lattner
373d0de766 Now that SILGen is in charge of temporary materialization (or not) we
can implement fun optimizations.  Here, we avoid materializing a
temporary copy for 'let' bases of protocol and archetype methods.
Consider:
protocol SimpleProtocol {
  func doSomethingGreat()
}

func testLetProtocolBases(let p : SimpleProtocol) {
  p.doSomethingGreat()
  p.doSomethingGreat()
}

before we produced:

sil @_TF1t20testLetProtocolBasesFT1pPS_14SimpleProtocol__T_ : $@thin (@in SimpleProtocol) -> () {
bb0(%0 : $*SimpleProtocol):
  %1 = alloc_stack $SimpleProtocol                // users: %7, %6, %4, %3, %2
  copy_addr %0 to [initialization] %1#1 : $*SimpleProtocol // id: %2
  %3 = project_existential %1#1 : $*SimpleProtocol to $*@sil_self SimpleProtocol // user: %5
  %4 = protocol_method %1#1 : $*SimpleProtocol, #SimpleProtocol.doSomethingGreat!1 : $@cc(witness_method) @callee_owned (@inout Self) -> () // user: %5
  %5 = apply %4(%3) : $@cc(witness_method) @callee_owned (@inout Self) -> ()
  destroy_addr %1#1 : $*SimpleProtocol            // id: %6
  dealloc_stack %1#0 : $*@local_storage SimpleProtocol // id: %7
  %8 = alloc_stack $SimpleProtocol                // users: %14, %13, %11, %10, %9
  copy_addr %0 to [initialization] %8#1 : $*SimpleProtocol // id: %9
  %10 = project_existential %8#1 : $*SimpleProtocol to $*@sil_self SimpleProtocol // user: %12
  %11 = protocol_method %8#1 : $*SimpleProtocol, #SimpleProtocol.doSomethingGreat!1 : $@cc(witness_method) @callee_owned (@inout Self) -> () // user: %12
  %12 = apply %11(%10) : $@cc(witness_method) @callee_owned (@inout Self) -> ()
  destroy_addr %8#1 : $*SimpleProtocol            // id: %13
  dealloc_stack %8#0 : $*@local_storage SimpleProtocol // id: %14
  destroy_addr %0 : $*SimpleProtocol              // id: %15
  %16 = tuple ()                                  // user: %17
  return %16 : $()                                // id: %17
}

now we produce the svelte:

sil @_TF1t20testLetProtocolBasesFT1pPS_14SimpleProtocol__T_ : $@thin (@in SimpleProtocol) -> () {
bb0(%0 : $*SimpleProtocol):
  %1 = project_existential %0 : $*SimpleProtocol to $*@sil_self SimpleProtocol // user: %3
  %2 = protocol_method %0 : $*SimpleProtocol, #SimpleProtocol.doSomethingGreat!1 : $@cc(witness_method) @callee_owned (@inout Self) -> () // user: %3
  %3 = apply %2(%1) : $@cc(witness_method) @callee_owned (@inout Self) -> ()
  %4 = project_existential %0 : $*SimpleProtocol to $*@sil_self SimpleProtocol // user: %6
  %5 = protocol_method %0 : $*SimpleProtocol, #SimpleProtocol.doSomethingGreat!1 : $@cc(witness_method) @callee_owned (@inout Self) -> () // user: %6
  %6 = apply %5(%4) : $@cc(witness_method) @callee_owned (@inout Self) -> ()
  destroy_addr %0 : $*SimpleProtocol              // id: %7
  %8 = tuple ()                                   // user: %9
  return %8 : $()                                 // id: %9
}

It turns out that 'var's were getting this optimization accidentally because the var
box had the single reference, but that it didn't work for 'let's.  It turns out that 
this optimization matters a lot when you enter the intersection of "required 
optimizations" that our string/array append implementation
imply: doing the extra copy defeats their "has one reference" optimizations. 

This also refactors some code into a shared place between archetypes and existentials.



Swift SVN r12131
2014-01-10 19:56:17 +00:00
Chris Lattner
f5466ab2b6 ding, dong, MaterializeExpr is dead.
Swift SVN r12125
2014-01-10 17:55:00 +00:00
Chris Lattner
f6a08290bc switch archetype bases over to the new world order where ArchetypeMemberRef
takes the archetype as an rvalue, not an lvalue.  This defines away the need
for MaterializeExpr at sema time, reusing the existing temporary mechanics in
SILGen.  This also opens future optimizations.


Swift SVN r12123
2014-01-10 17:41:38 +00:00
Doug Gregor
5f1b8618f4 Make the SILDeclRef for a destroying destructor store a DestructorDecl.
SILDeclRef was previously storing the ClassDecl for this case, because
semantic analysis didn't guarantee that a DestructorDecl was always
present. It is now, and this representation makes more sense.

Swift SVN r12122
2014-01-10 17:33:57 +00:00
Chris Lattner
0013ceea39 Rework how existential member references (i.e., calls to protocol methods)
to non-@mutating methods work in the AST: now the base expression is 
always computed as an rvalue, instead of computing them as an lvalue.  The 
optimization that we were accidentally getting before is now explicitly 
modeled, and the non-optimized case is now handled by standard temporary 
emission in SILGen instead of with MaterializeExpr.  The upshot of this 
carefully choreographed step is that there is no change in generated code (!).

Archetype member references still need to be switched over to this new
scheme (at which point materializeexpr is dead), and the optimization 
needs to be replicated for 'let' bases (at which point arguments 
becoming 'let' is only gated on debug info).



Swift SVN r12120
2014-01-10 07:26:30 +00:00