Commit Graph

768 Commits

Author SHA1 Message Date
Chris Lattner
f6e87dec54 Rework SILGen's emission of release_value to have it auto-merge into
retain_value instructions, just like we do for strong_retain/release.

This wraps up rdar://15889208, which is admittedly more of a moral 
victory than a practical one.


Swift SVN r15804
2014-04-02 16:39:53 +00:00
Chris Lattner
afea47b621 rename "destroy_value" to "release_value", part of rdar://15889208.
Swift SVN r15777
2014-04-02 05:33:52 +00:00
Joe Groff
ba34976f87 SILGen: Implement lowering for writeback conversion.
Lower LValueConversionExprs to LValueConversionComponents of SILGen's LValues, which add the conversion pair as a logical component of a writeback chain.

Swift SVN r15771
2014-04-02 03:15:12 +00:00
Joe Groff
8f1c2d1e79 Sema: Implement type-checking for inout writeback conversion.
Add a third branch to the constraint system for '&x' expressions that allows conversion from an lvalue to a type via an additional writeback step:

- Add an LValueConversionExpr node that converts from @lvalue T to @lvalue U, given a pair of functions that convert T -> U and U -> T, to represent the writeback temporary.
- Allow conversion in an inout expression from @lvalue T to a type U that has the following members:

  static func __writeback_conversion(Builtin.RawPointer, T.Type) -> U
  static func __writeback_conversion_get(T) -> V
  static func __writeback_conversion_set(V) -> T

which builds a solution that produces an LValueConversion from the get/set pair before passing the pointer to the writeback temporary off to the conversion function.

Swift SVN r15764
2014-04-02 00:17:51 +00:00
Joe Groff
b3e9a17269 SILGen: Implement inout address conversion.
Implement lowering for the LValueToPointer and InOutConversion expressions. For the former, we emit the lvalue, then convert it to a RawPointer; for the latter, we introduce an InOutConversion scope, which suppresses any nested writeback conversion scopes.

This completes the implementation of inout address conversion, except that we don't implement reabstraction of the lvalue prior to taking its address. Simply report them unimplemented for now, since reabstraction should not come up for our immediate use case with C types.

Swift SVN r15595
2014-03-29 02:50:26 +00:00
Joe Groff
45eadd1d9b Rename AddressOfExpr to InOutExpr.
The "address" is an implementation detail; formally, it turns an lvalue into an inout parameter.

Swift SVN r15458
2014-03-25 16:28:28 +00:00
Chris Lattner
13e06548cf Fix <rdar://problem/16411449> ownership qualifiers don't work with non-mutating struct property
Swift SVN r15429
2014-03-25 00:17:47 +00:00
Chris Lattner
3392c4e8ab remove ArchetypeSubscriptExpr, since it is dead now.
Swift SVN r14284
2014-02-23 08:04:51 +00:00
Chris Lattner
a121e9798e implement support for property references on archetypes, implementing rdar://14195801
Swift SVN r14282
2014-02-23 08:02:22 +00:00
Chris Lattner
728a865904 change Sema to form vardecl member references in protocols as MemberRefExpr instead of
ExistentialMemberRefExpr, and enhance silgen to avoid unnecessary copies of protocol
and archetype bases.   With this, uses of properties in protocols start to work.


Swift SVN r14270
2014-02-22 20:52:11 +00:00
Chris Lattner
380e44c615 remove ExistentialSubscriptExpr. We don't need specialized forms of
subscriptexpr for various base types, for the same reason we don't need
multiple different kinds of MemberRefExpr.


Swift SVN r14268
2014-02-22 20:18:02 +00:00
Chris Lattner
936cf62925 implement support for getting and setting subscripts on lvalues.
Swift SVN r14266
2014-02-22 20:00:15 +00:00
Chris Lattner
a61e32008c stub out missing lvalue handling for subscripts on protocols and archetypes
Swift SVN r14083
2014-02-19 15:57:53 +00:00
Chris Lattner
09e49dc2d8 strength reduce SILGen's representation of indexes from being
RValueSource's to RValues.  SILGen doesn't need the generality
of RValueSource.  NFC.


Swift SVN r14015
2014-02-17 23:41:32 +00:00
Chris Lattner
48759e2ae1 strength reduce SILGen's handling of the "value" argument when calling
a setter to use an RValue instead of RValueSource.  NFC.


Swift SVN r14013
2014-02-17 23:35:02 +00:00
Joe Groff
b19cfb27ea Drop the context generic params from SILFunctionType.
SILFunctionType is now 100% context free!

Swift SVN r13775
2014-02-11 04:21:20 +00:00
Joe Groff
481fbb7b91 Drop the non-interface types from SILFunctionType.
There are some straggling references to the context generic param list, but nothing uses the non-interface param or result types anymore!

Swift SVN r13725
2014-02-09 22:39:01 +00:00
Chris Lattner
d690a63a87 progress towards non-member observing properties:
- Add a "isDirectPropertyAccess" bit to DeclRefExpr, serving the 
   same purpose as MemberRefExprs for non-member properties.
 - Teach sema to synthesize correct non-member get/set implementations
   for observing properties.
 - Teach silgen to handle the isDirectPropertyAccess bit.



Swift SVN r13600
2014-02-06 22:34:37 +00:00
Chris Lattner
595817bd89 Rename data structures relating to WillSetDidSet properties to call them "Observing"
properties internally to the compiler.  NFC.


Swift SVN r13587
2014-02-06 17:51:45 +00:00
Doug Gregor
f1be1ed572 Implement super mesage sends for @objc property and subscript getters/setters.
Fixes <rdar://problem/15933008>.


Swift SVN r13100
2014-01-29 07:45:53 +00:00
Chris Lattner
eb66701757 simplify code now that AbstractStorageDecl unifies VarDecl and SubscriptDecl.
Swift SVN r13020
2014-01-28 00:39:20 +00:00
Chris Lattner
e668e86cc3 With many prerequisites out of the way, lets start actually working on didset/willset
properties.  This step provides AST support to model them.


Swift SVN r13011
2014-01-27 22:11:16 +00:00
Chris Lattner
2792e55be4 remove the -enable-new-objc-properties staging option, and
simplify some code.


Swift SVN r12976
2014-01-26 23:24:35 +00:00
Chris Lattner
ddc5ca81d6 Fix <rdar://problem/15858869> *all* objc accessors disabled in init methods, not just for self
This patch: 
 - Changes sema to set the "IsDirectPropertyAccess" on MemberRefExprs
   in inits/destructors that should be done directly because they are
   on the local object.
 - Removes the "SGF.AlwaysDirectStoredPropertyAccess" bool in SILGen,
   which was the source of the problem above and was otherwise problematic.

This will get a bit simpler when -enable-new-objc-properties rolls out. 


Swift SVN r12967
2014-01-26 07:23:42 +00:00
Chris Lattner
0dfb1ec790 introduce a new "IsDirectIVarAccess" bit to MemberRefExpr. Properties
that have both storage AND accessors are accessed by-default through
their accessors.  This bit indicates that a specific MRE should access
the storage instead.

Use this new bit in the synthesized getter/setter for "StorageObjC"
properties (it will also be used for other things in the future).
This also teaches SILGen about it.

One interesting aspect of this representation is that it makes it trivial
to add some expression syntax for directly accessing a store+computed 
property (e.g. ObjC properties, also someday didSet/willSet properties) 
someday if we care.  This would be analogous to the "self->ivar" syntax
in objc (vs self.ivar).  No, we will not use "->" for this. :-)

NFC since this is the use is still hidden under the -enable-new-objc-properties
staging option.



Swift SVN r12965
2014-01-26 06:08:53 +00:00
Chris Lattner
91fb51100d Introduce a new kind of StorageDecl called StoredObjC. These are
properties that are (usually) accessed through getters and setters, but
which have storage.  Nothing generates these yet.


Swift SVN r12902
2014-01-24 05:15:11 +00:00
Chris Lattner
690e8a38af switch places the ignore the result of an rvalue to allow it to be +0. No
impact on stdlib or testsuite.


Swift SVN r12879
2014-01-23 22:06:21 +00:00
Chris Lattner
c6a334ab6e teach SILGenFunction::emitLoad that clients allowing +0 results don't
need the load (and temporary, and cleanup) to actually be emitted for
address-only operands.  They can just use the physical lvalue as the +0 base.

In this example:
struct GenericStruct<T> {
  var a : T
  var b : Int

  func getA() -> T {
    return a
  }

  func getB() -> Int {
    return b
  }
}

we used to produce:

sil @_TFV2t213GenericStruct4getAU__fGS0_Q__FT_Q_ : $@cc(method) @thin <$T_0_0> (@out $T_0_0, @in GenericStruct<$T_0_0>) -> () {
bb0(%0 : $*T, %1 : $*GenericStruct<T>):
  debug_value_addr %1 : $*GenericStruct<T>  // let self // id: %2
  %3 = alloc_stack $GenericStruct<T>              // users: %8, %7, %5, %4
  copy_addr %1 to [initialization] %3#1 : $*GenericStruct<T> // id: %4
  %5 = struct_element_addr %3#1 : $*GenericStruct<T>, #a // user: %6
  copy_addr %5 to [initialization] %0 : $*T       // id: %6
  destroy_addr %3#1 : $*GenericStruct<T>          // id: %7
  dealloc_stack %3#0 : $*@local_storage GenericStruct<T> // id: %8
  destroy_addr %1 : $*GenericStruct<T>            // id: %9
  %10 = tuple ()                                  // user: %11
  return %10 : $()                                // id: %11
}

sil @_TFV2t213GenericStruct4getBU__fGS0_Q__FT_Si : $@cc(method) @thin <$T_0_0> (@in GenericStruct<$T_0_0>) -> Int64 {
bb0(%0 : $*GenericStruct<T>):
  debug_value_addr %0 : $*GenericStruct<T>  // let self // id: %1
  %2 = alloc_stack $GenericStruct<T>              // users: %7, %6, %4, %3
  copy_addr %0 to [initialization] %2#1 : $*GenericStruct<T> // id: %3
  %4 = struct_element_addr %2#1 : $*GenericStruct<T>, #b // user: %5
  %5 = load %4 : $*Int64                          // user: %9
  destroy_addr %2#1 : $*GenericStruct<T>          // id: %6
  dealloc_stack %2#0 : $*@local_storage GenericStruct<T> // id: %7
  destroy_addr %0 : $*GenericStruct<T>            // id: %8
  return %5 : $Int64                              // id: %9
}

now we produce:

sil @_TFV2t213GenericStruct4getAU__fGS0_Q__FT_Q_ : $@cc(method) @thin <$T_0_0> (@out $T_0_0, @in GenericStruct<$T_0_0>) -> () {
bb0(%0 : $*T, %1 : $*GenericStruct<T>):
  debug_value_addr %1 : $*GenericStruct<T>  // let self // id: %2
  %3 = struct_element_addr %1 : $*GenericStruct<T>, #a // user: %4
  copy_addr %3 to [initialization] %0 : $*T       // id: %4
  destroy_addr %1 : $*GenericStruct<T>            // id: %5
  %6 = tuple ()                                   // user: %7
  return %6 : $()                                 // id: %7
}

sil @_TFV2t213GenericStruct4getBU__fGS0_Q__FT_Si : $@cc(method) @thin <$T_0_0> (@in GenericStruct<$T_0_0>) -> Int64 {
bb0(%0 : $*GenericStruct<T>):
  debug_value_addr %0 : $*GenericStruct<T>  // let self // id: %1
  %2 = struct_element_addr %0 : $*GenericStruct<T>, #b // user: %3
  %3 = load %2 : $*Int64                          // user: %5
  destroy_addr %0 : $*GenericStruct<T>            // id: %4
  return %3 : $Int64                              // id: %5
}

This cuts about 120 lines out of the stdlib (so, about 40 temporaries).


Swift SVN r12871
2014-01-23 19:44:43 +00:00
Chris Lattner
2cf6d814c7 more tidying:
- Strength reduce the interface to LogicalPathComponent::getMaterialized
   to now just return a SILValue for the address.  The full "Materialize"
   structure hasn't been needed since MaterializeExpr got removed.
 - Move 'struct Materialize' out of SILGen.h into SILGenLValues.cpp now
   that it is only used for logical property materialization.
 - Drop the dead 'loc' argument on DeallocStackCleanup.  The location is
   already specified when the cleanup is emitted.


Swift SVN r12827
2014-01-23 00:43:20 +00:00
Chris Lattner
84f9919016 introduce a SGF::emitRValueAsSingleValue helper function to wrap a common
and repetitive pattern.


Swift SVN r12808
2014-01-22 22:51:55 +00:00
Chris Lattner
c755b13aa0 update comments for the [attributes] -> @attributes syntax change.
Swift SVN r12795
2014-01-22 22:09:57 +00:00
Chris Lattner
7cd0f1739a A big part of handling address-only types is making sure that various
emission routines use the SGFContext passed in.  To help with this and
to help the handshake, add a new "isInContext()" representation to 
ManagedValue.  This makes the code producing and consuming these more
explicit.  NFC.


Swift SVN r12783
2014-01-22 21:31:44 +00:00
Chris Lattner
b457be6a9f SGF::emitLValueForDecl only works on VarDecls, make its prototype more specific
to reflect that.


Swift SVN r12753
2014-01-22 18:20:06 +00:00
Chris Lattner
a7b39c21f3 emitReferenceToDecl is serving two purposes: for VarDecls it
can often produce an lvalue, for everything else it produces an RValue.

Split it up a bit so that all of the lvalue cases are handled by 
emitLValueForDecl (which it calls).  This allows clients that only
expect an lvalue back to have a simpler path, and allows one that
wants to probe to see if something is an lvalue or not to be simpler.



Swift SVN r12715
2014-01-22 07:07:05 +00:00
Chris Lattner
d4594b77a5 Switch the nominal type pattern matching destructuring logic to
use the new RValue emission infrastructure instead of duplicating
some of it.  This enables the use of computed properties, fixing
<rdar://problem/15859432> SILGen abort when pattern matching on computed property

and eliminates some code that future changes would otherwise have to 
worry about.  

There are other problems with this code (e.g. see rdar://15863069), so I think 
we should disable the feature until it has time to really bake, but this is still
useful progress in the right direction and is a net reduction of code.



Swift SVN r12618
2014-01-20 23:29:42 +00:00
Chris Lattner
2ab1f29664 Use emitRValueForDecl in various places that expect an RValue, and
use emitReferenceToDecl when we expect an lvalue or rvalue.  This
makes the code more explicit and avoids duplicating the "emit a
load if emitReferenceToDecl returned an lvalue" logic.


Swift SVN r12603
2014-01-20 18:50:34 +00:00
Chris Lattner
f5b85341a1 Expand out the "isComputed" property in AbstractStorageDecl to be an enum
with two kinds, and some more specific predicates that clients can use.

The notion of 'computed or not' isn't specific enough for how properties
are accessed.  We already have problems with ObjC properties that are 
stored but usually accessed through getters and setters, and a bool here
isn't helping matters.

NFC.



Swift SVN r12593
2014-01-20 18:16:30 +00:00
Chris Lattner
8563ebc36e rework and tidy SILGenLValue::visitMemberRefExpr to make the logic
flow better: the getter/setter case is the simple case, so switch
it to be the early out.


Swift SVN r12579
2014-01-20 16:10:22 +00:00
Chris Lattner
22bced4c08 retype emitGetAccessor/emitSetAccessor to take an AbstractStorageDecl
instead of a ValueDecl (which is more specific).  This allows them to
use the more specific ASD::usesObjCGetterAndSetter() method instead
of SGM::requiresObjCDispatch.

To enable this, push AbstractStorageDecl through SILGenLValue's
GetterSetterComponent.


Swift SVN r12578
2014-01-20 16:00:48 +00:00
Joe Groff
0776c4b6b8 SIL: Reorient function type lowering toward interface types.
Lower types for SILDeclRefs from the interface types of their referents, dragging the old type along for the ride so we can still offer the context to clients that haven't been weaned off of it. Make SILFunctionType's interface types and generic signature independent arguments of its  Derive the context types of SILFunctionType from the interface types, instead of the other way around. Do a bunch of annoying inseparable work in the AST and IRGen to accommodate the switchover.

Swift SVN r12536
2014-01-18 19:42:02 +00:00
John McCall
817e80bde5 Implicit conversions for UncheckedOptional.
rdar://15189000
rdar://15189009

Swift SVN r12260
2014-01-13 23:15:03 +00:00
Chris Lattner
f5466ab2b6 ding, dong, MaterializeExpr is dead.
Swift SVN r12125
2014-01-10 17:55:00 +00:00
Doug Gregor
68bcb0d2af Move emission of instance variable initial values from Sema to SILGen.
Hacking up ASTs to perform this emission was always gross; move it
over to SILGen. No functionality change.

Swift SVN r12067
2014-01-08 21:38:23 +00:00
Joe Groff
44fb729830 SIL: Use only interface types in the verifier.
Treat the interface types of SILFunctionTypes as the canonical representation in the verifier. Do a bunch of supporting and annoyingly irreducible work to enable this:

- Stop trying to uncurry generic parameter lists during type lowering and preserve the structure of AST GenericParamLists. This makes mapping dependent types into contexts easier.
- Properly walk generic parameter lists at all depths when grooming substitution vectors for use with substGenericArgs interfaces.
- Reseat the generic parameter lists created for protocol_method results so that we don't expect the outer Self archetype to be unbound; it's provided by the extra data of the result.
- Hack SILFunctionType serialization never to use a decl reference when serializing its generic param list. When this happens, we get incorrect archetypes. This is a gross hack, but when we're able to jump all the way to interface types, it can go away.

Putting these ducks in a row nicely un-XFAILs TextFormatting.swift.

Swift SVN r11989
2014-01-07 06:50:20 +00:00
Chris Lattner
b61a6fd946 Rework AST and SILGen of properties and subscripts to take advantage of the new mutability model.
- Change the AST for get/set functions to take self @inout only when they 
  are @mutating.  Setters default to @mutating, but can be explicitly marked 
  @!mutating. Getters default to not mutating, but can be marked @mutating.  
  This causes self to follow.
- Change sema to handle semantic analysis of a.y (and subscripts) based on
  whether the computed type of a allows mutation (which is when 'a' is an 
  lvalue, or both the getter and setter are non-mutating).  When both of
  these conditions fail, 'a.y' has rvalue type, and is thus non-mutable.
- Rework silgen of lvalues to handle this: now properties and subscripts 
  can have rvalues as bases, which means that all the lvalue machinery needs 
  to be able to handle the full generality of base expressions (which is 
  what my recent patches have been paving the way towards).
- Rework silgen of rvalues to similarly handle rvalue bases.
- Rework silgen of both to handle the case where the AST has found a base
  expression that is an lvalue, but where only a non-mutating getter or
  setter is needed.  Right now, we just emit a load of the lvalue, but
  it would result in better code to not require the base be an lvalue at 
  all (todo).

The upshot of all of this is that we are doing *much* less AST-level 
materialization (MaterializeExpr goes down), we generate a lot better SIL
out of SILGen in many cases, and 'self' being an rvalue in properties and
subscripts means that we correctly reject code like the examples in
test/Sema/immutability.swift.



Swift SVN r11884
2014-01-04 04:27:51 +00:00
Chris Lattner
1ca2722e83 introduce ManagedValue::forLValue(x) as a helper function for
making LValue ManagedValues, and switch SILGenLValue to use
this form of managed value consistently for lvalues, instead of
using unmanaged values in some cases.  NFC. 


Swift SVN r11878
2014-01-04 00:45:05 +00:00
Chris Lattner
1b86610e1a switch LValueWriteback to use ManagedValue now that it has access to it.
Swift SVN r11877
2014-01-04 00:29:36 +00:00
Chris Lattner
fdc3e70d6d move SILGenFunction::Writeback out of line and rename it to LValueWriteback
in preparation for more work on it.  NFC.


Swift SVN r11876
2014-01-04 00:17:09 +00:00
Doug Gregor
1ee513e7e8 Use Builtin.Word for array lengths, string literal lengths, etc.
This eliminates a number of 64-bit integer/64-bit pointer assumptions
in the type checker and SILGen.


Swift SVN r11863
2014-01-03 18:53:01 +00:00
Chris Lattner
5b394f67f3 sink SILDeclRef's down into emitGetAccessor/emitSetAccessor, which are
the things that apparently care about it.  The LValue/RValue machinery is 
happy to pass around the VarDecl/SubscriptDecl for the entity being
referenced, and this simplifies things.


Swift SVN r11857
2014-01-03 07:19:40 +00:00